• Unfortunately, we have experienced significant hard drive damage that requires urgent maintenance and rebuilding. The forum will be a state of read only until we install our new drives and rebuild all the configurations needed. Please follow our Facebook page for updates, we will be back up shortly! (The forum could go offline at any given time due to the nature of the failed drives whilst awaiting the upgrades.) When you see an Incapsula error, you know we are in the process of migration.

Command line options for elementclient.exe

Newbie Spellweaver
Joined
Mar 20, 2021
Messages
47
Reaction score
4
I've searched all over the place but can't find anywhere documented what command line options elementclient.exe supports. I only found most of these from the source code of some "PW launcher" thing on github.
  • startbypatcher
  • game:cpw (don't really understand what this does)
  • console:1
  • nocheck
  • user:<name> auto login this account
  • pwd:<pwd> auto login this account
  • role: <charname> auto select this char and log it in

What I'm actually trying to do is auto select the server. The 1.4.6 client didn't ask, I just have a script like
start /b elementclient.exe startbypatcher game:cpw console:1 nocheck user:xxx pwd:xxx role:xxx

so I can bypass the login screens, and it would go straight in. But the 1.5.5 client always waits for me to pick the server to log in to (even though there's only 1 listed in serverlist.txt). After I double click the server, THEN the user/pwd/role options work fine and auto login and pick the right char.
 
Joined
Jul 26, 2011
Messages
2,030
Reaction score
396
try server:1 ? (or whatever the ID is)

command like stuff from W2's client, maybe try something here
#pragma once

#include <AAssist.h>
#include <ABaseDef.h>

// Filename : EC_CommandLine.h
// Creator : Xu Wenbin
// Date : 2011/02/22

//
// 类 CECCommandLine: 查询控制台配置属性
//
class CECCommandLine
{
public:
static bool GetSupportSeperateFile();
static bool GetRenderWhenNoFocus();
static bool GetDoNotCheckSmallVersion();
static bool GetLoadFacePillData();
static bool GetClearAllCoolDown();

static ACString GetUser();
static ACString GetPassword();
static ACString GetArea();
static ACString GetToken();
static char GetTokenType();
static ACString GetRole();
static ACString GetAgent();
static bool GetEnableGT(bool &bResult);
static bool GetEnableArc(bool &bResult);
static bool GetEnableArcAsia(bool &bResult);
static bool GetExportServerListZoneIDName();
static bool GetEnableMiniClient(bool &bResult);
static bool GetEnableLuaDebug();
static bool GetRtDebugLevel(int &iLevel);
static bool GetRtDebugProtocolsToHide(AString &names);
static bool GetEnableLogicCheckInfo(bool &bResult);

static ACString GetStandardConfig(const ACHAR *szConfig);
static bool GetBriefConfig(const ACHAR *szConfig);
static bool GetEnable(const ACHAR *szConfig, bool &bResult);

private:
static bool IsSeperator(ACHAR c);
static bool SearchConfig(const ACHAR *szKey, bool &bKeyOnly, ACString &strValue);
static bool SearchNextItem(const ACHAR *pCmd, bool bColonAsSeperator, ACString &strItem, const ACHAR * & pCmdNext);
};

// Filename : EC_CommandLine.cpp
// Creator : Xu Wenbin
// Date : 2011/02/22

#include "EC_CommandLine.h"
#include <AChar.h>
#include <ALog.h>
#include <windows.h>

bool CECCommandLine::IsSeperator(ACHAR c)
{
return (c == ' ' || c == '\t');
}

ACString CECCommandLine::GetUser()
{
return GetStandardConfig(_AL("user"));
}

ACString CECCommandLine::GetPassword()
{
return GetStandardConfig(_AL("pwd"));
}

ACString CECCommandLine::GetArea()
{
return GetStandardConfig(_AL("area"));
}

ACString CECCommandLine::GetToken()
{
ACString strToken = GetStandardConfig(_AL("token"));
if (strToken.IsEmpty())
strToken = GetStandardConfig(_AL("token2"));
return strToken;
}

char CECCommandLine::GetTokenType()
{
char type = 0;
if (!GetStandardConfig(_AL("token")).IsEmpty())
type = 1;
else if (!GetStandardConfig(_AL("token2")).IsEmpty())
type = 2;
return type;
}

ACString CECCommandLine::GetRole()
{
return GetStandardConfig(_AL("role"));
}

ACString CECCommandLine::GetAgent()
{
return GetStandardConfig(_AL("agent"));
}

bool CECCommandLine::GetEnableGT(bool &bResult)
{
return GetEnable(_AL("gt"), bResult);
}

bool CECCommandLine::GetEnableArc(bool &bResult)
{
return GetEnable(_AL("coreclient"), bResult);
}

bool CECCommandLine::GetEnableArcAsia(bool &bResult)
{
return GetEnable(_AL("arcasia"), bResult);
}

bool CECCommandLine::GetExportServerListZoneIDName()
{
return GetBriefConfig(_AL("exportserver"));
}

bool CECCommandLine::GetEnableMiniClient(bool &bResult)
{
return GetEnable(_AL("miniclient"), bResult);
}

bool CECCommandLine::GetEnableLogicCheckInfo(bool &bResult)
{
return GetEnable(_AL("logiccheck"), bResult);
}

bool CECCommandLine::GetEnableLuaDebug()
{
return GetBriefConfig(_AL("luadebug"));
}

bool CECCommandLine::GetRtDebugLevel(int &iLevel)
{
ACString str = GetStandardConfig(_AL("rtdebug"));
if (str.IsEmpty()) return false;
iLevel = str.ToInt();
return true;
}

bool CECCommandLine::GetRtDebugProtocolsToHide(AString &names)
{
ACString str = GetStandardConfig(_AL("rtdebug_hide"));
if (str.IsEmpty()) return false;
names = AC2AS(str);
return true;
}

ACString CECCommandLine::GetStandardConfig(const ACHAR *szConfig)
{
// 获取标准格式的配置名称,如获取user:a中的a时,szConfig为user
// 要求 GetCommandLine 返回结果以 空格 或 tab 键分开多个配置

ACString strRet;

while (true)
{
// 验证并匹配配置项
bool bKeyOnly(false);
ACString strValue;
if (!SearchConfig(szConfig, bKeyOnly, strValue))
break;

// 验证是标准配置项(即配置项以key:value的形式存在)
if (bKeyOnly)
break;

// 获取配置项value
strRet = strValue;

break;
}

return strRet;
}

bool CECCommandLine::GetSupportSeperateFile()
{
return GetBriefConfig(_AL("sepfile"));
}

bool CECCommandLine::GetRenderWhenNoFocus()
{
return GetBriefConfig(_AL("rendernofocus"));
}

bool CECCommandLine::GetDoNotCheckSmallVersion()
{
return GetBriefConfig(_AL("nocheck"));
}

bool CECCommandLine::GetLoadFacePillData()
{
return GetBriefConfig(_AL("facepill"));
}

bool CECCommandLine::GetClearAllCoolDown()
{
return GetBriefConfig(_AL("nocooldown"));
}

bool CECCommandLine::GetBriefConfig(const ACHAR *szConfig)
{
// 获取标准格式的配置名称,如获取user:a中的a时,szConfig为user
// 要求 GetCommandLine 返回结果以 空格 或 tab 键分开多个配置

bool bRet(false);

while (true)
{
// 验证并匹配配置项key
bool bKeyOnly(false);
ACString strValue;
if (!SearchConfig(szConfig, bKeyOnly, strValue))
break;

// 验证是简单配置项(即配置项只有key)
if (!bKeyOnly)
break;

bRet = true;
break;
}

return bRet;
}

bool CECCommandLine::GetEnable(const ACHAR *szConfig, bool &bResult)
{
ACString str = GetStandardConfig(szConfig);
if (str.IsEmpty()) return false;
int nEnable = str.ToInt();
bResult = (nEnable != 0);
return true;
}

bool CECCommandLine::SearchConfig(const ACHAR *szKey, bool &bKeyOnly, ACString &strValue)
{
// 查找名称为 szKey 的配置项
// 查找成功时返回 true,其中,配置项以 key:value 形式存在时(szKey = key),返回bKeyOnly = false,strValue = value
// 查找失败时返回 false,bKeyOnly 及 strValue 值不变
// 注1:允许配置项 key、value 为以 key、'key'、"key",value、'value'、"value"等形式存在,例如 "user":'foo',输入参数 szKey为user,返回strValue为foo
// 注2:配置项之间的分隔符为空格、Tab键

bool bRet(false);

while (true)
{
// 验证待查找参数
if (!szKey || !szKey[0])
break;

// 验证 CommandLine
const ACHAR *szCommandLine = GetCommandLine();
if (!szCommandLine || !szCommandLine[0])
break;

// 查找验证并匹配配置项
const ACHAR *pCmd = szCommandLine;
const ACHAR *pCmdNext = NULL;
ACString strTempKey, strTempValue;
bool bTempKeyOnly(false);
while (SearchNextItem(pCmd, true, strTempKey, pCmdNext))
{
// 找到新的配置项key,验证格式并获取完整配置内容(用于返回或跳过)
if (!pCmdNext || !(*pCmdNext) || IsSeperator(*pCmdNext))
{
// 已经是配置内容末尾、或者到达配置项边界

// value 值为空
strTempValue.Empty();
bTempKeyOnly = true;

// 下一次查找位置即为此配置项末尾
pCmd = pCmdNext;
pCmdNext = NULL;
}
else
{
// 可能是标准配置项key:value 或错误的配置项 "m"k、"m"k:"value" 等

if (*pCmdNext != ':')
{
// 程序错误,SearchNextItem 处理不当导致,直接返回 false
ASSERT(false);
a_LogOutput(1, "CECCommandLine::SearchConfig(), Unexpected parse result: cmdline = "%s", key = "%s"", AC2AS(szCommandLine), AC2AS(strTempKey));
return false;
}

// 正确的配置项,从':'后开始查找 value 值
bTempKeyOnly = false;
if (!(*(pCmdNext+1)) || IsSeperator(*(pCmdNext+1)))
{
// value 值为空
strTempValue.Empty();

// 设置下一次查找位置
pCmd = pCmdNext+1;
pCmdNext = NULL;
}
else
{
// value 不为空
pCmd = pCmdNext+1;
pCmdNext = NULL;
bool bTemp = SearchNextItem(pCmd, false, strTempValue, pCmdNext);
if (!bTemp)
{
// 程序错误,SearchNextItem 处理不当导致,直接返回 false
ASSERT(false);
a_LogOutput(1, "CECCommandLine::SearchConfig(), Unexpected parse result: cmdline = "%s", pCmd = "%s"", AC2AS(szCommandLine), AC2AS(pCmd));
return false;
}

// value 成功查找,设置下一次查找位置
pCmd = pCmdNext;
pCmdNext = NULL;
}
}

// 当前配置项已正确获取,尝试匹配
if (strTempKey != szKey)
continue;

// 匹配成功,设置返回值
bKeyOnly = bTempKeyOnly;
if (bKeyOnly) strValue.Empty();
else strValue = strTempValue;
bRet = true;
break;
}

// 查找结果已经正确赋值,跳出循环即可
break;
}

return bRet;
}

bool CECCommandLine::SearchNextItem(const ACHAR *pCmd, bool bColonAsSeperator, ACString &strItem, const ACHAR * & pCmdNext)
{
// 查找下一个被双引号 "" 或单引号 '' 或被配置项分隔符(参数 bColonAsSeperator 为true时)、或标准配置项内key、value分隔符分开的项
// pCmd 为待查找字符串,实际使用中为 CommandLine 的一部分
// bColonAsSeperator 为true时,用于查找配置项的key,其与value分隔符即为冒号;为false时,用于查找配置项的value,其中的冒号为普通字符
// 查找成功时返回 true,strItem 返回非空的 key ,pCmdNext 指下向一个查找位置;
// 正确并能被成功查找的格式为 [key | 'key' | "key"][分隔符 | 结束],其中,key 中不包含单引号或双引号、'key'中不包含单引号、"key"中不包括双引号;分隔符包含配置项分隔符(空格、Tab)、配置项内key和value之间的分隔符(冒号,在 bColonAsSeperator 为 true 有效)
// 注1:处理过程会跳过格式错误项,以增强鲁棒性

bool bRet(false);

while (true)
{
if (!pCmd)
break;

ACHAR cQuote = 0; // 记录当前匹配项的起始模式:值为"时表示以"开始、为'表示以'开始、否则为普通模式
ACHAR cQuote1 = '\'';
ACHAR cQuote2 = '"';

// 可能需要跳过非法配置项,因此需要再加一层循环
while (true)
{
// 跳过开头配置项分隔符
while (*pCmd && IsSeperator(*pCmd))
pCmd ++;

if (!*pCmd)
{
// 已经查找到字符串末尾
break;
}

// 处理第一个字符,检查引号情况、并确定匹配模式
strItem.Empty();
ACHAR c = *pCmd++;
cQuote = (c == cQuote2 ? c : (c == cQuote1 ? c : 0));
if (!cQuote)
{
strItem += c;

// 检查是否有后续字符

if (!*pCmd)
{
// 没有后续字符,如 console:1 出现在配置表的最后
bRet = true;
pCmdNext = pCmd;
break;
}
}

// 开始后续匹配
while (*pCmd)
{
c = *pCmd++;

// 处理匹配中某字符

if (cQuote)
{
// 引号模式开头,要求一定以同一符号结束

if (c != cQuote)
{
strItem += c;
continue;
}

// 遇到匹配符号,检查后面的格式是否正确,不正确则跳过

if (*pCmd && !IsSeperator(*pCmd) && (!bColonAsSeperator || *pCmd!=':') )
{
// 不是结束、或key和value分隔符、或配置项分隔符,为非法格式

// 跳过非法格式
while (*pCmd && !IsSeperator(*pCmd))
pCmd ++;

// 遇到结束(将跳出循环)、或遇到配置项分隔符(跳过当前非法格式进行下一次查找)
}

// 后面的格式正确,跳出所有循环返回
bRet = true;
pCmdNext = pCmd;
break;
}

// 非引号开头模式,以key和value分隔符或配置项分隔符结束

if (!IsSeperator(c) && (!bColonAsSeperator || c != ':'))
{
strItem += c;
if (*pCmd)
{
// 后续还有内容时
continue;
}

// 解析结束,查找成功
bRet = true;
pCmdNext = pCmd;
break;
}

// 遇到分隔符,查找成功,跳出所有循环返回
bRet = true;
pCmdNext = pCmd-1;
break;
}
if (bRet)
{
// 成功查找,跳出所有循环返回
break;
}

// 失败,继续尝试
}

break;
}

return bRet;
}

(these are very similar in 1.5.3 as well, w2 I just had onhand at the time)
 
Last edited:
Upvote 0
Newbie Spellweaver
Joined
Mar 20, 2021
Messages
47
Reaction score
4
Thanks very much for posting those. Looks from that like it should be "area:1", though I tried that and every other variation I could think of (server:1, exportserver:1, and using names instead) without success. Looks like they must've removed support for it. Weird that 1.4.6 autoselected the server even if you didn't tell it to.
 
Upvote 0
Back
Top