Parse settings from the command line (#1578)

Allow specifying any setting as --setting=value
Sections other than main: --section.setting=value
Previous positional arguments are still supported
Update user manual with quick usage and examples
This commit is contained in:
ORelio 2021-05-20 21:40:57 +02:00
parent 9af9fe78ee
commit 172e25fef0
5 changed files with 597 additions and 495 deletions

View file

@ -79,7 +79,7 @@ namespace MinecraftClient
//Process ini configuration file
if (args.Length >= 1 && System.IO.File.Exists(args[0]) && System.IO.Path.GetExtension(args[0]).ToLower() == ".ini")
{
Settings.LoadSettings(args[0]);
Settings.LoadFile(args[0]);
//remove ini configuration file from arguments array
List<string> args_tmp = args.ToList<string>();
@ -88,7 +88,7 @@ namespace MinecraftClient
}
else if (System.IO.File.Exists("MinecraftClient.ini"))
{
Settings.LoadSettings("MinecraftClient.ini");
Settings.LoadFile("MinecraftClient.ini");
}
else Settings.WriteDefaultSettings("MinecraftClient.ini");
@ -98,20 +98,26 @@ namespace MinecraftClient
//Other command-line arguments
if (args.Length >= 1)
{
Settings.Login = args[0];
if (args.Length >= 2)
if (args.Contains("--help"))
{
Settings.Password = args[1];
if (args.Length >= 3)
{
Settings.SetServerIP(args[2]);
Console.WriteLine("Command-Line Help:");
Console.WriteLine("MinecraftClient.exe <username> <password> <server>");
Console.WriteLine("MinecraftClient.exe <username> <password> <server> \"/mycommand\"");
Console.WriteLine("MinecraftClient.exe --setting=value [--other settings]");
Console.WriteLine("MinecraftClient.exe --section.setting=value [--other settings]");
Console.WriteLine("MinecraftClient.exe <settings-file.ini> [--other settings]");
return;
}
//Single command?
if (args.Length >= 4)
try
{
Settings.SingleCommand = args[3];
}
Settings.LoadArguments(args);
}
catch (ArgumentException e)
{
Settings.interactiveMode = false;
HandleFailure(e.Message);
return;
}
}

View file

@ -82,6 +82,9 @@ error.connection_timeout=§8Es gab einen Timeout während des Verbindungsaufbaus
error.forge=§8Forge Login Handshake konnte nicht erfolgreich abgeschlossen werden.
error.forge_encrypt=§8Forge StartEncryption Handshake konnte nicht erfolgreich abgeschlossen werden.
error.setting.str2int=Konnte '{0}' nicht in einen Int umwandeln. Bitte überprüfe die Einstellungen.
error.setting.argument_syntax={0}: Invalid syntax, expecting --argname=value or --section.argname=value
error.setting.unknown_section={0}: Unknown setting section '{1}'
error.setting.unknown_or_invalid={0}: Unknown setting or invalid value
error.http_code=§8Es gab einen Fehlercode vom Server: {0}
error.auth=§8Es gab einen Fehlercode vom Server, während die Authentication erneuert wurde: {0}
error.realms.ip_error=Konnte die Server-IP deiner Realms-Welt nicht abfragen

View file

@ -82,6 +82,9 @@ error.connection_timeout=§8A timeout occured while attempting to connect to thi
error.forge=§8Forge Login Handshake did not complete successfully
error.forge_encrypt=§8Forge StartEncryption Handshake did not complete successfully
error.setting.str2int=Failed to convert '{0}' into an int. Please check your settings.
error.setting.argument_syntax={0}: Invalid syntax, expecting --argname=value or --section.argname=value
error.setting.unknown_section={0}: Unknown setting section '{1}'
error.setting.unknown_or_invalid={0}: Unknown setting or invalid value
error.http_code=§8Got error code from server: {0}
error.auth=§8Got error code from server while refreshing authentication: {0}
error.realms.ip_error=Cannot retrieve the server IP of your Realms world

View file

@ -207,33 +207,46 @@ namespace MinecraftClient
public static bool ReplayMod_Enabled = false;
public static int ReplayMod_BackupInterval = 3000;
//Custom app variables and Minecraft accounts
private static readonly Dictionary<string, object> AppVars = new Dictionary<string, object>();
private static readonly Dictionary<string, KeyValuePair<string, string>> Accounts = new Dictionary<string, KeyValuePair<string, string>>();
private static readonly Dictionary<string, KeyValuePair<string, ushort>> Servers = new Dictionary<string, KeyValuePair<string, ushort>>();
//Temporary Server Alias storage when server list is not loaded yet
private static string ServerAliasTemp = null;
private enum ParseMode { Default, Main, AppVars, Proxy, MCSettings, AntiAFK, Hangman, Alerts, ChatLog, AutoRelog, ScriptScheduler, RemoteControl, ChatFormat, AutoRespond, AutoAttack, AutoFishing, AutoEat, AutoCraft, AutoDrop, Mailer, ReplayMod, Logging };
//Mapping for settings sections in the INI file
private enum Section { Default, Main, AppVars, Proxy, MCSettings, AntiAFK, Hangman, Alerts, ChatLog, AutoRelog, ScriptScheduler, RemoteControl, ChatFormat, AutoRespond, AutoAttack, AutoFishing, AutoEat, AutoCraft, AutoDrop, Mailer, ReplayMod, Logging };
/// <summary>
/// Load settings from the give INI file
/// Get settings section from name
/// </summary>
/// <param name="settingsfile">File to load</param>
public static void LoadSettings(string settingsfile)
/// <param name="name">Section name</param>
/// <returns>Section enum</returns>
private static Section GetSection(string name)
{
ConsoleIO.WriteLogLine("[Settings] Loading Settings from " + Path.GetFullPath(settingsfile));
if (File.Exists(settingsfile))
Section pMode;
if (Enum.TryParse(name, true, out pMode))
return pMode;
return Section.Default;
}
/// <summary>
/// Load settings from the given INI file
/// </summary>
/// <param name="file">File to load</param>
public static void LoadFile(string file)
{
ConsoleIO.WriteLogLine("[Settings] Loading Settings from " + Path.GetFullPath(file));
if (File.Exists(file))
{
try
{
string serverAlias = "";
string[] Lines = File.ReadAllLines(settingsfile);
ParseMode pMode = ParseMode.Default;
string[] Lines = File.ReadAllLines(file);
Section section = Section.Default;
foreach (string lineRAW in Lines)
{
string line = pMode == ParseMode.Main && lineRAW.ToLower().Trim().StartsWith("password")
string line = section == Section.Main && lineRAW.ToLower().Trim().StartsWith("password")
? lineRAW.Trim() //Do not strip # in passwords
: lineRAW.Split('#')[0].Trim();
@ -241,32 +254,7 @@ namespace MinecraftClient
{
if (line[0] == '[' && line[line.Length - 1] == ']')
{
switch (line.Substring(1, line.Length - 2).ToLower())
{
case "alerts": pMode = ParseMode.Alerts; break;
case "antiafk": pMode = ParseMode.AntiAFK; break;
case "autorelog": pMode = ParseMode.AutoRelog; break;
case "chatlog": pMode = ParseMode.ChatLog; break;
case "hangman": pMode = ParseMode.Hangman; break;
case "main": pMode = ParseMode.Main; break;
case "mcsettings": pMode = ParseMode.MCSettings; break;
case "scriptscheduler": pMode = ParseMode.ScriptScheduler; break;
case "remotecontrol": pMode = ParseMode.RemoteControl; break;
case "proxy": pMode = ParseMode.Proxy; break;
case "appvars": pMode = ParseMode.AppVars; break;
case "autorespond": pMode = ParseMode.AutoRespond; break;
case "chatformat": pMode = ParseMode.ChatFormat; break;
case "autoattack": pMode = ParseMode.AutoAttack; break;
case "autofishing": pMode = ParseMode.AutoFishing; break;
case "autoeat": pMode = ParseMode.AutoEat; break;
case "autocraft": pMode = ParseMode.AutoCraft; break;
case "mailer": pMode = ParseMode.Mailer; break;
case "autodrop": pMode = ParseMode.AutoDrop; break;
case "replaymod": pMode = ParseMode.ReplayMod; break;
case "logging": pMode = ParseMode.Logging; break;
default: pMode = ParseMode.Default; break;
}
section = GetSection(line.Substring(1, line.Length - 2).ToLower());
}
else
{
@ -274,42 +262,110 @@ namespace MinecraftClient
if (line.Length > (argName.Length + 1))
{
string argValue = line.Substring(argName.Length + 1);
switch (pMode)
LoadSingleSetting(section, argName, argValue);
}
}
}
}
}
catch (IOException) { }
}
}
/// <summary>
/// Load settings from the command line
/// </summary>
/// <param name="args">Command-line arguments</param>
/// <exception cref="System.ArgumentException">Thrown on invalid arguments</exception>
public static void LoadArguments(string[] args)
{
case ParseMode.Main:
int positionalIndex = 0;
foreach (string argument in args)
{
if (argument.StartsWith("--"))
{
//Load settings as --setting=value and --section.setting=value
if (!argument.Contains("="))
throw new ArgumentException(Translations.Get("error.setting.argument_syntax", argument));
Section section = Section.Main;
string argName = argument.Substring(2).Split('=')[0];
string argValue = argument.Substring(argName.Length + 3);
if (argName.Contains('.'))
{
string sectionName = argName.Split('.')[0];
section = GetSection(sectionName);
if (section == Section.Default)
throw new ArgumentException(Translations.Get("error.setting.unknown_section", argument, sectionName));
argName = argName.Split('.')[1];
}
if (!LoadSingleSetting(section, argName, argValue))
throw new ArgumentException(Translations.Get("error.setting.unknown_or_invalid", argument));
}
else if (argument.StartsWith("-") && argument.Length > 1)
{
//Keep single dash arguments as unsupported for now (future use)
throw new ArgumentException(Translations.Get("error.setting.argument_syntax", argument));
}
else
{
switch (positionalIndex)
{
case 0: Login = argument; break;
case 1: Password = argument; break;
case 2: if (!SetServerIP(argument)) ServerAliasTemp = argument; break;
case 3: SingleCommand = argument; break;
}
positionalIndex++;
}
}
}
/// <summary>
/// Load a single setting from INI file or command-line argument
/// </summary>
/// <param name="section">Settings section</param>
/// <param name="argName">Setting name</param>
/// <param name="argValue">Setting value</param>
/// <returns>TRUE if setting was valid</returns>
private static bool LoadSingleSetting(Section section, string argName, string argValue)
{
switch (section)
{
case Section.Main:
switch (argName.ToLower())
{
case "login": Login = argValue; break;
case "password": Password = argValue; break;
case "login": Login = argValue; return true;
case "password": Password = argValue; return true;
case "type": AccountType = argValue == "mojang"
? ProtocolHandler.AccountType.Mojang
: ProtocolHandler.AccountType.Microsoft; break;
: ProtocolHandler.AccountType.Microsoft; return true;
case "method": LoginMethod = argValue.ToLower() == "browser"
? "browser"
: "mcc"; break;
case "serverip": if (!SetServerIP(argValue)) serverAlias = argValue; ; break;
case "singlecommand": SingleCommand = argValue; break;
case "language": Language = argValue; break;
case "consoletitle": ConsoleTitle = argValue; break;
case "timestamps": ConsoleIO.EnableTimestamps = str2bool(argValue); break;
case "exitonfailure": interactiveMode = !str2bool(argValue); break;
case "playerheadicon": playerHeadAsIcon = str2bool(argValue); break;
case "chatbotlogfile": chatbotLogFile = argValue; break;
case "mcversion": ServerVersion = argValue; break;
case "messagecooldown": messageCooldown = TimeSpan.FromSeconds(str2int(argValue)); break;
case "scriptcache": CacheScripts = str2bool(argValue); break;
case "showsystemmessages": DisplaySystemMessages = str2bool(argValue); break;
case "showxpbarmessages": DisplayXPBarMessages = str2bool(argValue); break;
case "showchatlinks": DisplayChatLinks = str2bool(argValue); break;
case "terrainandmovements": TerrainAndMovements = str2bool(argValue); break;
case "entityhandling": EntityHandling = str2bool(argValue); break;
case "enableentityhandling": EntityHandling = str2bool(argValue); break;
case "inventoryhandling": InventoryHandling = str2bool(argValue); break;
case "privatemsgscmdname": PrivateMsgsCmdName = argValue.ToLower().Trim(); break;
case "autorespawn": AutoRespawn = str2bool(argValue); break;
: "mcc"; return true;
case "serverip": if (!SetServerIP(argValue)) ServerAliasTemp = argValue; return true;
case "singlecommand": SingleCommand = argValue; return true;
case "language": Language = argValue; return true;
case "consoletitle": ConsoleTitle = argValue; return true;
case "timestamps": ConsoleIO.EnableTimestamps = str2bool(argValue); return true;
case "exitonfailure": interactiveMode = !str2bool(argValue); return true;
case "playerheadicon": playerHeadAsIcon = str2bool(argValue); return true;
case "chatbotlogfile": chatbotLogFile = argValue; return true;
case "mcversion": ServerVersion = argValue; return true;
case "messagecooldown": messageCooldown = TimeSpan.FromSeconds(str2int(argValue)); return true;
case "scriptcache": CacheScripts = str2bool(argValue); return true;
case "showsystemmessages": DisplaySystemMessages = str2bool(argValue); return true;
case "showxpbarmessages": DisplayXPBarMessages = str2bool(argValue); return true;
case "showchatlinks": DisplayChatLinks = str2bool(argValue); return true;
case "terrainandmovements": TerrainAndMovements = str2bool(argValue); return true;
case "entityhandling": EntityHandling = str2bool(argValue); return true;
case "enableentityhandling": EntityHandling = str2bool(argValue); return true;
case "inventoryhandling": InventoryHandling = str2bool(argValue); return true;
case "privatemsgscmdname": PrivateMsgsCmdName = argValue.ToLower().Trim(); return true;
case "autorespawn": AutoRespawn = str2bool(argValue); return true;
// Backward compatible so people can still enable debug with old config format
case "debugmessages": DebugMessages = str2bool(argValue); break;
case "minecraftrealms": MinecraftRealmsEnabled = str2bool(argValue); break;
case "debugmessages": DebugMessages = str2bool(argValue); return true;
case "minecraftrealms": MinecraftRealmsEnabled = str2bool(argValue); return true;
case "botowners":
Bots_Owners.Clear();
@ -319,7 +375,7 @@ namespace MinecraftClient
foreach (string name in names)
if (!String.IsNullOrWhiteSpace(name))
Bots_Owners.Add(name.Trim());
break;
return true;
case "internalcmdchar":
switch (argValue.ToLower())
@ -328,13 +384,13 @@ namespace MinecraftClient
case "slash": internalCmdChar = '/'; break;
case "backslash": internalCmdChar = '\\'; break;
}
break;
return true;
case "sessioncache":
if (argValue == "none") { SessionCaching = CacheType.None; }
else if (argValue == "memory") { SessionCaching = CacheType.Memory; }
else if (argValue == "disk") { SessionCaching = CacheType.Disk; }
break;
return true;
case "accountlist":
if (File.Exists(argValue))
@ -349,9 +405,9 @@ namespace MinecraftClient
}
//Try user value against aliases after load
Settings.SetAccount(Login);
SetAccount(Login);
}
break;
return true;
case "serverlist":
if (File.Exists(argValue))
@ -378,9 +434,13 @@ namespace MinecraftClient
ServerPort = server_port_temp;
//Try server value against aliases after load
SetServerIP(serverAlias);
if (!String.IsNullOrEmpty(ServerAliasTemp))
{
SetServerIP(ServerAliasTemp);
ServerAliasTemp = null;
}
break;
}
return true;
case "brandinfo":
switch (argValue.Trim().ToLower())
@ -389,7 +449,7 @@ namespace MinecraftClient
case "vanilla": BrandInfo = "vanilla"; break;
default: BrandInfo = null; break;
}
break;
return true;
case "resolvesrvrecords":
if (argValue.Trim().ToLower() == "fast")
@ -402,7 +462,7 @@ namespace MinecraftClient
ResolveSrvRecords = str2bool(argValue);
ResolveSrvRecordsShortTimeout = false;
}
break;
return true;
case "mcforge":
if (argValue.ToLower() == "auto")
@ -415,58 +475,58 @@ namespace MinecraftClient
ServerAutodetectForge = false;
ServerForceForge = str2bool(argValue);
}
break;
return true;
}
break;
case ParseMode.Logging:
case Section.Logging:
switch (argName.ToLower())
{
case "debugmessages": DebugMessages = str2bool(argValue); break;
case "chatmessages": ChatMessages = str2bool(argValue); break;
case "warningmessages": WarningMessages = str2bool(argValue); break;
case "errormessages": ErrorMessages = str2bool(argValue); break;
case "infomessages": InfoMessages = str2bool(argValue); break;
case "chatfilter": ChatFilter = new Regex(argValue); break;
case "debugfilter": DebugFilter = new Regex(argValue); break;
case "debugmessages": DebugMessages = str2bool(argValue); return true;
case "chatmessages": ChatMessages = str2bool(argValue); return true;
case "warningmessages": WarningMessages = str2bool(argValue); return true;
case "errormessages": ErrorMessages = str2bool(argValue); return true;
case "infomessages": InfoMessages = str2bool(argValue); return true;
case "chatfilter": ChatFilter = new Regex(argValue); return true;
case "debugfilter": DebugFilter = new Regex(argValue); return true;
case "filtermode":
if (argValue.ToLower().StartsWith("white"))
FilterMode = FilterModeEnum.Whitelist;
else
FilterMode = FilterModeEnum.Blacklist;
break;
case "logtofile": LogToFile = str2bool(argValue); break;
case "logfile": LogFile = argValue; break;
case "prependtimestamp": PrependTimestamp = str2bool(argValue); break;
return true;
case "logtofile": LogToFile = str2bool(argValue); return true;
case "logfile": LogFile = argValue; return true;
case "prependtimestamp": PrependTimestamp = str2bool(argValue); return true;
}
break;
case ParseMode.Alerts:
case Section.Alerts:
switch (argName.ToLower())
{
case "enabled": Alerts_Enabled = str2bool(argValue); break;
case "alertsfile": Alerts_MatchesFile = argValue; break;
case "excludesfile": Alerts_ExcludesFile = argValue; break;
case "beeponalert": Alerts_Beep_Enabled = str2bool(argValue); break;
case "enabled": Alerts_Enabled = str2bool(argValue); return true;
case "alertsfile": Alerts_MatchesFile = argValue; return true;
case "excludesfile": Alerts_ExcludesFile = argValue; return true;
case "beeponalert": Alerts_Beep_Enabled = str2bool(argValue); return true;
}
break;
case ParseMode.AntiAFK:
case Section.AntiAFK:
switch (argName.ToLower())
{
case "enabled": AntiAFK_Enabled = str2bool(argValue); break;
case "delay": AntiAFK_Delay = str2int(argValue); break;
case "command": AntiAFK_Command = argValue == "" ? "/ping" : argValue; break;
case "enabled": AntiAFK_Enabled = str2bool(argValue); return true;
case "delay": AntiAFK_Delay = str2int(argValue); return true;
case "command": AntiAFK_Command = argValue == "" ? "/ping" : argValue; return true;
}
break;
case ParseMode.AutoRelog:
case Section.AutoRelog:
switch (argName.ToLower())
{
case "enabled": AutoRelog_Enabled = str2bool(argValue); break;
case "retries": AutoRelog_Retries = str2int(argValue); break;
case "ignorekickmessage": AutoRelog_IgnoreKickMessage = str2bool(argValue); break;
case "kickmessagesfile": AutoRelog_KickMessagesFile = argValue; break;
case "enabled": AutoRelog_Enabled = str2bool(argValue); return true;
case "retries": AutoRelog_Retries = str2int(argValue); return true;
case "ignorekickmessage": AutoRelog_IgnoreKickMessage = str2bool(argValue); return true;
case "kickmessagesfile": AutoRelog_KickMessagesFile = argValue; return true;
case "delay":
string[] delayParts = argValue.Split('-');
@ -480,72 +540,72 @@ namespace MinecraftClient
AutoRelog_Delay_Min = str2int(delayParts[0]);
AutoRelog_Delay_Max = str2int(delayParts[1]);
}
break;
return true;
}
break;
case ParseMode.ChatLog:
case Section.ChatLog:
switch (argName.ToLower())
{
case "enabled": ChatLog_Enabled = str2bool(argValue); break;
case "timestamps": ChatLog_DateTime = str2bool(argValue); break;
case "filter": ChatLog_Filter = ChatBots.ChatLog.str2filter(argValue); break;
case "logfile": ChatLog_File = argValue; break;
case "enabled": ChatLog_Enabled = str2bool(argValue); return true;
case "timestamps": ChatLog_DateTime = str2bool(argValue); return true;
case "filter": ChatLog_Filter = ChatBots.ChatLog.str2filter(argValue); return true;
case "logfile": ChatLog_File = argValue; return true;
}
break;
case ParseMode.Hangman:
case Section.Hangman:
switch (argName.ToLower())
{
case "enabled": Hangman_Enabled = str2bool(argValue); break;
case "english": Hangman_English = str2bool(argValue); break;
case "wordsfile": Hangman_FileWords_EN = argValue; break;
case "fichiermots": Hangman_FileWords_FR = argValue; break;
case "enabled": Hangman_Enabled = str2bool(argValue); return true;
case "english": Hangman_English = str2bool(argValue); return true;
case "wordsfile": Hangman_FileWords_EN = argValue; return true;
case "fichiermots": Hangman_FileWords_FR = argValue; return true;
}
break;
case ParseMode.ScriptScheduler:
case Section.ScriptScheduler:
switch (argName.ToLower())
{
case "enabled": ScriptScheduler_Enabled = str2bool(argValue); break;
case "tasksfile": ScriptScheduler_TasksFile = argValue; break;
case "enabled": ScriptScheduler_Enabled = str2bool(argValue); return true;
case "tasksfile": ScriptScheduler_TasksFile = argValue; return true;
}
break;
case ParseMode.RemoteControl:
case Section.RemoteControl:
switch (argName.ToLower())
{
case "enabled": RemoteCtrl_Enabled = str2bool(argValue); break;
case "autotpaccept": RemoteCtrl_AutoTpaccept = str2bool(argValue); break;
case "tpaccepteveryone": RemoteCtrl_AutoTpaccept_Everyone = str2bool(argValue); break;
case "enabled": RemoteCtrl_Enabled = str2bool(argValue); return true;
case "autotpaccept": RemoteCtrl_AutoTpaccept = str2bool(argValue); return true;
case "tpaccepteveryone": RemoteCtrl_AutoTpaccept_Everyone = str2bool(argValue); return true;
}
break;
case ParseMode.ChatFormat:
case Section.ChatFormat:
switch (argName.ToLower())
{
case "builtins": ChatFormat_Builtins = str2bool(argValue); break;
case "public": ChatFormat_Public = new Regex(argValue); break;
case "private": ChatFormat_Private = new Regex(argValue); break;
case "tprequest": ChatFormat_TeleportRequest = new Regex(argValue); break;
case "builtins": ChatFormat_Builtins = str2bool(argValue); return true;
case "public": ChatFormat_Public = new Regex(argValue); return true;
case "private": ChatFormat_Private = new Regex(argValue); return true;
case "tprequest": ChatFormat_TeleportRequest = new Regex(argValue); return true;
}
break;
case ParseMode.Proxy:
case Section.Proxy:
switch (argName.ToLower())
{
case "enabled":
ProxyEnabledLogin = ProxyEnabledIngame = str2bool(argValue);
if (argValue.Trim().ToLower() == "login")
ProxyEnabledLogin = true;
break;
return true;
case "type":
argValue = argValue.ToLower();
if (argValue == "http") { proxyType = Proxy.ProxyHandler.Type.HTTP; }
else if (argValue == "socks4") { proxyType = Proxy.ProxyHandler.Type.SOCKS4; }
else if (argValue == "socks4a") { proxyType = Proxy.ProxyHandler.Type.SOCKS4a; }
else if (argValue == "socks5") { proxyType = Proxy.ProxyHandler.Type.SOCKS5; }
break;
return true;
case "server":
string[] host_splitted = argValue.Split(':');
if (host_splitted.Length == 1)
@ -558,29 +618,30 @@ namespace MinecraftClient
ProxyHost = host_splitted[0];
ProxyPort = str2int(host_splitted[1]);
}
break;
case "username": ProxyUsername = argValue; break;
case "password": ProxyPassword = argValue; break;
return true;
case "username": ProxyUsername = argValue; return true;
case "password": ProxyPassword = argValue; return true;
}
break;
case ParseMode.AppVars:
case Section.AppVars:
SetVar(argName, argValue);
break;
return true;
case ParseMode.AutoRespond:
case Section.AutoRespond:
switch (argName.ToLower())
{
case "enabled": AutoRespond_Enabled = str2bool(argValue); break;
case "matchesfile": AutoRespond_Matches = argValue; break;
case "enabled": AutoRespond_Enabled = str2bool(argValue); return true;
case "matchesfile": AutoRespond_Matches = argValue; return true;
}
break;
case ParseMode.AutoAttack:
case Section.AutoAttack:
switch (argName.ToLower())
{
case "enabled": AutoAttack_Enabled = str2bool(argValue); break;
case "mode": AutoAttack_Mode = argValue.ToLower(); break;
case "priority": AutoAttack_Priority = argValue.ToLower(); break;
case "enabled": AutoAttack_Enabled = str2bool(argValue); return true;
case "mode": AutoAttack_Mode = argValue.ToLower(); return true;
case "priority": AutoAttack_Priority = argValue.ToLower(); return true;
case "cooldownseconds":
if (argValue.ToLower() == "auto")
{
@ -591,48 +652,48 @@ namespace MinecraftClient
AutoAttack_OverrideAttackSpeed = true;
AutoAttack_CooldownSeconds = str2float(argValue);
}
break;
return true;
}
break;
case ParseMode.AutoFishing:
case Section.AutoFishing:
switch (argName.ToLower())
{
case "enabled": AutoFishing_Enabled = str2bool(argValue); break;
case "antidespawn": AutoFishing_Antidespawn = str2bool(argValue); break;
case "enabled": AutoFishing_Enabled = str2bool(argValue); return true;
case "antidespawn": AutoFishing_Antidespawn = str2bool(argValue); return true;
}
break;
case ParseMode.AutoEat:
case Section.AutoEat:
switch (argName.ToLower())
{
case "enabled": AutoEat_Enabled = str2bool(argValue); break;
case "threshold": AutoEat_hungerThreshold = str2int(argValue); break;
case "enabled": AutoEat_Enabled = str2bool(argValue); return true;
case "threshold": AutoEat_hungerThreshold = str2int(argValue); return true;
}
break;
case ParseMode.AutoCraft:
case Section.AutoCraft:
switch (argName.ToLower())
{
case "enabled": AutoCraft_Enabled = str2bool(argValue); break;
case "configfile": AutoCraft_configFile = argValue; break;
case "enabled": AutoCraft_Enabled = str2bool(argValue); return true;
case "configfile": AutoCraft_configFile = argValue; return true;
}
break;
case ParseMode.AutoDrop:
case Section.AutoDrop:
switch (argName.ToLower())
{
case "enabled": AutoDrop_Enabled = str2bool(argValue); break;
case "mode": AutoDrop_Mode = argValue; break;
case "items": AutoDrop_items = argValue; break;
case "enabled": AutoDrop_Enabled = str2bool(argValue); return true;
case "mode": AutoDrop_Mode = argValue; return true;
case "items": AutoDrop_items = argValue; return true;
}
break;
case ParseMode.MCSettings:
case Section.MCSettings:
switch (argName.ToLower())
{
case "enabled": MCSettings_Enabled = str2bool(argValue); break;
case "locale": MCSettings_Locale = argValue; break;
case "enabled": MCSettings_Enabled = str2bool(argValue); return true;
case "locale": MCSettings_Locale = argValue; return true;
case "difficulty":
switch (argValue.ToLower())
{
@ -641,7 +702,7 @@ namespace MinecraftClient
case "normal": MCSettings_Difficulty = 2; break;
case "difficult": MCSettings_Difficulty = 3; break;
}
break;
return true;
case "renderdistance":
MCSettings_RenderDistance = 2;
if (argValue.All(Char.IsDigit))
@ -658,7 +719,7 @@ namespace MinecraftClient
case "far": MCSettings_RenderDistance = 16; break;
}
}
break;
return true;
case "chatmode":
switch (argValue.ToLower())
{
@ -666,52 +727,47 @@ namespace MinecraftClient
case "commands": MCSettings_ChatMode = 1; break;
case "disabled": MCSettings_ChatMode = 2; break;
}
break;
case "chatcolors": MCSettings_ChatColors = str2bool(argValue); break;
case "skin_cape": MCSettings_Skin_Cape = str2bool(argValue); break;
case "skin_jacket": MCSettings_Skin_Jacket = str2bool(argValue); break;
case "skin_sleeve_left": MCSettings_Skin_Sleeve_Left = str2bool(argValue); break;
case "skin_sleeve_right": MCSettings_Skin_Sleeve_Right = str2bool(argValue); break;
case "skin_pants_left": MCSettings_Skin_Pants_Left = str2bool(argValue); break;
case "skin_pants_right": MCSettings_Skin_Pants_Right = str2bool(argValue); break;
case "skin_hat": MCSettings_Skin_Hat = str2bool(argValue); break;
return true;
case "chatcolors": MCSettings_ChatColors = str2bool(argValue); return true;
case "skin_cape": MCSettings_Skin_Cape = str2bool(argValue); return true;
case "skin_jacket": MCSettings_Skin_Jacket = str2bool(argValue); return true;
case "skin_sleeve_left": MCSettings_Skin_Sleeve_Left = str2bool(argValue); return true;
case "skin_sleeve_right": MCSettings_Skin_Sleeve_Right = str2bool(argValue); return true;
case "skin_pants_left": MCSettings_Skin_Pants_Left = str2bool(argValue); return true;
case "skin_pants_right": MCSettings_Skin_Pants_Right = str2bool(argValue); return true;
case "skin_hat": MCSettings_Skin_Hat = str2bool(argValue); return true;
case "main_hand":
switch (argValue.ToLower())
{
case "left": MCSettings_MainHand = 0; break;
case "right": MCSettings_MainHand = 1; break;
}
break;
return true;
}
break;
case ParseMode.Mailer:
case Section.Mailer:
switch (argName.ToLower())
{
case "enabled": Mailer_Enabled = str2bool(argValue); break;
case "database": Mailer_DatabaseFile = argValue; break;
case "ignorelist": Mailer_IgnoreListFile = argValue; break;
case "publicinteractions": Mailer_PublicInteractions = str2bool(argValue); break;
case "maxmailsperplayer": Mailer_MaxMailsPerPlayer = str2int(argValue); break;
case "maxdatabasesize": Mailer_MaxDatabaseSize = str2int(argValue); break;
case "retentiondays": Mailer_MailRetentionDays = str2int(argValue); break;
case "enabled": Mailer_Enabled = str2bool(argValue); return true;
case "database": Mailer_DatabaseFile = argValue; return true;
case "ignorelist": Mailer_IgnoreListFile = argValue; return true;
case "publicinteractions": Mailer_PublicInteractions = str2bool(argValue); return true;
case "maxmailsperplayer": Mailer_MaxMailsPerPlayer = str2int(argValue); return true;
case "maxdatabasesize": Mailer_MaxDatabaseSize = str2int(argValue); return true;
case "retentiondays": Mailer_MailRetentionDays = str2int(argValue); return true;
}
break;
case ParseMode.ReplayMod:
case Section.ReplayMod:
switch (argName.ToLower())
{
case "enabled": ReplayMod_Enabled = str2bool(argValue); break;
case "backupinterval": ReplayMod_BackupInterval = str2int(argValue); break;
case "enabled": ReplayMod_Enabled = str2bool(argValue); return true;
case "backupinterval": ReplayMod_BackupInterval = str2int(argValue); return true;
}
break;
}
}
}
}
}
}
catch (IOException) { }
}
return false;
}
/// <summary>

View file

@ -50,25 +50,59 @@ You can have several INI files and drag & drop one of them over MinecraftClient.
Command-line usage
------
**MinecraftClient.exe username password server:**
Quick usage:
This will automatically connect you to the chosen server.
To specify a server and ask password interactively, use "" as password.
To specify offline mode with no password, use "-" as password.
```
MinecraftClient.exe --help
MinecraftClient.exe <username> <password> <server>
MinecraftClient.exe <username> <password> <server> "/mycommand"
MinecraftClient.exe --setting=value [--other settings]
MinecraftClient.exe --section.setting=value [--other settings]
MinecraftClient.exe <settings-file.ini> [--other settings]
```
You can mix and match arguments by following theses rules:
* First positional argument may be either the login or settings file
* Other positional arguments are read in order: login, password, server, command
* Arguments starting with `--` can be in any order and position
**MinecraftClient.exe username password server "/mycommand":**
Examples and further explanations:
This will automatically send "/mycommand" to the server and close.
To send several commands and maybe stay connected, use the Scripting bot instead.
```
MinecraftClient.exe <login> <password> <server>
```
**MinecraftClient.exe myconfig.ini:**
* This will automatically connect you to the chosen server.
* You may omit password and/or server to specify e.g. only the login
* To specify a server but ask password interactively, use `""` as password.
* To specify offline mode with no password, use `-` as password.
This will load the specified configuration file
If the file contains login / password / server ip, it will automatically connect.
```
MinecraftClient.exe <login> <password> <server> "/mycommand"
```
**MinecraftClient.exe myconfig.ini othername otherpassword otherIP:**
* This will automatically send `/mycommand` to the server and close.
* To send several commands and/or stay connected, use the ScriptScheduler bot instead.
Load the specified configuration file and override some settings from the file.
```
MinecraftClient.exe <myconfig.ini>
```
* This will load the specified configuration file
* If the file contains login / password / server ip, it will automatically connect.
```
MinecraftClient.exe --setting=value [--other settings]
```
* Specify settings on the command-line, see possible value in the configuration file
* Use `--section.setting=value` for settings outside the `[Main]` section
* Example: `--antiafk.enabled=true` for enabling the AntiAFK bot
```
MinecraftClient.exe <myconfig.ini> <login> <password> <server> [--other settings]
```
* Load the specified configuration file and override some settings from the file
Internal commands
------