Add support of language files (#1273)

* Basic support of language file
Only mapped main part of MCC.
* Translations function imporve
* Change translation file naming
* Fix default translation file naming
* Complete translation file mapping for main part
Command and ChatBot not done yet
* Complete translation mapping for commands
Except Entitycmd
* Complete translation mapping for ChatBots
* Add new method for replacing translation key
Just for Entitycmd. Be proud of yourself. We have a convenient method now.
* Complete all translation mapping
* Add default config and translation file to resource
* Remove untranslatable messages from default translation file
This commit is contained in:
ReinforceZwei 2020-10-17 19:41:31 +08:00 committed by GitHub
parent 0c88c18ea0
commit 2017d5d652
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
54 changed files with 1658 additions and 660 deletions

View file

@ -34,7 +34,7 @@ namespace MinecraftClient
//Script compatibility check for handling future versions differently //Script compatibility check for handling future versions differently
if (lines.Length < 1 || lines[0] != "//MCCScript 1.0") if (lines.Length < 1 || lines[0] != "//MCCScript 1.0")
throw new CSharpException(CSErrorType.InvalidScript, throw new CSharpException(CSErrorType.InvalidScript,
new InvalidDataException("The provided script does not have a valid MCCScript header")); new InvalidDataException(Translations.Get("exception.csrunner.invalid_head")));
//Script hash for determining if it was previously compiled //Script hash for determining if it was previously compiled
ulong scriptHash = QuickHash(lines); ulong scriptHash = QuickHash(lines);

View file

@ -50,9 +50,7 @@ namespace MinecraftClient
return master.Handler; return master.Handler;
if (_handler != null) if (_handler != null)
return _handler; return _handler;
throw new InvalidOperationException( throw new InvalidOperationException(Translations.Get("exception.chatbot.init"));
"ChatBot methods should NOT be called in the constructor as API handler is not initialized yet."
+ " Override Initialize() or AfterGameJoined() instead to perform initialization tasks.");
} }
} }
private bool MessageCooldownEnded private bool MessageCooldownEnded
@ -762,6 +760,26 @@ namespace MinecraftClient
LogToConsole(text); LogToConsole(text);
} }
/// <summary>
/// Write the translated text in the console by giving a translation key. Nothing will be sent to the server.
/// </summary>
/// <param name="key">Translation key</param>
/// <param name="args"></param>
protected void LogToConsoleTranslated(string key, params object[] args)
{
LogToConsole(Translations.TryGet(key, args));
}
/// <summary>
/// Write the translated text in the console by giving a translation key, but only if DebugMessages is enabled in INI file. Nothing will be sent to the server.
/// </summary>
/// <param name="key">Translation key</param>
/// <param name="args"></param>
protected void LogDebugToConsoleTranslated(string key, params object[] args)
{
LogDebugToConsole(Translations.TryGet(key, args));
}
/// <summary> /// <summary>
/// Disconnect from the server and restart the program /// Disconnect from the server and restart the program
/// It will unload and reload all the bots and then reconnect to the server /// It will unload and reload all the bots and then reconnect to the server
@ -771,7 +789,7 @@ namespace MinecraftClient
protected void ReconnectToTheServer(int ExtraAttempts = 3, int delaySeconds = 0) protected void ReconnectToTheServer(int ExtraAttempts = 3, int delaySeconds = 0)
{ {
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLogLine(String.Format("[{0}] Disconnecting and Reconnecting to the Server", this.GetType().Name)); ConsoleIO.WriteLogLine(Translations.Get("chatbot.reconnect", this.GetType().Name));
McClient.ReconnectionAttemptsLeft = ExtraAttempts; McClient.ReconnectionAttemptsLeft = ExtraAttempts;
Program.Restart(delaySeconds); Program.Restart(delaySeconds);
} }
@ -1264,9 +1282,9 @@ namespace MinecraftClient
/// <param name="cmdDesc">Description/usage of the command</param> /// <param name="cmdDesc">Description/usage of the command</param>
/// <param name="callback">Method for handling the command</param> /// <param name="callback">Method for handling the command</param>
/// <returns>True if successfully registered</returns> /// <returns>True if successfully registered</returns>
protected bool RegisterChatBotCommand(string cmdName, string cmdDesc, CommandRunner callback) protected bool RegisterChatBotCommand(string cmdName, string cmdDesc, string cmdUsage, CommandRunner callback)
{ {
return Handler.RegisterCommand(cmdName, cmdDesc, callback); return Handler.RegisterCommand(cmdName, cmdDesc, cmdUsage, callback);
} }
/// <summary> /// <summary>
@ -1337,9 +1355,11 @@ namespace MinecraftClient
private readonly string _cmdName; private readonly string _cmdName;
private readonly string _cmdDesc; private readonly string _cmdDesc;
private readonly string _cmdUsage;
public override string CMDName { get { return _cmdName; } } public override string CmdName { get { return _cmdName; } }
public override string CMDDesc { get { return _cmdDesc; } } public override string CmdUsage { get { return _cmdUsage; } }
public override string CmdDesc { get { return _cmdDesc; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
@ -1349,13 +1369,15 @@ namespace MinecraftClient
/// <summary> /// <summary>
/// ChatBotCommand Constructor /// ChatBotCommand Constructor
/// </summary> /// </summary>
/// <param name="CMDName">Name of the command</param> /// <param name="cmdName">Name of the command</param>
/// <param name="CMDDesc">Description/usage of the command</param> /// <param name="cmdDesc">Description of the command. Support tranlation.</param>
/// <param name="runner">Method for handling the command</param> /// <param name="cmdUsage">Usage of the command</param>
public ChatBotCommand(string cmdName, string cmdDesc, CommandRunner callback) /// <param name="callback">Method for handling the command</param>
public ChatBotCommand(string cmdName, string cmdDesc, string cmdUsage, CommandRunner callback)
{ {
this._cmdName = cmdName; this._cmdName = cmdName;
this._cmdDesc = cmdDesc; this._cmdDesc = cmdDesc;
this._cmdUsage = cmdUsage;
this.Runner = callback; this.Runner = callback;
} }
} }

View file

@ -28,21 +28,21 @@ namespace MinecraftClient.ChatBots
singleMode = true; singleMode = true;
else if (mode == "multi") else if (mode == "multi")
singleMode = false; singleMode = false;
else LogToConsole("Unknown attack mode: " + mode + ". Using single mode as default."); else LogToConsoleTranslated("bot.autoAttack.mode", mode);
if (priority == "distance") if (priority == "distance")
priorityDistance = true; priorityDistance = true;
else if (priority == "health") else if (priority == "health")
priorityDistance = false; priorityDistance = false;
else LogToConsole("Unknown priority: " + priority + ". Using distance priority as default."); else LogToConsoleTranslated("bot.autoAttack.priority", priority);
} }
public override void Initialize() public override void Initialize()
{ {
if (!GetEntityHandlingEnabled()) if (!GetEntityHandlingEnabled())
{ {
LogToConsole("Entity Handling is not enabled in the config file!"); LogToConsoleTranslated("extra.entity_required");
LogToConsole("This bot will be unloaded."); LogToConsoleTranslated("general.bot_unload");
UnloadBot(); UnloadBot();
} }
} }

View file

@ -166,12 +166,13 @@ namespace MinecraftClient.ChatBots
{ {
if (!GetInventoryEnabled()) if (!GetInventoryEnabled())
{ {
LogToConsole("Inventory handling is disabled. AutoCraft will be unloaded"); LogToConsoleTranslated("extra.inventory_required");
LogToConsoleTranslated("general.bot_unload");
UnloadBot(); UnloadBot();
return; return;
} }
RegisterChatBotCommand("autocraft", "Auto-crafting ChatBot command", CommandHandler); RegisterChatBotCommand("autocraft", Translations.Get("bot.autoCraft.cmd"), GetHelp(), CommandHandler);
RegisterChatBotCommand("ac", "Auto-crafting ChatBot command alias", CommandHandler); RegisterChatBotCommand("ac", Translations.Get("bot.autoCraft.alias"), GetHelp(), CommandHandler);
LoadConfig(); LoadConfig();
} }
@ -186,14 +187,14 @@ namespace MinecraftClient.ChatBots
return ""; return "";
case "list": case "list":
string names = string.Join(", ", recipes.Keys.ToList()); string names = string.Join(", ", recipes.Keys.ToList());
return String.Format("Total {0} recipes loaded: {1}", recipes.Count, names); return Translations.Get("bot.autoCraft.cmd.list", recipes.Count, names);
case "reload": case "reload":
recipes.Clear(); recipes.Clear();
LoadConfig(); LoadConfig();
return ""; return "";
case "resetcfg": case "resetcfg":
WriteDefaultConfig(); WriteDefaultConfig();
return "Resetting your config to default"; return Translations.Get("bot.autoCraft.cmd.resetcfg");
case "start": case "start":
if (args.Length >= 2) if (args.Length >= 2)
{ {
@ -204,12 +205,12 @@ namespace MinecraftClient.ChatBots
PrepareCrafting(recipes[name]); PrepareCrafting(recipes[name]);
return ""; return "";
} }
else return "Specified recipe name does not exist. Check your config file."; else return Translations.Get("bot.autoCraft.recipe_not_exist");
} }
else return "Please specify the recipe name you want to craft."; else return Translations.Get("bot.autoCraft.no_recipe_name");
case "stop": case "stop":
StopCrafting(); StopCrafting();
return "AutoCraft stopped"; return Translations.Get("bot.autoCraft.stop");
case "help": case "help":
return GetCommandHelp(args.Length >= 2 ? args[1] : ""); return GetCommandHelp(args.Length >= 2 ? args[1] : "");
default: default:
@ -221,7 +222,7 @@ namespace MinecraftClient.ChatBots
private string GetHelp() private string GetHelp()
{ {
return "Available commands: load, list, reload, resetcfg, start, stop, help. Use /autocraft help <cmd name> for more information. You may use /ac as command alias."; return Translations.Get("bot.autoCraft.available_cmd", "load, list, reload, resetcfg, start, stop, help");
} }
private string GetCommandHelp(string cmd) private string GetCommandHelp(string cmd)
@ -229,19 +230,19 @@ namespace MinecraftClient.ChatBots
switch (cmd.ToLower()) switch (cmd.ToLower())
{ {
case "load": case "load":
return "Load the config file."; return Translations.Get("bot.autocraft.help.load");
case "list": case "list":
return "List loaded recipes name."; return Translations.Get("bot.autocraft.help.list");
case "reload": case "reload":
return "Reload the config file."; return Translations.Get("bot.autocraft.help.reload");
case "resetcfg": case "resetcfg":
return "Write the default example config to default location."; return Translations.Get("bot.autocraft.help.resetcfg");
case "start": case "start":
return "Start the crafting. Usage: /autocraft start <recipe name>"; return Translations.Get("bot.autocraft.help.start");
case "stop": case "stop":
return "Stop the current running crafting process"; return Translations.Get("bot.autocraft.help.stop");
case "help": case "help":
return "Get the command description. Usage: /autocraft help <command name>"; return Translations.Get("bot.autocraft.help.help");
default: default:
return GetHelp(); return GetHelp();
} }
@ -258,16 +259,16 @@ namespace MinecraftClient.ChatBots
Directory.CreateDirectory(@"autocraft"); Directory.CreateDirectory(@"autocraft");
} }
WriteDefaultConfig(); WriteDefaultConfig();
LogDebugToConsole("No config found. Writing a new one."); LogDebugToConsoleTranslated("bot.autoCraft.debug.no_config");
} }
try try
{ {
ParseConfig(); ParseConfig();
LogToConsole("Successfully loaded"); LogToConsoleTranslated("bot.autoCraft.loaded");
} }
catch (Exception e) catch (Exception e)
{ {
LogToConsole("Error while parsing config: \n" + e.Message); LogToConsoleTranslated("bot.autoCraft.error.config", "\n" + e.Message);
} }
} }
@ -301,11 +302,11 @@ namespace MinecraftClient.ChatBots
string[] content = File.ReadAllLines(configPath); string[] content = File.ReadAllLines(configPath);
if (content.Length <= 0) if (content.Length <= 0)
{ {
throw new Exception("Empty onfiguration file: " + configPath); throw new Exception(Translations.Get("bot.autoCraft.exception.empty", configPath));
} }
if (content[0].ToLower() != "[autocraft]") if (content[0].ToLower() != "[autocraft]")
{ {
throw new Exception("Invalid configuration file: " + configPath); throw new Exception(Translations.Get("bot.autoCraft.exception.invalid", configPath));
} }
// local variable for use in parsing config // local variable for use in parsing config
@ -352,7 +353,7 @@ namespace MinecraftClient.ChatBots
} }
else else
{ {
throw new Exception("Missing item in recipe: " + pair.Key); throw new Exception(Translations.Get("bot.autoCraft.exception.item_miss", pair.Key));
} }
} }
@ -373,7 +374,7 @@ namespace MinecraftClient.ChatBots
tableLocation.Y = Convert.ToInt32(values[1]); tableLocation.Y = Convert.ToInt32(values[1]);
tableLocation.Z = Convert.ToInt32(values[2]); tableLocation.Z = Convert.ToInt32(values[2]);
} }
else throw new Exception("Invalid tablelocation format: " + key); else throw new Exception(Translations.Get("bot.autoCraft.exception.invalid_table", key));
break; break;
case "onfailure": case "onfailure":
abortOnFailure = value.ToLower() == "abort" ? true : false; abortOnFailure = value.ToLower() == "abort" ? true : false;
@ -411,17 +412,17 @@ namespace MinecraftClient.ChatBots
} }
else else
{ {
throw new Exception("Invalid item name in recipe " + lastRecipe + " at " + key); throw new Exception(Translations.Get("bot.autoCraft.exception.item_name", lastRecipe, key));
} }
} }
else else
{ {
throw new Exception("Missing recipe name while parsing a recipe"); throw new Exception(Translations.Get("bot.autoCraft.exception.name_miss"));
} }
} }
else else
{ {
throw new Exception("Invalid slot field in recipe: " + key); throw new Exception(Translations.Get("bot.autoCraft.exception.slot", key));
} }
} }
else else
@ -436,7 +437,7 @@ namespace MinecraftClient.ChatBots
} }
else else
{ {
throw new Exception("Duplicate recipe name specified: " + value); throw new Exception(Translations.Get("bot.autoCraft.exception.duplicate", value));
} }
break; break;
case "type": case "type":
@ -555,7 +556,7 @@ namespace MinecraftClient.ChatBots
// table required but not found. Try to open one // table required but not found. Try to open one
OpenTable(tableLocation); OpenTable(tableLocation);
waitingForTable = true; waitingForTable = true;
SetTimeout("table not found"); SetTimeout(Translations.Get("bot.autoCraft.table_not_found"));
return; return;
} }
} }
@ -577,10 +578,10 @@ namespace MinecraftClient.ChatBots
// Repeat the whole process again // Repeat the whole process again
actionSteps.Add(new ActionStep(ActionType.Repeat)); actionSteps.Add(new ActionStep(ActionType.Repeat));
// Start crafting // Start crafting
ConsoleIO.WriteLogLine("Starting AutoCraft: " + recipe.ResultItem); LogToConsoleTranslated("bot.autoCraft.start", recipe.ResultItem);
HandleNextStep(); HandleNextStep();
} }
else ConsoleIO.WriteLogLine("AutoCraft cannot be started. Check your available materials for crafting " + recipe.ResultItem); else LogToConsoleTranslated("bot.autoCraft.start_fail", recipe.ResultItem);
} }
/// <summary> /// <summary>
@ -596,7 +597,7 @@ namespace MinecraftClient.ChatBots
if (GetInventories().ContainsKey(inventoryInUse)) if (GetInventories().ContainsKey(inventoryInUse))
{ {
CloseInventory(inventoryInUse); CloseInventory(inventoryInUse);
ConsoleIO.WriteLogLine("Inventory #" + inventoryInUse + " was closed by AutoCraft"); LogToConsoleTranslated("bot.autoCraft.close_inventory", inventoryInUse);
} }
} }
@ -679,12 +680,12 @@ namespace MinecraftClient.ChatBots
if (actionSteps[index - 1].ActionType == ActionType.LeftClick && actionSteps[index - 1].ItemType != ItemType.Air) if (actionSteps[index - 1].ActionType == ActionType.LeftClick && actionSteps[index - 1].ItemType != ItemType.Air)
{ {
// Inform user the missing meterial name // Inform user the missing meterial name
ConsoleIO.WriteLogLine("Missing material: " + actionSteps[index - 1].ItemType.ToString()); LogToConsoleTranslated("bot.autoCraft.missing_material", actionSteps[index - 1].ItemType.ToString());
} }
if (abortOnFailure) if (abortOnFailure)
{ {
StopCrafting(); StopCrafting();
ConsoleIO.WriteLogLine("Crafting aborted! Check your available materials."); LogToConsoleTranslated("bot.autoCraft.aborted");
} }
else else
{ {
@ -692,14 +693,14 @@ namespace MinecraftClient.ChatBots
// Even though crafting failed, action step index will still increase // Even though crafting failed, action step index will still increase
// we want to do that failed step again so decrease index by 1 // we want to do that failed step again so decrease index by 1
index--; index--;
ConsoleIO.WriteLogLine("Crafting failed! Waiting for more materials"); LogToConsoleTranslated("bot.autoCraft.craft_fail");
} }
} }
} }
private void HandleUpdateTimeout() private void HandleUpdateTimeout()
{ {
ConsoleIO.WriteLogLine("Action timeout! Reason: " + timeoutAction); LogToConsoleTranslated("bot.autoCraft.timeout", timeoutAction);
} }
/// <summary> /// <summary>

View file

@ -64,10 +64,10 @@ namespace MinecraftClient.ChatBots
enable = true; enable = true;
inventoryUpdated = 0; inventoryUpdated = 0;
OnUpdateFinish(); OnUpdateFinish();
return "AutoDrop enabled"; return Translations.Get("bot.autoDrop.on");
case "off": case "off":
enable = false; enable = false;
return "AutoDrop disabled"; return Translations.Get("bot.autoDrop.off");
case "add": case "add":
if (args.Length >= 2) if (args.Length >= 2)
{ {
@ -75,16 +75,16 @@ namespace MinecraftClient.ChatBots
if (Enum.TryParse(args[1], true, out item)) if (Enum.TryParse(args[1], true, out item))
{ {
itemList.Add(item); itemList.Add(item);
return "Added item " + item.ToString(); return Translations.Get("bot.autoDrop.added", item.ToString());
} }
else else
{ {
return "Incorrect item name " + args[1] + ". Please try again"; return Translations.Get("bot.autoDrop.incorrect_name", args[1]);
} }
} }
else else
{ {
return "Usage: add <item name>"; return Translations.Get("cmd.inventory.help.usage") + ": add <item name>";
} }
case "remove": case "remove":
if (args.Length >= 2) if (args.Length >= 2)
@ -95,30 +95,30 @@ namespace MinecraftClient.ChatBots
if (itemList.Contains(item)) if (itemList.Contains(item))
{ {
itemList.Remove(item); itemList.Remove(item);
return "Removed item " + item.ToString(); return Translations.Get("bot.autoDrop.removed", item.ToString());
} }
else else
{ {
return "Item not in the list"; return Translations.Get("bot.autoDrop.not_in_list");
} }
} }
else else
{ {
return "Incorrect item name " + args[1] + ". Please try again"; return Translations.Get("bot.autoDrop.incorrect_name", args[1]);
} }
} }
else else
{ {
return "Usage: remove <item name>"; return Translations.Get("cmd.inventory.help.usage") + ": remove <item name>";
} }
case "list": case "list":
if (itemList.Count > 0) if (itemList.Count > 0)
{ {
return "Total " + itemList.Count + " in the list:\n" + string.Join("\n", itemList); return Translations.Get("bot.autoDrop.list", itemList.Count, string.Join("\n", itemList));
} }
else else
{ {
return "No item in the list"; return Translations.Get("bot.autoDrop.no_item");
} }
default: default:
return GetHelp(); return GetHelp();
@ -132,19 +132,20 @@ namespace MinecraftClient.ChatBots
private string GetHelp() private string GetHelp()
{ {
return "AutoDrop ChatBot command. Available commands: on, off, add, remove, list"; return Translations.Get("general.available_cmd", "on, off, add, remove, list");
} }
public override void Initialize() public override void Initialize()
{ {
if (!GetInventoryEnabled()) if (!GetInventoryEnabled())
{ {
LogToConsole("Inventory handling is disabled. Unloading..."); LogToConsoleTranslated("extra.inventory_required");
LogToConsoleTranslated("general.bot_unload");
UnloadBot(); UnloadBot();
return; return;
} }
RegisterChatBotCommand("autodrop", "AutoDrop ChatBot command", CommandHandler); RegisterChatBotCommand("autodrop", Translations.Get("bot.autoDrop.cmd"), GetHelp(), CommandHandler);
RegisterChatBotCommand("ad", "AutoDrop ChatBot command alias", CommandHandler); RegisterChatBotCommand("ad", Translations.Get("bot.autoDrop.alias"), GetHelp(), CommandHandler);
} }
public override void Update() public override void Update()

View file

@ -25,8 +25,8 @@ namespace MinecraftClient.ChatBots
{ {
if (!GetEntityHandlingEnabled()) if (!GetEntityHandlingEnabled())
{ {
LogToConsole("Entity Handling is not enabled in the config file!"); LogToConsoleTranslated("extra.entity_required");
LogToConsole("This bot will be unloaded."); LogToConsoleTranslated("general.bot_unload");
UnloadBot(); UnloadBot();
} }
inventoryEnabled = GetInventoryEnabled(); inventoryEnabled = GetInventoryEnabled();
@ -50,7 +50,7 @@ namespace MinecraftClient.ChatBots
{ {
if (GetCurrentLocation().Distance(entity.Location) < 2 && !isFishing) if (GetCurrentLocation().Distance(entity.Location) < 2 && !isFishing)
{ {
LogToConsole("Threw a fishing rod"); LogToConsoleTranslated("bot.autoFish.throw");
fishingRod = entity; fishingRod = entity;
LastPos = entity.Location; LastPos = entity.Location;
isFishing = true; isFishing = true;
@ -108,14 +108,14 @@ namespace MinecraftClient.ChatBots
/// </summary> /// </summary>
public void OnCaughtFish() public void OnCaughtFish()
{ {
LogToConsole(GetTimestamp() + ": Caught a fish!"); LogToConsole(GetTimestamp() + ": " + Translations.Get("bot.autoFish.caught"));
// retract fishing rod // retract fishing rod
UseItemInHand(); UseItemInHand();
if (inventoryEnabled) if (inventoryEnabled)
{ {
if (!hasFishingRod()) if (!hasFishingRod())
{ {
LogToConsole(GetTimestamp() + ": No Fishing Rod on hand. Maybe broken?"); LogToConsole(GetTimestamp() + ": " + Translations.Get("bot.autoFish.no_rod"));
return; return;
} }
} }

View file

@ -26,7 +26,7 @@ namespace MinecraftClient.ChatBots
McClient.ReconnectionAttemptsLeft = attempts; McClient.ReconnectionAttemptsLeft = attempts;
delay = DelayBeforeRelog; delay = DelayBeforeRelog;
if (delay < 1) { delay = 1; } if (delay < 1) { delay = 1; }
LogDebugToConsole("Launching with " + attempts + " reconnection attempts"); LogDebugToConsoleTranslated("bot.autoRelog.launch", attempts);
} }
public override void Initialize() public override void Initialize()
@ -34,27 +34,27 @@ namespace MinecraftClient.ChatBots
McClient.ReconnectionAttemptsLeft = attempts; McClient.ReconnectionAttemptsLeft = attempts;
if (Settings.AutoRelog_IgnoreKickMessage) if (Settings.AutoRelog_IgnoreKickMessage)
{ {
LogDebugToConsole("Initializing without a kick message file"); LogDebugToConsoleTranslated("bot.autoRelog.no_kick_msg");
} }
else else
{ {
if (System.IO.File.Exists(Settings.AutoRelog_KickMessagesFile)) if (System.IO.File.Exists(Settings.AutoRelog_KickMessagesFile))
{ {
LogDebugToConsole("Loading messages from file: " + System.IO.Path.GetFullPath(Settings.AutoRelog_KickMessagesFile)); LogDebugToConsoleTranslated("bot.autoRelog.loading", System.IO.Path.GetFullPath(Settings.AutoRelog_KickMessagesFile));
dictionary = System.IO.File.ReadAllLines(Settings.AutoRelog_KickMessagesFile, Encoding.UTF8); dictionary = System.IO.File.ReadAllLines(Settings.AutoRelog_KickMessagesFile, Encoding.UTF8);
for (int i = 0; i < dictionary.Length; i++) for (int i = 0; i < dictionary.Length; i++)
{ {
LogDebugToConsole(" Loaded message: " + dictionary[i]); LogDebugToConsoleTranslated("bot.autoRelog.loaded", dictionary[i]);
dictionary[i] = dictionary[i].ToLower(); dictionary[i] = dictionary[i].ToLower();
} }
} }
else else
{ {
LogToConsole("File not found: " + System.IO.Path.GetFullPath(Settings.AutoRelog_KickMessagesFile)); LogToConsoleTranslated("bot.autoRelog.not_found", System.IO.Path.GetFullPath(Settings.AutoRelog_KickMessagesFile));
LogDebugToConsole(" Current directory was: " + System.IO.Directory.GetCurrentDirectory()); LogDebugToConsoleTranslated("bot.autoRelog.curr_dir", System.IO.Directory.GetCurrentDirectory());
} }
} }
} }
@ -63,19 +63,19 @@ namespace MinecraftClient.ChatBots
{ {
if (reason == DisconnectReason.UserLogout) if (reason == DisconnectReason.UserLogout)
{ {
LogDebugToConsole("Disconnection initiated by User or MCC bot. Ignoring."); LogDebugToConsoleTranslated("bot.autoRelog.ignore");
} }
else else
{ {
message = GetVerbatim(message); message = GetVerbatim(message);
string comp = message.ToLower(); string comp = message.ToLower();
LogDebugToConsole("Got disconnected with message: " + message); LogDebugToConsoleTranslated("bot.autoRelog.disconnect_msg", message);
if (Settings.AutoRelog_IgnoreKickMessage) if (Settings.AutoRelog_IgnoreKickMessage)
{ {
LogDebugToConsole("Ignoring kick message, reconnecting anyway."); LogDebugToConsoleTranslated("bot.autoRelog.reconnect_always");
LogToConsole("Waiting " + delay + " seconds before reconnecting..."); LogToConsoleTranslated("bot.autoRelog.wait", delay);
System.Threading.Thread.Sleep(delay * 1000); System.Threading.Thread.Sleep(delay * 1000);
ReconnectToTheServer(); ReconnectToTheServer();
return true; return true;
@ -85,8 +85,8 @@ namespace MinecraftClient.ChatBots
{ {
if (comp.Contains(msg)) if (comp.Contains(msg))
{ {
LogDebugToConsole("Message contains '" + msg + "'. Reconnecting."); LogDebugToConsoleTranslated("bot.autoRelog.reconnect", msg);
LogToConsole("Waiting " + delay + " seconds before reconnecting..."); LogToConsoleTranslated("bot.autoRelog.wait", delay);
System.Threading.Thread.Sleep(delay * 1000); System.Threading.Thread.Sleep(delay * 1000);
McClient.ReconnectionAttemptsLeft = attempts; McClient.ReconnectionAttemptsLeft = attempts;
ReconnectToTheServer(); ReconnectToTheServer();
@ -94,7 +94,7 @@ namespace MinecraftClient.ChatBots
} }
} }
LogDebugToConsole("Message not containing any defined keywords. Ignoring."); LogDebugToConsoleTranslated("bot.autoRelog.reconnect_ignore");
} }
return false; return false;

View file

@ -62,7 +62,7 @@ namespace MinecraftClient.ChatBots
} }
if (String.IsNullOrEmpty(file) || file.IndexOfAny(Path.GetInvalidPathChars()) >= 0) if (String.IsNullOrEmpty(file) || file.IndexOfAny(Path.GetInvalidPathChars()) >= 0)
{ {
LogToConsole("Path '" + file + "' contains invalid characters."); LogToConsoleTranslated("bot.chatLog.invalid_file", file);
UnloadBot(); UnloadBot();
} }
} }

View file

@ -156,53 +156,53 @@ namespace MinecraftClient.ChatBots
/// </summary> /// </summary>
public override void Initialize() public override void Initialize()
{ {
LogDebugToConsole("Initializing Mailer with settings:"); LogDebugToConsoleTranslated("bot.mailer.init");
LogDebugToConsole(" - Database File: " + Settings.Mailer_DatabaseFile); LogDebugToConsoleTranslated("bot.mailer.init.db" + Settings.Mailer_DatabaseFile);
LogDebugToConsole(" - Ignore List: " + Settings.Mailer_IgnoreListFile); LogDebugToConsoleTranslated("bot.mailer.init.ignore" + Settings.Mailer_IgnoreListFile);
LogDebugToConsole(" - Public Interactions: " + Settings.Mailer_PublicInteractions); LogDebugToConsoleTranslated("bot.mailer.init.public" + Settings.Mailer_PublicInteractions);
LogDebugToConsole(" - Max Mails per Player: " + Settings.Mailer_MaxMailsPerPlayer); LogDebugToConsoleTranslated("bot.mailer.init.max_mails" + Settings.Mailer_MaxMailsPerPlayer);
LogDebugToConsole(" - Max Database Size: " + Settings.Mailer_MaxDatabaseSize); LogDebugToConsoleTranslated("bot.mailer.init.db_size" + Settings.Mailer_MaxDatabaseSize);
LogDebugToConsole(" - Mail Retention: " + Settings.Mailer_MailRetentionDays + " days"); LogDebugToConsoleTranslated("bot.mailer.init.mail_retention" + Settings.Mailer_MailRetentionDays + " days");
if (Settings.Mailer_MaxDatabaseSize <= 0) if (Settings.Mailer_MaxDatabaseSize <= 0)
{ {
LogToConsole("Cannot enable Mailer: Max Database Size must be greater than zero. Please review the settings."); LogToConsoleTranslated("bot.mailer.init_fail.db_size");
UnloadBot(); UnloadBot();
return; return;
} }
if (Settings.Mailer_MaxMailsPerPlayer <= 0) if (Settings.Mailer_MaxMailsPerPlayer <= 0)
{ {
LogToConsole("Cannot enable Mailer: Max Mails per Player must be greater than zero. Please review the settings."); LogToConsoleTranslated("bot.mailer.init_fail.max_mails");
UnloadBot(); UnloadBot();
return; return;
} }
if (Settings.Mailer_MailRetentionDays <= 0) if (Settings.Mailer_MailRetentionDays <= 0)
{ {
LogToConsole("Cannot enable Mailer: Mail Retention must be greater than zero. Please review the settings."); LogToConsoleTranslated("bot.mailer.init_fail.mail_retention");
UnloadBot(); UnloadBot();
return; return;
} }
if (!File.Exists(Settings.Mailer_DatabaseFile)) if (!File.Exists(Settings.Mailer_DatabaseFile))
{ {
LogToConsole("Creating new database file: " + Path.GetFullPath(Settings.Mailer_DatabaseFile)); LogToConsoleTranslated("bot.mailer.create.db", Path.GetFullPath(Settings.Mailer_DatabaseFile));
new MailDatabase().SaveToFile(Settings.Mailer_DatabaseFile); new MailDatabase().SaveToFile(Settings.Mailer_DatabaseFile);
} }
if (!File.Exists(Settings.Mailer_IgnoreListFile)) if (!File.Exists(Settings.Mailer_IgnoreListFile))
{ {
LogToConsole("Creating new ignore list: " + Path.GetFullPath(Settings.Mailer_IgnoreListFile)); LogToConsoleTranslated("bot.mailer.create.ignore", Path.GetFullPath(Settings.Mailer_IgnoreListFile));
new IgnoreList().SaveToFile(Settings.Mailer_IgnoreListFile); new IgnoreList().SaveToFile(Settings.Mailer_IgnoreListFile);
} }
lock (readWriteLock) lock (readWriteLock)
{ {
LogDebugToConsole("Loading database file: " + Path.GetFullPath(Settings.Mailer_DatabaseFile)); LogDebugToConsoleTranslated("bot.mailer.load.db", Path.GetFullPath(Settings.Mailer_DatabaseFile));
mailDatabase = MailDatabase.FromFile(Settings.Mailer_DatabaseFile); mailDatabase = MailDatabase.FromFile(Settings.Mailer_DatabaseFile);
LogDebugToConsole("Loading ignore list: " + Path.GetFullPath(Settings.Mailer_IgnoreListFile)); LogDebugToConsoleTranslated("bot.mailer.load.ignore", Path.GetFullPath(Settings.Mailer_IgnoreListFile));
ignoreList = IgnoreList.FromFile(Settings.Mailer_IgnoreListFile); ignoreList = IgnoreList.FromFile(Settings.Mailer_IgnoreListFile);
} }
@ -210,7 +210,7 @@ namespace MinecraftClient.ChatBots
mailDbFileMonitor = new FileMonitor(Path.GetDirectoryName(Settings.Mailer_DatabaseFile), Path.GetFileName(Settings.Mailer_DatabaseFile), FileMonitorCallback); mailDbFileMonitor = new FileMonitor(Path.GetDirectoryName(Settings.Mailer_DatabaseFile), Path.GetFileName(Settings.Mailer_DatabaseFile), FileMonitorCallback);
ignoreListFileMonitor = new FileMonitor(Path.GetDirectoryName(Settings.Mailer_IgnoreListFile), Path.GetFileName(Settings.Mailer_IgnoreListFile), FileMonitorCallback); ignoreListFileMonitor = new FileMonitor(Path.GetDirectoryName(Settings.Mailer_IgnoreListFile), Path.GetFileName(Settings.Mailer_IgnoreListFile), FileMonitorCallback);
RegisterChatBotCommand("mailer", "Subcommands: getmails, addignored, getignored, removeignored", ProcessInternalCommand); RegisterChatBotCommand("mailer", Translations.Get("bot.mailer.cmd"), "mailer <getmails|addignored|getignored|removeignored>", ProcessInternalCommand);
} }
/// <summary> /// <summary>
@ -258,7 +258,7 @@ namespace MinecraftClient.ChatBots
if (message.Length <= maxMessageLength) if (message.Length <= maxMessageLength)
{ {
Mail mail = new Mail(username, recipient, message, anonymous, DateTime.Now); Mail mail = new Mail(username, recipient, message, anonymous, DateTime.Now);
LogToConsole("Saving message: " + mail.ToString()); LogToConsoleTranslated("bot.mailer.saving", mail.ToString());
lock (readWriteLock) lock (readWriteLock)
{ {
mailDatabase.Add(mail); mailDatabase.Add(mail);
@ -276,7 +276,7 @@ namespace MinecraftClient.ChatBots
break; break;
} }
} }
else LogDebugToConsole(username + " is ignored!"); else LogDebugToConsoleTranslated("bot.mailer.user_ignored", username);
} }
} }
@ -288,7 +288,7 @@ namespace MinecraftClient.ChatBots
DateTime dateNow = DateTime.Now; DateTime dateNow = DateTime.Now;
if (nextMailSend < dateNow) if (nextMailSend < dateNow)
{ {
LogDebugToConsole("Looking for mails to send @ " + DateTime.Now); LogDebugToConsoleTranslated("bot.mailer.process_mails", DateTime.Now);
// Process at most 3 mails at a time to avoid spamming. Other mails will be processed on next mail send // Process at most 3 mails at a time to avoid spamming. Other mails will be processed on next mail send
HashSet<string> onlinePlayersLowercase = new HashSet<string>(GetOnlinePlayers().Select(name => name.ToLower())); HashSet<string> onlinePlayersLowercase = new HashSet<string>(GetOnlinePlayers().Select(name => name.ToLower()));
@ -297,7 +297,7 @@ namespace MinecraftClient.ChatBots
string sender = mail.Anonymous ? "Anonymous" : mail.Sender; string sender = mail.Anonymous ? "Anonymous" : mail.Sender;
SendPrivateMessage(mail.Recipient, sender + " mailed: " + mail.Content); SendPrivateMessage(mail.Recipient, sender + " mailed: " + mail.Content);
mail.setDelivered(); mail.setDelivered();
LogDebugToConsole("Delivered: " + mail.ToString()); LogDebugToConsoleTranslated("bot.mailer.delivered", mail.ToString());
} }
lock (readWriteLock) lock (readWriteLock)
@ -335,11 +335,11 @@ namespace MinecraftClient.ChatBots
string commandName = args[0].ToLower(); string commandName = args[0].ToLower();
switch (commandName) switch (commandName)
{ {
case "getmails": case "getmails": // Sorry, I (ReinforceZwei) replaced "=" to "-" because it would affect the parsing of translation file (key=value)
return "== Mails in database ==\n" + string.Join("\n", mailDatabase); return Translations.Get("bot.mailer.cmd.getmails", string.Join("\n", mailDatabase));
case "getignored": case "getignored":
return "== Ignore list ==\n" + string.Join("\n", ignoreList); return Translations.Get("bot.mailer.cmd.getignored", string.Join("\n", ignoreList));
case "addignored": case "addignored":
case "removeignored": case "removeignored":
@ -356,7 +356,7 @@ namespace MinecraftClient.ChatBots
ignoreList.SaveToFile(Settings.Mailer_IgnoreListFile); ignoreList.SaveToFile(Settings.Mailer_IgnoreListFile);
} }
} }
return "Added " + args[1] + " to the ignore list!"; return Translations.Get("bot.mailer.cmd.ignore.added", args[1]);
} }
else else
{ {
@ -368,13 +368,13 @@ namespace MinecraftClient.ChatBots
ignoreList.SaveToFile(Settings.Mailer_IgnoreListFile); ignoreList.SaveToFile(Settings.Mailer_IgnoreListFile);
} }
} }
return "Removed " + args[1] + " from the ignore list!"; return Translations.Get("bot.mailer.cmd.ignore.removed", args[1]);
} }
} }
else return "Missing or invalid name. Usage: " + commandName + " <username>"; else return Translations.Get("bot.mailer.cmd.ignore.invalid", commandName);
} }
} }
return "See usage: /help mailer"; return Translations.Get("bot.mailer.cmd.help") + ": /help mailer";
} }
} }
} }

View file

@ -29,7 +29,7 @@ namespace MinecraftClient.ChatBots
replay.MetaData.serverName = GetServerHost() + GetServerPort(); replay.MetaData.serverName = GetServerHost() + GetServerPort();
backupCounter = backupInterval; backupCounter = backupInterval;
RegisterChatBotCommand("replay", "replay command", Command); RegisterChatBotCommand("replay", Translations.Get("bot.replayCapture.cmd"), "replay <save|stop>", Command);
} }
public override void OnNetworkPacket(int packetID, List<byte> packetData, bool isLogin, bool isInbound) public override void OnNetworkPacket(int packetID, List<byte> packetData, bool isLogin, bool isInbound)
@ -69,18 +69,18 @@ namespace MinecraftClient.ChatBots
case "save": case "save":
{ {
replay.CreateBackupReplay(@"replay_recordings\" + replay.GetReplayDefaultName()); replay.CreateBackupReplay(@"replay_recordings\" + replay.GetReplayDefaultName());
return "Replay file created."; return Translations.Get("bot.replayCapture.created");
} }
case "stop": case "stop":
{ {
replay.OnShutDown(); replay.OnShutDown();
return "Record stopped."; return Translations.Get("bot.replayCapture.stopped");
} }
} }
} }
return "Available commands: save, stop"; return Translations.Get("general.available_cmd", "save, stop");
} }
else return "Record was stopped. Restart the program to start another record."; else return Translations.Get("bot.replayCapture.restart");
} }
catch (Exception e) catch (Exception e)
{ {

View file

@ -121,7 +121,7 @@ namespace MinecraftClient.ChatBots
caller = type.Name; caller = type.Name;
} }
catch { } catch { }
ConsoleIO.WriteLineFormatted(String.Format("§8[MCC] [{0}] Cannot find script file: {1}", caller, filename)); ConsoleIO.WriteLineFormatted(Translations.Get("bot.script.not_found", caller, filename));
} }
return false; return false;
@ -137,14 +137,14 @@ namespace MinecraftClient.ChatBots
thread = null; thread = null;
if (!String.IsNullOrEmpty(owner)) if (!String.IsNullOrEmpty(owner))
SendPrivateMessage(owner, "Script '" + file + "' loaded."); SendPrivateMessage(owner, Translations.Get("bot.script.pm.loaded", file));
} }
else else
{ {
LogToConsole("File not found: '" + System.IO.Path.GetFullPath(file) + "'"); LogToConsoleTranslated("bot.script.file_not_found", System.IO.Path.GetFullPath(file));
if (!String.IsNullOrEmpty(owner)) if (!String.IsNullOrEmpty(owner))
SendPrivateMessage(owner, "File not found: '" + file + "'"); SendPrivateMessage(owner, Translations.Get("bot.script.file_not_found", file));
UnloadBot(); //No need to keep the bot active UnloadBot(); //No need to keep the bot active
} }
@ -166,7 +166,7 @@ namespace MinecraftClient.ChatBots
} }
catch (CSharpException e) catch (CSharpException e)
{ {
string errorMessage = "Script '" + file + "' failed to run (" + e.ExceptionType + ")."; string errorMessage = Translations.Get("bot.script.fail", file, e.ExceptionType);
LogToConsole(errorMessage); LogToConsole(errorMessage);
if (owner != null) if (owner != null)
SendPrivateMessage(owner, errorMessage); SendPrivateMessage(owner, errorMessage);

View file

@ -44,8 +44,7 @@ namespace MinecraftClient.ChatBots
//Load the given file from the startup parameters //Load the given file from the startup parameters
if (System.IO.File.Exists(tasksfile)) if (System.IO.File.Exists(tasksfile))
{ {
if (Settings.DebugMessages) LogDebugToConsoleTranslated("bot.scriptScheduler.loading", System.IO.Path.GetFullPath(tasksfile));
LogToConsole("Loading tasks from '" + System.IO.Path.GetFullPath(tasksfile) + "'");
TaskDesc current_task = null; TaskDesc current_task = null;
String[] lines = System.IO.File.ReadAllLines(tasksfile, Encoding.UTF8); String[] lines = System.IO.File.ReadAllLines(tasksfile, Encoding.UTF8);
foreach (string lineRAW in lines) foreach (string lineRAW in lines)
@ -88,7 +87,7 @@ namespace MinecraftClient.ChatBots
} }
else else
{ {
LogToConsole("File not found: '" + System.IO.Path.GetFullPath(tasksfile) + "'"); LogToConsoleTranslated("bot.scriptScheduler.not_found", System.IO.Path.GetFullPath(tasksfile));
UnloadBot(); //No need to keep the bot active UnloadBot(); //No need to keep the bot active
} }
} }
@ -107,19 +106,19 @@ namespace MinecraftClient.ChatBots
|| (current_task.triggerOnTime && current_task.triggerOnTime_Times.Count > 0) || (current_task.triggerOnTime && current_task.triggerOnTime_Times.Count > 0)
|| (current_task.triggerOnInterval && current_task.triggerOnInterval_Interval > 0)) || (current_task.triggerOnInterval && current_task.triggerOnInterval_Interval > 0))
{ {
if (Settings.DebugMessages)
LogToConsole("Loaded task:\n" + Task2String(current_task)); LogDebugToConsoleTranslated("bot.scriptScheduler.loaded_task", Task2String(current_task));
current_task.triggerOnInterval_Interval_Countdown = current_task.triggerOnInterval_Interval; //Init countdown for interval current_task.triggerOnInterval_Interval_Countdown = current_task.triggerOnInterval_Interval; //Init countdown for interval
tasks.Add(current_task); tasks.Add(current_task);
} }
else if (Settings.DebugMessages) else
{ {
LogToConsole("This task will never trigger:\n" + Task2String(current_task)); LogDebugToConsoleTranslated("bot.scriptScheduler.no_trigger", Task2String(current_task));
} }
} }
else if (Settings.DebugMessages) else
{ {
LogToConsole("No action for task:\n" + Task2String(current_task)); LogDebugToConsoleTranslated("bot.scriptScheduler.no_action", Task2String(current_task));
} }
} }
} }
@ -145,8 +144,7 @@ namespace MinecraftClient.ChatBots
if (!task.triggerOnTime_alreadyTriggered) if (!task.triggerOnTime_alreadyTriggered)
{ {
task.triggerOnTime_alreadyTriggered = true; task.triggerOnTime_alreadyTriggered = true;
if (Settings.DebugMessages) LogDebugToConsoleTranslated("bot.scriptScheduler.running_time", task.action);
LogToConsole("Time / Running action: " + task.action);
PerformInternalCommand(task.action); PerformInternalCommand(task.action);
} }
} }
@ -161,8 +159,7 @@ namespace MinecraftClient.ChatBots
if (task.triggerOnInterval_Interval_Countdown == 0) if (task.triggerOnInterval_Interval_Countdown == 0)
{ {
task.triggerOnInterval_Interval_Countdown = task.triggerOnInterval_Interval; task.triggerOnInterval_Interval_Countdown = task.triggerOnInterval_Interval;
if (Settings.DebugMessages) LogDebugToConsoleTranslated("bot.scriptScheduler.running_inverval", task.action);
LogToConsole("Interval / Running action: " + task.action);
PerformInternalCommand(task.action); PerformInternalCommand(task.action);
} }
else task.triggerOnInterval_Interval_Countdown--; else task.triggerOnInterval_Interval_Countdown--;
@ -175,8 +172,7 @@ namespace MinecraftClient.ChatBots
{ {
if (task.triggerOnLogin || (firstlogin_done == false && task.triggerOnFirstLogin)) if (task.triggerOnLogin || (firstlogin_done == false && task.triggerOnFirstLogin))
{ {
if (Settings.DebugMessages) LogDebugToConsoleTranslated("bot.scriptScheduler.running_login", task.action);
LogToConsole("Login / Running action: " + task.action);
PerformInternalCommand(task.action); PerformInternalCommand(task.action);
} }
} }
@ -196,9 +192,8 @@ namespace MinecraftClient.ChatBots
private static string Task2String(TaskDesc task) private static string Task2String(TaskDesc task)
{ {
return String.Format( return Translations.Get(
" triggeronfirstlogin = {0}\n triggeronlogin = {1}\n triggerontime = {2}\n " "bot.scriptScheduler.task",
+ "triggeroninterval = {3}\n timevalue = {4}\n timeinterval = {5}\n action = {6}",
task.triggerOnFirstLogin, task.triggerOnFirstLogin,
task.triggerOnLogin, task.triggerOnLogin,
task.triggerOnTime, task.triggerOnTime,

View file

@ -19,11 +19,11 @@ namespace MinecraftClient.ChatBots
if (IsPrivateMessage(text, ref message, ref username)) if (IsPrivateMessage(text, ref message, ref username))
{ {
LogToConsole("Bot: " + username + " told me : " + message); LogToConsoleTranslated("bot.testBot.told", username, message);
} }
else if (IsChatMessage(text, ref message, ref username)) else if (IsChatMessage(text, ref message, ref username))
{ {
LogToConsole("Bot: " + username + " said : " + message); LogToConsoleTranslated("bot.testBot.said", username, message);
} }
} }
} }

View file

@ -16,12 +16,27 @@ namespace MinecraftClient
/// <summary> /// <summary>
/// The command name /// The command name
/// </summary> /// </summary>
public abstract string CMDName { get; } public abstract string CmdName { get; }
/// <summary> /// <summary>
/// Usage message, eg: 'name [args]: do something' /// Command description with translation support. Please add your message in Translations.cs file and return mapping key in this property
/// </summary> /// </summary>
public abstract string CMDDesc { get; } public abstract string CmdDesc { get; }
/// <summary>
/// Get the translated version of command description.
/// </summary>
/// <returns>Translated command description</returns>
public string GetCmdDescTranslated()
{
string s = string.IsNullOrEmpty(CmdUsage) || string.IsNullOrEmpty(CmdDesc) ? "" : ": "; // If either one is empty, no colon :
return CmdUsage + s + Translations.TryGet(CmdDesc);
}
/// <summary>
/// Usage message, eg: 'name [args]'
/// </summary>
public abstract string CmdUsage { get; }
/// <summary> /// <summary>
/// Perform the command /// Perform the command

View file

@ -7,8 +7,9 @@ namespace MinecraftClient.Commands
{ {
public class Animation : Command public class Animation : Command
{ {
public override string CMDName { get { return "animation"; } } public override string CmdName { get { return "animation"; } }
public override string CMDDesc { get { return "animation <mainhand|offhand>"; } } public override string CmdUsage { get { return "animation <mainhand|offhand>"; } }
public override string CmdDesc { get { return "cmd.animation.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
@ -20,24 +21,24 @@ namespace MinecraftClient.Commands
if (args[0] == "mainhand" || args[0] == "0") if (args[0] == "mainhand" || args[0] == "0")
{ {
handler.DoAnimation(0); handler.DoAnimation(0);
return "Done"; return Translations.Get("general.done");
} }
else if (args[0] == "offhand" || args[0] == "1") else if (args[0] == "offhand" || args[0] == "1")
{ {
handler.DoAnimation(1); handler.DoAnimation(1);
return "Done"; return Translations.Get("general.done");
} }
else else
{ {
return CMDDesc; return GetCmdDescTranslated();
} }
} }
else else
{ {
return CMDDesc; return GetCmdDescTranslated();
} }
} }
else return CMDDesc; else return GetCmdDescTranslated();
} }
} }
} }

View file

@ -7,13 +7,14 @@ namespace MinecraftClient.Commands
{ {
class ChangeSlot : Command class ChangeSlot : Command
{ {
public override string CMDName { get { return "changeslot"; } } public override string CmdName { get { return "changeslot"; } }
public override string CMDDesc { get { return "changeslot <1-9>: Change hotbar"; } } public override string CmdUsage { get { return "changeslot <1-9>"; } }
public override string CmdDesc { get { return "cmd.changeSlot.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
if (!handler.GetInventoryEnabled()) if (!handler.GetInventoryEnabled())
return "Please enable InventoryHandling in the config file first."; return Translations.Get("extra.inventory_required");
if (hasArg(command)) if (hasArg(command))
{ {
@ -24,21 +25,21 @@ namespace MinecraftClient.Commands
} }
catch (FormatException) catch (FormatException)
{ {
return "Could not change slot: Not a Number"; return Translations.Get("cmd.changeSlot.nan");
} }
if (slot >= 1 && slot <= 9) if (slot >= 1 && slot <= 9)
{ {
if (handler.ChangeSlot(slot-=1)) if (handler.ChangeSlot(slot-=1))
{ {
return "Changed to slot " + (slot+=1); return Translations.Get("cmd.changeSlot.changed", (slot+=1));
} }
else else
{ {
return "Could not change slot"; return Translations.Get("cmd.changeSlot.fail");
} }
} }
} }
return CMDDesc; return GetCmdDescTranslated();
} }
} }
} }

View file

@ -7,8 +7,9 @@ namespace MinecraftClient.Commands
{ {
public class Connect : Command public class Connect : Command
{ {
public override string CMDName { get { return "connect"; } } public override string CmdName { get { return "connect"; } }
public override string CMDDesc { get { return "connect <server> [account]: connect to the specified server."; } } public override string CmdUsage { get { return "connect <server> [account]"; } }
public override string CmdDesc { get { return "cmd.connect.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
@ -19,7 +20,7 @@ namespace MinecraftClient.Commands
{ {
if (!Settings.SetAccount(args[1])) if (!Settings.SetAccount(args[1]))
{ {
return "Unknown account '" + args[1] + "'."; return Translations.Get("cmd.connect.unknown", args[1]);
} }
} }
@ -28,9 +29,9 @@ namespace MinecraftClient.Commands
Program.Restart(); Program.Restart();
return ""; return "";
} }
else return "Invalid server IP '" + args[0] + "'."; else return Translations.Get("cmd.connect.invalid_ip", args[0]);
} }
else return CMDDesc; else return GetCmdDescTranslated();
} }
} }
} }

View file

@ -7,8 +7,9 @@ namespace MinecraftClient.Commands
{ {
public class Debug : Command public class Debug : Command
{ {
public override string CMDName { get { return "debug"; } } public override string CmdName { get { return "debug"; } }
public override string CMDDesc { get { return "debug [on|off]: toggle debug messages."; } } public override string CmdUsage { get { return "debug [on|off]"; } }
public override string CmdDesc { get { return "cmd.debug.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
@ -17,7 +18,7 @@ namespace MinecraftClient.Commands
Settings.DebugMessages = (getArg(command).ToLower() == "on"); Settings.DebugMessages = (getArg(command).ToLower() == "on");
} }
else Settings.DebugMessages = !Settings.DebugMessages; else Settings.DebugMessages = !Settings.DebugMessages;
return "Debug messages are now " + (Settings.DebugMessages ? "ON" : "OFF"); return Translations.Get(Settings.DebugMessages ? "cmd.debug.state_on" : "cmd.debug.state_off");
} }
} }
} }

View file

@ -8,13 +8,14 @@ namespace MinecraftClient.Commands
{ {
public class Dig : Command public class Dig : Command
{ {
public override string CMDName { get { return "dig"; } } public override string CmdName { get { return "dig"; } }
public override string CMDDesc { get { return "dig <x> <y> <z>: attempt to break a block"; } } public override string CmdUsage { get { return "dig <x> <y> <z>"; } }
public override string CmdDesc { get { return "cmd.dig.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
if (!handler.GetTerrainEnabled()) if (!handler.GetTerrainEnabled())
return "Please enable Terrain and Movements to use this command."; return Translations.Get("extra.terrainandmovement_required");
if (hasArg(command)) if (hasArg(command))
{ {
@ -28,18 +29,18 @@ namespace MinecraftClient.Commands
int z = int.Parse(args[2]); int z = int.Parse(args[2]);
Location blockToBreak = new Location(x, y, z); Location blockToBreak = new Location(x, y, z);
if (blockToBreak.DistanceSquared(handler.GetCurrentLocation().EyesLocation()) > 25) if (blockToBreak.DistanceSquared(handler.GetCurrentLocation().EyesLocation()) > 25)
return "You are too far away from this block."; return Translations.Get("cmd.dig.too_far");
if (handler.GetWorld().GetBlock(blockToBreak).Type == Material.Air) if (handler.GetWorld().GetBlock(blockToBreak).Type == Material.Air)
return "No block at this location (Air)"; return Translations.Get("cmd.dig.no_block");
if (handler.DigBlock(blockToBreak)) if (handler.DigBlock(blockToBreak))
return String.Format("Attempting to dig block at {0} {1} {2}", x, y, z); return Translations.Get("cmd.dig.dig", x, y, z);
else return "Failed to start digging block."; else return "cmd.dig.fail";
} }
catch (FormatException) { return CMDDesc; } catch (FormatException) { return GetCmdDescTranslated(); }
} }
else return CMDDesc; else return GetCmdDescTranslated();
} }
else return CMDDesc; else return GetCmdDescTranslated();
} }
} }
} }

View file

@ -8,8 +8,9 @@ namespace MinecraftClient.Commands
{ {
class Entitycmd : Command class Entitycmd : Command
{ {
public override string CMDName { get { return "entity"; } } public override string CmdName { get { return "entity"; } }
public override string CMDDesc { get { return "entity <id|entitytype> <attack|use>"; } } public override string CmdUsage { get { return "entity <id|entitytype> <attack|use>"; } }
public override string CmdDesc { get { return ""; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
@ -33,10 +34,10 @@ namespace MinecraftClient.Commands
{ {
case "attack": case "attack":
handler.InteractEntity(entityID, 1); handler.InteractEntity(entityID, 1);
return "Entity attacked"; return Translations.Get("cmd.entityCmd.attacked");
case "use": case "use":
handler.InteractEntity(entityID, 0); handler.InteractEntity(entityID, 0);
return "Entity used"; return Translations.Get("cmd.entityCmd.used");
default: default:
Entity entity = handler.GetEntities()[entityID]; Entity entity = handler.GetEntities()[entityID];
int id = entity.ID; int id = entity.ID;
@ -56,52 +57,52 @@ namespace MinecraftClient.Commands
color = "§e"; // Yellow color = "§e"; // Yellow
string location = String.Format("X:{0}, Y:{1}, Z:{2}", Math.Round(entity.Location.X, 2), Math.Round(entity.Location.Y, 2), Math.Round(entity.Location.Y, 2)); string location = String.Format("X:{0}, Y:{1}, Z:{2}", Math.Round(entity.Location.X, 2), Math.Round(entity.Location.Y, 2), Math.Round(entity.Location.Y, 2));
string done = String.Format("Entity: {0}\n [MCC] Type: {1}", id, type); string done = Translations.Replace("([cmd.entityCmd.entity]): {0}\n [MCC] Type: {1}", id, type);
if (!String.IsNullOrEmpty(nickname)) if (!String.IsNullOrEmpty(nickname))
done += String.Format("\n [MCC] Nickname: {0}", nickname); done += Translations.Replace("\n [MCC] ([cmd.entityCmd.nickname]): {0}", nickname);
else if (!String.IsNullOrEmpty(customname)) else if (!String.IsNullOrEmpty(customname))
done += String.Format("\n [MCC] CustomName: {0}§8", customname.Replace("&", "§")); done += Translations.Replace("\n [MCC] ([cmd.entityCmd.customname]): {0}§8", customname.Replace("&", "§"));
if (type == EntityType.Player) if (type == EntityType.Player)
done += String.Format("\n [MCC] Latency: {0}", latency); done += Translations.Replace("\n [MCC] ([cmd.entityCmd.latency]): {0}", latency);
else if (type == EntityType.Item || type == EntityType.ItemFrame || type == Mapping.EntityType.EyeOfEnder || type == Mapping.EntityType.Egg || type == Mapping.EntityType.EnderPearl || type == Mapping.EntityType.Potion || type == Mapping.EntityType.Fireball || type == Mapping.EntityType.FireworkRocket) else if (type == EntityType.Item || type == EntityType.ItemFrame || type == Mapping.EntityType.EyeOfEnder || type == Mapping.EntityType.Egg || type == Mapping.EntityType.EnderPearl || type == Mapping.EntityType.Potion || type == Mapping.EntityType.Fireball || type == Mapping.EntityType.FireworkRocket)
{ {
string displayName = item.DisplayName; string displayName = item.DisplayName;
if (String.IsNullOrEmpty(displayName)) if (String.IsNullOrEmpty(displayName))
done += String.Format("\n [MCC] Item: {0} x{1}", item.Type, item.Count); done += Translations.Replace("\n [MCC] ([cmd.entityCmd.item]): {0} x{1}", item.Type, item.Count);
else else
done += String.Format("\n [MCC] Item: {0} x{1} - {2}§8", item.Type, item.Count, displayName); done += Translations.Replace("\n [MCC] ([cmd.entityCmd.item]): {0} x{1} - {2}§8", item.Type, item.Count, displayName);
} }
if (entity.Equipment.Count >= 1 && entity.Equipment != null) if (entity.Equipment.Count >= 1 && entity.Equipment != null)
{ {
done += String.Format("\n [MCC] Equipment:"); done += Translations.Replace("\n [MCC] ([cmd.entityCmd.equipment]):");
if (entity.Equipment.ContainsKey(0) && entity.Equipment[0] != null) if (entity.Equipment.ContainsKey(0) && entity.Equipment[0] != null)
done += String.Format("\n [MCC] MainHand: {0} x{1}", entity.Equipment[0].Type, entity.Equipment[0].Count); done += Translations.Replace("\n [MCC] ([cmd.entityCmd.mainhand]): {0} x{1}", entity.Equipment[0].Type, entity.Equipment[0].Count);
if (entity.Equipment.ContainsKey(1) && entity.Equipment[1] != null) if (entity.Equipment.ContainsKey(1) && entity.Equipment[1] != null)
done += String.Format("\n [MCC] OffHand: {0} x{1}", entity.Equipment[1].Type, entity.Equipment[1].Count); done += Translations.Replace("\n [MCC] ([cmd.entityCmd.offhand]): {0} x{1}", entity.Equipment[1].Type, entity.Equipment[1].Count);
if (entity.Equipment.ContainsKey(5) && entity.Equipment[5] != null) if (entity.Equipment.ContainsKey(5) && entity.Equipment[5] != null)
done += String.Format("\n [MCC] Helmet: {0} x{1}", entity.Equipment[5].Type, entity.Equipment[5].Count); done += Translations.Replace("\n [MCC] ([cmd.entityCmd.helmet]): {0} x{1}", entity.Equipment[5].Type, entity.Equipment[5].Count);
if (entity.Equipment.ContainsKey(4) && entity.Equipment[4] != null) if (entity.Equipment.ContainsKey(4) && entity.Equipment[4] != null)
done += String.Format("\n [MCC] Chestplate: {0} x{1}", entity.Equipment[4].Type, entity.Equipment[4].Count); done += Translations.Replace("\n [MCC] ([cmd.entityCmd.chestplate]): {0} x{1}", entity.Equipment[4].Type, entity.Equipment[4].Count);
if (entity.Equipment.ContainsKey(3) && entity.Equipment[3] != null) if (entity.Equipment.ContainsKey(3) && entity.Equipment[3] != null)
done += String.Format("\n [MCC] Leggings: {0} x{1}", entity.Equipment[3].Type, entity.Equipment[3].Count); done += Translations.Replace("\n [MCC] ([cmd.entityCmd.leggings]): {0} x{1}", entity.Equipment[3].Type, entity.Equipment[3].Count);
if (entity.Equipment.ContainsKey(2) && entity.Equipment[2] != null) if (entity.Equipment.ContainsKey(2) && entity.Equipment[2] != null)
done += String.Format("\n [MCC] Boots: {0} x{1}", entity.Equipment[2].Type, entity.Equipment[2].Count); done += Translations.Replace("\n [MCC] ([cmd.entityCmd.boots]): {0} x{1}", entity.Equipment[2].Type, entity.Equipment[2].Count);
} }
done += String.Format("\n [MCC] Pose: {0}", pose); done += Translations.Replace("\n [MCC] ([cmd.entityCmd.pose]): {0}", pose);
done += String.Format("\n [MCC] Health: {0}", color + health + "§8"); done += Translations.Replace("\n [MCC] ([cmd.entityCmd.health]): {0}", color + health + "§8");
done += String.Format("\n [MCC] Distance: {0}", distance); done += Translations.Replace("\n [MCC] ([cmd.entityCmd.distance]): {0}", distance);
done += String.Format("\n [MCC] Location: {0}", location); done += Translations.Replace("\n [MCC] ([cmd.entityCmd.location]): {0}", location);
return done; return done;
} }
} }
else return "Entity not found"; else return Translations.Get("cmd.entityCmd.not_found");
} }
else else
{ {
EntityType interacttype = EntityType.Player; EntityType interacttype = EntityType.Player;
Enum.TryParse(args[0], out interacttype); Enum.TryParse(args[0], out interacttype);
string actionst = "Entity attacked"; string actionst = "cmd.entityCmd.attacked";
int actioncount = 0; int actioncount = 0;
foreach (var entity2 in handler.GetEntities()) foreach (var entity2 in handler.GetEntities())
{ {
@ -113,28 +114,28 @@ namespace MinecraftClient.Commands
if (action == "attack") if (action == "attack")
{ {
handler.InteractEntity(entity2.Key, 1); handler.InteractEntity(entity2.Key, 1);
actionst = "Entity attacked"; actionst = "cmd.entityCmd.attacked";
actioncount++; actioncount++;
} }
else if (action == "use") else if (action == "use")
{ {
handler.InteractEntity(entity2.Key, 0); handler.InteractEntity(entity2.Key, 0);
actionst = "Entity used"; actionst = "cmd.entityCmd.used";
actioncount++; actioncount++;
} }
else return CMDDesc; else return GetCmdDescTranslated();
} }
} }
return actioncount + " " + actionst; return actioncount + " " + Translations.Get(actionst);
} }
} }
catch (FormatException) { return CMDDesc; } catch (FormatException) { return GetCmdDescTranslated(); }
} }
else else
{ {
Dictionary<int, Mapping.Entity> entities = handler.GetEntities(); Dictionary<int, Entity> entities = handler.GetEntities();
List<string> response = new List<string>(); List<string> response = new List<string>();
response.Add("Entities:"); response.Add(Translations.Get("cmd.entityCmd.entities"));
foreach (var entity2 in entities) foreach (var entity2 in entities)
{ {
int id = entity2.Key; int id = entity2.Key;
@ -147,20 +148,20 @@ namespace MinecraftClient.Commands
Item item = entity2.Value.Item; Item item = entity2.Value.Item;
string location = String.Format("X:{0}, Y:{1}, Z:{2}", Math.Round(entity2.Value.Location.X, 2), Math.Round(entity2.Value.Location.Y, 2), Math.Round(entity2.Value.Location.Y, 2)); string location = String.Format("X:{0}, Y:{1}, Z:{2}", Math.Round(entity2.Value.Location.X, 2), Math.Round(entity2.Value.Location.Y, 2), Math.Round(entity2.Value.Location.Y, 2));
if (type == EntityType.Item || type == EntityType.ItemFrame || type == Mapping.EntityType.EyeOfEnder || type == Mapping.EntityType.Egg || type == Mapping.EntityType.EnderPearl || type == Mapping.EntityType.Potion || type == Mapping.EntityType.Fireball || type == Mapping.EntityType.FireworkRocket) if (type == EntityType.Item || type == EntityType.ItemFrame || type == EntityType.EyeOfEnder || type == EntityType.Egg || type == EntityType.EnderPearl || type == EntityType.Potion || type == EntityType.Fireball || type == EntityType.FireworkRocket)
response.Add(String.Format(" #{0}: Type: {1}, Item: {2}, Location: {3}", id, type, item.Type, location)); response.Add(Translations.Replace(" #{0}: ([cmd.entityCmd.type]): {1}, ([cmd.entityCmd.item]): {2}, ([cmd.entityCmd.location]): {3}", id, type, item.Type, location));
else if (type == Mapping.EntityType.Player && !String.IsNullOrEmpty(nickname)) else if (type == EntityType.Player && !String.IsNullOrEmpty(nickname))
response.Add(String.Format(" #{0}: Type: {1}, Nickname: §8{2}§8, Latency: {3}, Health: {4}, Pose: {5}, Location: {6}", id, type, nickname, latency, health, pose, location)); response.Add(Translations.Replace(" #{0}: ([cmd.entityCmd.type]): {1}, ([cmd.entityCmd.nickname]): §8{2}§8, ([cmd.entityCmd.latency]): {3}, ([cmd.entityCmd.health]): {4}, ([cmd.entityCmd.pose]): {5}, ([cmd.entityCmd.location]): {6}", id, type, nickname, latency, health, pose, location));
else if (type == Mapping.EntityType.Player && !String.IsNullOrEmpty(customname)) else if (type == EntityType.Player && !String.IsNullOrEmpty(customname))
response.Add(String.Format(" #{0}: Type: {1}, CustomName: §8{2}§8, Latency: {3}, Health: {4}, Pose: {5}, Location: {6}", id, type, customname.Replace("&", "§"), latency, health, pose, location)); response.Add(Translations.Replace(" #{0}: ([cmd.entityCmd.type]): {1}, ([cmd.entityCmd.customname]): §8{2}§8, ([cmd.entityCmd.latency]): {3}, ([cmd.entityCmd.health]): {4}, ([cmd.entityCmd.pose]): {5}, ([cmd.entityCmd.location]): {6}", id, type, customname.Replace("&", "§"), latency, health, pose, location));
else else
response.Add(String.Format(" #{0}: Type: {1}, Health: {2}, Location: {3}", id, type, health, location)); response.Add(Translations.Replace(" #{0}: ([cmd.entityCmd.type]): {1}, ([cmd.entityCmd.health]): {2}, ([cmd.entityCmd.location]): {3}", id, type, health, location));
} }
response.Add(CMDDesc); response.Add(GetCmdDescTranslated());
return String.Join("\n", response); return String.Join("\n", response);
} }
} }
else return "Please enable entityhandling in config to use this command."; else return Translations.Get("extra.entity_required");
} }
} }
} }

View file

@ -7,8 +7,9 @@ namespace MinecraftClient.Commands
{ {
public class Exit : Command public class Exit : Command
{ {
public override string CMDName { get { return "exit"; } } public override string CmdName { get { return "exit"; } }
public override string CMDDesc { get { return "exit: disconnect from the server."; } } public override string CmdUsage { get { return "exit"; } }
public override string CmdDesc { get { return "cmd.exit.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {

View file

@ -7,12 +7,13 @@ namespace MinecraftClient.Commands
{ {
class Health : Command class Health : Command
{ {
public override string CMDName { get { return "health"; } } public override string CmdName { get { return "health"; } }
public override string CMDDesc { get { return "health: Display Health and Food saturation."; } } public override string CmdUsage { get { return "health"; } }
public override string CmdDesc { get { return "cmd.health.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
return "Health: " + handler.GetHealth() + ", Saturation: " + handler.GetSaturation() + ", Level: " + handler.GetLevel() + ", TotalExperience: " + handler.GetTotalExperience(); return Translations.Get("cmd.health.response", handler.GetHealth(), handler.GetSaturation(), handler.GetLevel(), handler.GetTotalExperience());
} }
} }
} }

View file

@ -7,8 +7,9 @@ namespace MinecraftClient.Commands
{ {
class Inventory : Command class Inventory : Command
{ {
public override string CMDName { get { return "inventory"; } } public override string CmdName { get { return "inventory"; } }
public override string CMDDesc { get { return GetCommandDesc(); } } public override string CmdUsage { get { return GetBasicUsage(); } }
public override string CmdDesc { get { return "cmd.inventory.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
@ -32,17 +33,17 @@ namespace MinecraftClient.Commands
{ {
int count = int.Parse(args[3]); int count = int.Parse(args[3]);
if (handler.DoCreativeGive(slot, itemType, count, null)) if (handler.DoCreativeGive(slot, itemType, count, null))
return "Requested " + itemType + " x" + count + " in slot #" + slot; return Translations.Get("cmd.inventory.creative_done", itemType, count, slot);
else return "Failed to request Creative Give"; else return Translations.Get("cmd.inventory.creative_fail");
} }
else return "You need Gamemode Creative"; else return Translations.Get("cmd.inventory.need_creative");
} }
else else
{ {
return CMDDesc; return GetCmdDescTranslated();
} }
} }
else return CMDDesc; else return GetCmdDescTranslated();
} }
else if (args[0].ToLower().StartsWith("p")) else if (args[0].ToLower().StartsWith("p"))
{ {
@ -55,7 +56,7 @@ namespace MinecraftClient.Commands
availableIds.Remove(0); // remove player inventory ID from list availableIds.Remove(0); // remove player inventory ID from list
if (availableIds.Count == 1) if (availableIds.Count == 1)
inventoryId = availableIds[0]; // one container, use it inventoryId = availableIds[0]; // one container, use it
else return "Cannot find container, please retry with explicit ID"; else return Translations.Get("cmd.inventory.container_not_found");
} }
else if (args[0].ToLower() == "help") else if (args[0].ToLower() == "help")
{ {
@ -73,65 +74,65 @@ namespace MinecraftClient.Commands
{ {
case "close": case "close":
if (handler.CloseInventory(inventoryId)) if (handler.CloseInventory(inventoryId))
return "Closing Inventoy #" + inventoryId; return Translations.Get("cmd.inventory.close", inventoryId);
else return "Failed to close Inventory #" + inventoryId; else return Translations.Get("cmd.inventory.close_fail", inventoryId);
case "list": case "list":
Container inventory = handler.GetInventory(inventoryId); Container inventory = handler.GetInventory(inventoryId);
if(inventory==null) if(inventory==null)
return "Inventory #" + inventoryId + " do not exist"; return Translations.Get("cmd.inventory.not_exist", inventoryId);
List<string> response = new List<string>(); List<string> response = new List<string>();
response.Add("Inventory #" + inventoryId + " - " + inventory.Title + "§8"); response.Add(Translations.Get("cmd.inventory.inventory") + " #" + inventoryId + " - " + inventory.Title + "§8");
foreach (KeyValuePair<int, Item> item in inventory.Items) foreach (KeyValuePair<int, Item> item in inventory.Items)
{ {
string displayName = item.Value.DisplayName; string displayName = item.Value.DisplayName;
if (String.IsNullOrEmpty(displayName)) if (String.IsNullOrEmpty(displayName))
{ {
if (item.Value.Damage != 0) if (item.Value.Damage != 0)
response.Add(String.Format(" #{0}: {1} x{2} | Damage: {3}", item.Key, item.Value.Type, item.Value.Count, item.Value.Damage)); response.Add(String.Format(" #{0}: {1} x{2} | {3}: {4}", item.Key, item.Value.Type, item.Value.Count, Translations.Get("cmd.inventory.damage"), item.Value.Damage));
else else
response.Add(String.Format(" #{0}: {1} x{2}", item.Key, item.Value.Type, item.Value.Count)); response.Add(String.Format(" #{0}: {1} x{2}", item.Key, item.Value.Type, item.Value.Count));
} }
else else
{ {
if (item.Value.Damage != 0) if (item.Value.Damage != 0)
response.Add(String.Format(" #{0}: {1} x{2} - {3}§8 | Damage: {4}", item.Key, item.Value.Type, item.Value.Count, displayName, item.Value.Damage)); response.Add(String.Format(" #{0}: {1} x{2} - {3}§8 | {4}: {5}", item.Key, item.Value.Type, item.Value.Count, displayName, Translations.Get("cmd.inventory.damage"), item.Value.Damage));
else else
response.Add(String.Format(" #{0}: {1} x{2} - {3}§8", item.Key, item.Value.Type, item.Value.Count, displayName)); response.Add(String.Format(" #{0}: {1} x{2} - {3}§8", item.Key, item.Value.Type, item.Value.Count, displayName));
} }
} }
if (inventoryId == 0) response.Add("Your selected hotbar is " + (handler.GetCurrentSlot() + 1)); if (inventoryId == 0) response.Add(Translations.Get("cmd.inventory.hotbar", (handler.GetCurrentSlot() + 1)));
return String.Join("\n", response.ToArray()); return String.Join("\n", response.ToArray());
case "click": case "click":
if (args.Length >= 3) if (args.Length >= 3)
{ {
int slot = int.Parse(args[2]); int slot = int.Parse(args[2]);
WindowActionType actionType = WindowActionType.LeftClick; WindowActionType actionType = WindowActionType.LeftClick;
string keyName = "Left"; string keyName = "cmd.inventory.left";
if (args.Length >= 4) if (args.Length >= 4)
{ {
string b = args[3]; string b = args[3];
if (b.ToLower()[0] == 'r') if (b.ToLower()[0] == 'r')
{ {
actionType = WindowActionType.RightClick; actionType = WindowActionType.RightClick;
keyName = "Right"; keyName = "cmd.inventory.right";
} }
if (b.ToLower()[0] == 'm') if (b.ToLower()[0] == 'm')
{ {
actionType = WindowActionType.MiddleClick; actionType = WindowActionType.MiddleClick;
keyName = "Middle"; keyName = "cmd.inventory.middle";
} }
} }
handler.DoWindowAction(inventoryId, slot, actionType); handler.DoWindowAction(inventoryId, slot, actionType);
return keyName + " clicking slot " + slot + " in window #" + inventoryId; return Translations.Get("cmd.inventory.clicking", Translations.Get(keyName), slot, inventoryId);
} }
else return CMDDesc; else return CmdUsage;
case "drop": case "drop":
if (args.Length >= 3) if (args.Length >= 3)
{ {
int slot = int.Parse(args[2]); int slot = int.Parse(args[2]);
// check item exist // check item exist
if (!handler.GetInventory(inventoryId).Items.ContainsKey(slot)) if (!handler.GetInventory(inventoryId).Items.ContainsKey(slot))
return "No item in slot #" + slot; return Translations.Get("cmd.inventory.no_item", slot);
WindowActionType actionType = WindowActionType.DropItem; WindowActionType actionType = WindowActionType.DropItem;
if (args.Length >= 4) if (args.Length >= 4)
{ {
@ -143,35 +144,35 @@ namespace MinecraftClient.Commands
if (handler.DoWindowAction(inventoryId, slot, actionType)) if (handler.DoWindowAction(inventoryId, slot, actionType))
{ {
if (actionType == WindowActionType.DropItemStack) if (actionType == WindowActionType.DropItemStack)
return "Dropped whole item stack from slot #" + slot; return Translations.Get("cmd.inventory.drop_stack", slot);
else return "Dropped 1 item from slot #" + slot; else return Translations.Get("cmd.inventory.drop", slot);
} }
else else
{ {
return "Failed"; return "Failed";
} }
} }
else return CMDDesc; else return GetCmdDescTranslated();
default: default:
return CMDDesc; return GetCmdDescTranslated();
} }
} }
catch (FormatException) { return CMDDesc; } catch (FormatException) { return GetCmdDescTranslated(); }
} }
else else
{ {
Dictionary<int, Container> inventories = handler.GetInventories(); Dictionary<int, Container> inventories = handler.GetInventories();
List<string> response = new List<string>(); List<string> response = new List<string>();
response.Add("Inventories:"); response.Add(Translations.Get("cmd.inventory.inventories") + ":");
foreach (KeyValuePair<int, Container> inventory in inventories) foreach (KeyValuePair<int, Container> inventory in inventories)
{ {
response.Add(String.Format(" #{0}: {1}", inventory.Key, inventory.Value.Title + "§8")); response.Add(String.Format(" #{0}: {1}", inventory.Key, inventory.Value.Title + "§8"));
} }
response.Add(CMDDesc); response.Add(CmdUsage);
return String.Join("\n", response); return String.Join("\n", response);
} }
} }
else return "Please enable inventoryhandling in config to use this command."; else return Translations.Get("extra.inventory_required");
} }
#region Methods for commands help #region Methods for commands help
@ -182,26 +183,22 @@ namespace MinecraftClient.Commands
private string GetAvailableActions() private string GetAvailableActions()
{ {
return "Available actions: list, close, click, drop."; return Translations.Get("cmd.inventory.help.available") + ": list, close, click, drop.";
} }
private string GetBasicUsage() private string GetBasicUsage()
{ {
return "Basic usage: /inventory <player|container|<id>> <action>."; return Translations.Get("cmd.inventory.help.basic") + ": /inventory <player|container|<id>> <action>.";
} }
private string GetHelp() private string GetHelp()
{ {
return GetBasicUsage() return Translations.Get("cmd.inventory.help.help", GetAvailableActions(), GetCreativeGiveHelp());
+ "\n " + GetAvailableActions() + " Use \"/inventory help <action>\" for action help."
+ "\n Creative mode give: " + GetCreativeGiveHelp()
+ "\n \"player\" and \"container\" can be simplified to \"p\" and \"c\"."
+ "\n Note that parameters in \"[]\" are optional.";
} }
private string GetCreativeGiveHelp() private string GetCreativeGiveHelp()
{ {
return "Usage: /inventory creativegive <slot> <itemtype> <count>"; return Translations.Get("cmd.inventory.help.usage") + ": /inventory creativegive <slot> <itemtype> <count>";
} }
private string GetSubCommandHelp(string cmd) private string GetSubCommandHelp(string cmd)
@ -209,17 +206,17 @@ namespace MinecraftClient.Commands
switch (cmd) switch (cmd)
{ {
case "list": case "list":
return "List your inventory. Usage: /inventory <player|container|<id>> list"; return Translations.Get("cmd.inventory.help.list") + Translations.Get("cmd.inventory.help.usage") + ": /inventory <player|container|<id>> list";
case "close": case "close":
return "Close an opened container. Usage: /inventory <player|container|<id>> close"; return Translations.Get("cmd.inventory.help.close") + Translations.Get("cmd.inventory.help.usage") + ": /inventory <player|container|<id>> close";
case "click": case "click":
return "Click on an item. Usage: /inventory <player|container|<id>> click <slot> [left|right|middle]. \nDefault is left click"; return Translations.Get("cmd.inventory.help.click") + Translations.Get("cmd.inventory.help.usage") + ": /inventory <player|container|<id>> click <slot> [left|right|middle]. \nDefault is left click";
case "drop": case "drop":
return "Drop an item from inventory. Usage: /inventory <player|container|<id>> drop <slot> [all]. \nAll means drop full stack"; return Translations.Get("cmd.inventory.help.drop") + Translations.Get("cmd.inventory.help.usage") + ": /inventory <player|container|<id>> drop <slot> [all]. \nAll means drop full stack";
case "help": case "help":
return GetHelp(); return GetHelp();
default: default:
return "Unknown action. " + GetAvailableActions(); return Translations.Get("cmd.inventory.help.unknown") + GetAvailableActions();
} }
} }
#endregion #endregion

View file

@ -7,12 +7,13 @@ namespace MinecraftClient.Commands
{ {
public class List : Command public class List : Command
{ {
public override string CMDName { get { return "list"; } } public override string CmdName { get { return "list"; } }
public override string CMDDesc { get { return "list: get the player list."; } } public override string CmdUsage { get { return "list"; } }
public override string CmdDesc { get { return "cmd.list.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
return "PlayerList: " + String.Join(", ", handler.GetOnlinePlayers()); return Translations.Get("cmd.list.players", String.Join(", ", handler.GetOnlinePlayers()));
} }
} }
} }

View file

@ -7,8 +7,9 @@ namespace MinecraftClient.Commands
{ {
public class Log : Command public class Log : Command
{ {
public override string CMDName { get { return "log"; } } public override string CmdName { get { return "log"; } }
public override string CMDDesc { get { return "log <text>: log some text to the console."; } } public override string CmdUsage { get { return "log <text>"; } }
public override string CmdDesc { get { return "cmd.log.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
@ -17,7 +18,7 @@ namespace MinecraftClient.Commands
ConsoleIO.WriteLogLine(getArg(command)); ConsoleIO.WriteLogLine(getArg(command));
return ""; return "";
} }
else return CMDDesc; else return GetCmdDescTranslated();
} }
} }
} }

View file

@ -8,8 +8,9 @@ namespace MinecraftClient.Commands
{ {
public class Look : Command public class Look : Command
{ {
public override string CMDName { get { return "look"; } } public override string CmdName { get { return "look"; } }
public override string CMDDesc { get { return "look <x y z|yaw pitch|up|down|east|west|north|south>: look at direction or coordinates."; } } public override string CmdUsage { get { return "look <x y z|yaw pitch|up|down|east|west|north|south>"; } }
public override string CmdDesc { get { return "cmd.look.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
@ -28,7 +29,7 @@ namespace MinecraftClient.Commands
case "west": direction = Direction.West; break; case "west": direction = Direction.West; break;
case "north": direction = Direction.North; break; case "north": direction = Direction.North; break;
case "south": direction = Direction.South; break; case "south": direction = Direction.South; break;
default: return "Unknown direction '" + dirStr + "'."; default: return Translations.Get("cmd.look.unknown", dirStr);
} }
handler.UpdateLocation(handler.GetCurrentLocation(), direction); handler.UpdateLocation(handler.GetCurrentLocation(), direction);
@ -42,9 +43,9 @@ namespace MinecraftClient.Commands
float pitch = Single.Parse(args[1]); float pitch = Single.Parse(args[1]);
handler.UpdateLocation(handler.GetCurrentLocation(), yaw, pitch); handler.UpdateLocation(handler.GetCurrentLocation(), yaw, pitch);
return String.Format("Looking at YAW: {0} PITCH: {1}", yaw.ToString("0.00"), pitch.ToString("0.00")); return Translations.Get("cmd.look.at", yaw.ToString("0.00"), pitch.ToString("0.00"));
} }
catch (FormatException) { return CMDDesc; } catch (FormatException) { return GetCmdDescTranslated(); }
} }
else if (args.Length == 3) else if (args.Length == 3)
{ {
@ -57,14 +58,14 @@ namespace MinecraftClient.Commands
Location block = new Location(x, y, z); Location block = new Location(x, y, z);
handler.UpdateLocation(handler.GetCurrentLocation(), block); handler.UpdateLocation(handler.GetCurrentLocation(), block);
return "Looking at " + block; return Translations.Get("cmd.look.block", block);
} }
catch (FormatException) { return CMDDesc; } catch (FormatException) { return CmdUsage; }
} }
else return CMDDesc; else return GetCmdDescTranslated();
} }
else return "Please enable terrainandmovements in config to use this command."; else return Translations.Get("extra.terrainandmovement_required");
} }
} }
} }

View file

@ -8,8 +8,9 @@ namespace MinecraftClient.Commands
{ {
public class Move : Command public class Move : Command
{ {
public override string CMDName { get { return "move"; } } public override string CmdName { get { return "move"; } }
public override string CMDDesc { get { return "move <on|off|get|up|down|east|west|north|south|x y z>: walk or start walking."; } } public override string CmdUsage { get { return "move <on|off|get|up|down|east|west|north|south|x y z>"; } }
public override string CmdDesc { get { return "walk or start walking."; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
@ -19,12 +20,12 @@ namespace MinecraftClient.Commands
if (argStr == "on") if (argStr == "on")
{ {
handler.SetTerrainEnabled(true); handler.SetTerrainEnabled(true);
return "Enabling Terrain and Movements on next server login, respawn or world change."; return Translations.Get("cmd.move.enable");
} }
else if (argStr == "off") else if (argStr == "off")
{ {
handler.SetTerrainEnabled(false); handler.SetTerrainEnabled(false);
return "Disabling Terrain and Movements."; return Translations.Get("cmd.move.disable");
} }
else if (handler.GetTerrainEnabled()) else if (handler.GetTerrainEnabled())
{ {
@ -40,14 +41,14 @@ namespace MinecraftClient.Commands
case "north": direction = Direction.North; break; case "north": direction = Direction.North; break;
case "south": direction = Direction.South; break; case "south": direction = Direction.South; break;
case "get": return handler.GetCurrentLocation().ToString(); case "get": return handler.GetCurrentLocation().ToString();
default: return "Unknown direction '" + argStr + "'."; default: return Translations.Get("cmd.look.unknown", argStr);
} }
if (Movement.CanMove(handler.GetWorld(), handler.GetCurrentLocation(), direction)) if (Movement.CanMove(handler.GetWorld(), handler.GetCurrentLocation(), direction))
{ {
handler.MoveTo(Movement.Move(handler.GetCurrentLocation(), direction)); handler.MoveTo(Movement.Move(handler.GetCurrentLocation(), direction));
return "Moving " + argStr + '.'; return Translations.Get("cmd.move.moving", argStr);
} }
else return "Cannot move in that direction."; else return Translations.Get("cmd.move.dir_fail");
} }
else if (args.Length == 3) else if (args.Length == 3)
{ {
@ -58,14 +59,14 @@ namespace MinecraftClient.Commands
int z = int.Parse(args[2]); int z = int.Parse(args[2]);
Location goal = new Location(x, y, z); Location goal = new Location(x, y, z);
if (handler.MoveTo(goal)) if (handler.MoveTo(goal))
return "Walking to " + goal; return Translations.Get("cmd.move.walk", goal);
return "Failed to compute path to " + goal; return Translations.Get("cmd.move.fail", goal);
} }
catch (FormatException) { return CMDDesc; } catch (FormatException) { return GetCmdDescTranslated(); }
} }
else return CMDDesc; else return GetCmdDescTranslated();
} }
else return "Please enable terrainandmovements to use this command."; else return Translations.Get("extra.terrainandmovement_required");
} }
} }
} }

View file

@ -7,8 +7,9 @@ namespace MinecraftClient.Commands
{ {
public class Reco : Command public class Reco : Command
{ {
public override string CMDName { get { return "reco"; } } public override string CmdName { get { return "reco"; } }
public override string CMDDesc { get { return "reco [account]: restart and reconnect to the server."; } } public override string CmdUsage { get { return "reco [account]"; } }
public override string CmdDesc { get { return "cmd.reco.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
@ -17,7 +18,7 @@ namespace MinecraftClient.Commands
{ {
if (!Settings.SetAccount(args[0])) if (!Settings.SetAccount(args[0]))
{ {
return "Unknown account '" + args[0] + "'."; return Translations.Get("cmd.connect.unknown", args[0]);
} }
} }
Program.Restart(); Program.Restart();

View file

@ -7,13 +7,14 @@ namespace MinecraftClient.Commands
{ {
public class Respawn : Command public class Respawn : Command
{ {
public override string CMDName { get { return "respawn"; } } public override string CmdName { get { return "respawn"; } }
public override string CMDDesc { get { return "respawn: Use this to respawn if you are dead."; } } public override string CmdUsage { get { return "respawn"; } }
public override string CmdDesc { get { return "cmd.respawn.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
handler.SendRespawnPacket(); handler.SendRespawnPacket();
return "You have respawned."; return Translations.Get("cmd.respawn.done");
} }
} }
} }

View file

@ -7,8 +7,9 @@ namespace MinecraftClient.Commands
{ {
public class Script : Command public class Script : Command
{ {
public override string CMDName { get { return "script"; } } public override string CmdName { get { return "script"; } }
public override string CMDDesc { get { return "script <scriptname>: run a script file."; } } public override string CmdUsage { get { return "script <scriptname>"; } }
public override string CmdDesc { get { return "cmd.script.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
@ -17,7 +18,7 @@ namespace MinecraftClient.Commands
handler.BotLoad(new ChatBots.Script(getArg(command), null, localVars)); handler.BotLoad(new ChatBots.Script(getArg(command), null, localVars));
return ""; return "";
} }
else return CMDDesc; else return GetCmdDescTranslated();
} }
} }
} }

View file

@ -7,8 +7,9 @@ namespace MinecraftClient.Commands
{ {
public class Send : Command public class Send : Command
{ {
public override string CMDName { get { return "send"; } } public override string CmdName { get { return "send"; } }
public override string CMDDesc { get { return "send <text>: send a chat message or command."; } } public override string CmdUsage { get { return "send <text>"; } }
public override string CmdDesc { get { return "cmd.send.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
@ -17,7 +18,7 @@ namespace MinecraftClient.Commands
handler.SendText(getArg(command)); handler.SendText(getArg(command));
return ""; return "";
} }
else return CMDDesc; else return GetCmdDescTranslated();
} }
} }
} }

View file

@ -7,8 +7,9 @@ namespace MinecraftClient.Commands
{ {
public class Set : Command public class Set : Command
{ {
public override string CMDName { get { return "set"; } } public override string CmdName { get { return "set"; } }
public override string CMDDesc { get { return "set varname=value: set a custom %variable%."; } } public override string CmdUsage { get { return "set varname=value"; } }
public override string CmdDesc { get { return "cmd.set.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
@ -21,11 +22,11 @@ namespace MinecraftClient.Commands
{ {
return ""; //Success return ""; //Success
} }
else return "variable name must be A-Za-z0-9."; else return Translations.Get("cmd.set.format");
} }
else return CMDDesc; else return GetCmdDescTranslated();
} }
else return CMDDesc; else return GetCmdDescTranslated();
} }
} }
} }

View file

@ -8,8 +8,9 @@ namespace MinecraftClient.Commands
public class Sneak : Command public class Sneak : Command
{ {
private bool sneaking = false; private bool sneaking = false;
public override string CMDName { get { return "Sneak"; } } public override string CmdName { get { return "Sneak"; } }
public override string CMDDesc { get { return "Sneak: Toggles sneaking"; } } public override string CmdUsage { get { return "Sneak"; } }
public override string CmdDesc { get { return "cmd.sneak.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
@ -18,14 +19,14 @@ namespace MinecraftClient.Commands
var result = handler.SendEntityAction(Protocol.EntityActionType.StopSneaking); var result = handler.SendEntityAction(Protocol.EntityActionType.StopSneaking);
if (result) if (result)
sneaking = false; sneaking = false;
return result ? "You aren't sneaking anymore" : "Fail"; return Translations.Get(result ? "cmd.sneak.off" : "general.fail");
} }
else else
{ {
var result = handler.SendEntityAction(Protocol.EntityActionType.StartSneaking); var result = handler.SendEntityAction(Protocol.EntityActionType.StartSneaking);
if (result) if (result)
sneaking = true; sneaking = true;
return result ? "You are sneaking now" : "Fail"; return Translations.Get(result ? "cmd.sneak.on" : "general.fail");
} }
} }

View file

@ -7,8 +7,9 @@ namespace MinecraftClient.Commands
{ {
class Tps : Command class Tps : Command
{ {
public override string CMDName { get { return "tps"; } } public override string CmdName { get { return "tps"; } }
public override string CMDDesc { get { return "Display server current tps (tick per second). May not be accurate"; } } public override string CmdUsage { get { return "tps"; } }
public override string CmdDesc { get { return "cmd.tps.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
@ -19,7 +20,7 @@ namespace MinecraftClient.Commands
else if (tps < 15) else if (tps < 15)
color = "§e"; // Yellow color = "§e"; // Yellow
else color = "§a"; // Green else color = "§a"; // Green
return "Current tps: " + color + tps; return Translations.Get("cmd.tps.current") + ": " + color + tps;
} }
} }
} }

View file

@ -7,17 +7,18 @@ namespace MinecraftClient.Commands
{ {
class UseItem : Command class UseItem : Command
{ {
public override string CMDName { get { return "useitem"; } } public override string CmdName { get { return "useitem"; } }
public override string CMDDesc { get { return "useitem: Use (left click) an item on the hand"; } } public override string CmdUsage { get { return "useitem"; } }
public override string CmdDesc { get { return "cmd.useitem.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
if (handler.GetInventoryEnabled()) if (handler.GetInventoryEnabled())
{ {
handler.UseItemOnHand(); handler.UseItemOnHand();
return "Used an item"; return Translations.Get("cmd.useitem.use");
} }
else return "Please enable inventoryhandling in config to use this command."; else return Translations.Get("extra.inventory_required");
} }
} }
} }

View file

@ -8,12 +8,13 @@ namespace MinecraftClient.Commands
{ {
class Useblock : Command class Useblock : Command
{ {
public override string CMDName { get { return "useblock"; } } public override string CmdName { get { return "useblock"; } }
public override string CMDDesc { get { return "useblock <x> <y> <z>: use block"; } } public override string CmdUsage { get { return "useblock <x> <y> <z>"; } }
public override string CmdDesc { get { return "cmd.useblock.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object> localVars)
{ {
if (!handler.GetTerrainEnabled()) return "Please enable TerrainHandling in the config file first."; if (!handler.GetTerrainEnabled()) return Translations.Get("extra.terrainandmovement_required");
if (hasArg(command)) if (hasArg(command))
{ {
string[] args = getArgs(command); string[] args = getArgs(command);
@ -24,9 +25,9 @@ namespace MinecraftClient.Commands
int z = Convert.ToInt32(args[2]); int z = Convert.ToInt32(args[2]);
handler.PlaceBlock(new Location(x, y, z), Direction.Down); handler.PlaceBlock(new Location(x, y, z), Direction.Down);
} }
else { return CMDDesc; } else { return GetCmdDescTranslated(); }
} }
return CMDDesc; return GetCmdDescTranslated();
} }
} }
} }

View file

@ -0,0 +1,111 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 這段程式碼是由工具產生的。
// 執行階段版本:4.0.30319.42000
//
// 對這個檔案所做的變更可能會造成錯誤的行為,而且如果重新產生程式碼,
// 變更將會遺失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace MinecraftClient {
using System;
/// <summary>
/// 用於查詢當地語系化字串等的強類型資源類別。
/// </summary>
// 這個類別是自動產生的,是利用 StronglyTypedResourceBuilder
// 類別透過 ResGen 或 Visual Studio 這類工具。
// 若要加入或移除成員,請編輯您的 .ResX 檔,然後重新執行 ResGen
// (利用 /str 選項),或重建您的 VS 專案。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class DefaultConfigResource {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal DefaultConfigResource() {
}
/// <summary>
/// 傳回這個類別使用的快取的 ResourceManager 執行個體。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MinecraftClient.DefaultConfigResource", typeof(DefaultConfigResource).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 覆寫目前執行緒的 CurrentUICulture 屬性,對象是所有
/// 使用這個強類型資源類別的資源查閱。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// 查詢類似 # Minecraft Console Client v1.16.3
///# Startup Config File
///
///[Main]
///
///# General settings
///# Leave blank to prompt user on startup
///# Use &quot;-&quot; as password for offline mode
///
///login=
///password=
///serverip=
///
///# Advanced settings
///
///language=en_GB
///consoletitle=%username%@%serverip% - Minecraft Console Client
///internalcmdchar=slash # Use &apos;none&apos;, &apos;slash&apos; or &apos;backslash&apos;
///splitmessagedelay=2 # Seconds between each part of a long message
///botowners=Player1,Player2,Player3 # Name list or [字串的其餘部分已遭截斷]&quot;; 的當地語系化字串。
/// </summary>
public static string MinecraftClient {
get {
return ResourceManager.GetString("MinecraftClient", resourceCulture);
}
}
/// <summary>
/// 查詢類似 [mcc]
///# Messages from MCC itself
///mcc.description=Console Client for MC {0} to {1} - v{2} - By ORelio &amp; Contributors
///mcc.keyboard_debug=Keyboard debug mode: Press any key to display info
///mcc.setting=Loading Settings from {0}
///mcc.login=Login :
///mcc.login_basic_io=Please type the username or email of your choice.
///mcc.password=Password :
///mcc.password_basic_io=Please type the password for {0}.
///mcc.password_hidden=Password : {0}
///mcc.offline=§8You chose to run in offline mode.
///mcc.session_invalid=§8Cach [字串的其餘部分已遭截斷]&quot;; 的當地語系化字串。
/// </summary>
public static string TranslationEnglish {
get {
return ResourceManager.GetString("TranslationEnglish", resourceCulture);
}
}
}
}

View file

@ -0,0 +1,127 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="MinecraftClient" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\config\MinecraftClient.ini;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="TranslationEnglish" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\lang\en.ini;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
</root>

View file

@ -25,7 +25,7 @@ namespace MinecraftClient
if (Settings.DebugMessages) if (Settings.DebugMessages)
{ {
string callerClass = new System.Diagnostics.StackFrame(1).GetMethod().DeclaringType.Name; string callerClass = new System.Diagnostics.StackFrame(1).GetMethod().DeclaringType.Name;
ConsoleIO.WriteLineFormatted(String.Format("§8[{0}] Initializing FileSystemWatcher for file: {1}", callerClass, Path.Combine(folder, filename))); ConsoleIO.WriteLineFormatted(Translations.Get("filemonitor.init", callerClass, Path.Combine(folder, filename)));
} }
try try
@ -43,7 +43,7 @@ namespace MinecraftClient
if (Settings.DebugMessages) if (Settings.DebugMessages)
{ {
string callerClass = new System.Diagnostics.StackFrame(1).GetMethod().DeclaringType.Name; string callerClass = new System.Diagnostics.StackFrame(1).GetMethod().DeclaringType.Name;
ConsoleIO.WriteLineFormatted(String.Format("§8[{0}] Failed to initialize FileSystemWatcher, retrying using Polling", callerClass)); ConsoleIO.WriteLineFormatted(Translations.Get("filemonitor.fail", callerClass));
} }
monitor = null; monitor = null;

View file

@ -202,7 +202,7 @@ namespace MinecraftClient
client = ProxyHandler.newTcpClient(host, port); client = ProxyHandler.newTcpClient(host, port);
client.ReceiveBufferSize = 1024 * 1024; client.ReceiveBufferSize = 1024 * 1024;
handler = Protocol.ProtocolHandler.GetProtocolHandler(client, protocolversion, forgeInfo, this); handler = Protocol.ProtocolHandler.GetProtocolHandler(client, protocolversion, forgeInfo, this);
Console.WriteLine("Version is supported.\nLogging in..."); Translations.WriteLine("mcc.version_supported");
try try
{ {
@ -211,7 +211,7 @@ namespace MinecraftClient
if (singlecommand) if (singlecommand)
{ {
handler.SendChatMessage(command); handler.SendChatMessage(command);
ConsoleIO.WriteLineFormatted("§7Command §8" + command + "§7 sent."); ConsoleIO.WriteLineFormatted(Translations.Get("mcc.single_cmd", command));
Thread.Sleep(5000); Thread.Sleep(5000);
handler.Disconnect(); handler.Disconnect();
Thread.Sleep(1000); Thread.Sleep(1000);
@ -222,9 +222,7 @@ namespace MinecraftClient
BotLoad(bot, false); BotLoad(bot, false);
botsOnHold.Clear(); botsOnHold.Clear();
Console.WriteLine("Server was successfully joined.\nType '" Translations.WriteLine("mcc.joined", (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar));
+ (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar)
+ "quit' to leave the server.");
cmdprompt = new Thread(new ThreadStart(CommandPrompt)); cmdprompt = new Thread(new ThreadStart(CommandPrompt));
cmdprompt.Name = "MCC Command prompt"; cmdprompt.Name = "MCC Command prompt";
@ -237,21 +235,21 @@ namespace MinecraftClient
} }
else else
{ {
Console.WriteLine("Failed to login to this server."); Translations.WriteLine("error.login_failed");
retry = true; retry = true;
} }
} }
catch (Exception e) catch (Exception e)
{ {
ConsoleIO.WriteLineFormatted("§8" + e.GetType().Name + ": " + e.Message); ConsoleIO.WriteLineFormatted("§8" + e.GetType().Name + ": " + e.Message);
Console.WriteLine("Failed to join this server."); Translations.WriteLine("error.join");
retry = true; retry = true;
} }
} }
catch (SocketException e) catch (SocketException e)
{ {
ConsoleIO.WriteLineFormatted("§8" + e.Message); ConsoleIO.WriteLineFormatted("§8" + e.Message);
Console.WriteLine("Failed to connect to this IP."); Translations.WriteLine("error.connect");
retry = true; retry = true;
} }
@ -259,7 +257,7 @@ namespace MinecraftClient
{ {
if (ReconnectionAttemptsLeft > 0) if (ReconnectionAttemptsLeft > 0)
{ {
ConsoleIO.WriteLogLine("Waiting 5 seconds (" + ReconnectionAttemptsLeft + " attempts left)..."); ConsoleIO.WriteLogLine(Translations.Get("mcc.reconnect", ReconnectionAttemptsLeft));
Thread.Sleep(5000); Thread.Sleep(5000);
ReconnectionAttemptsLeft--; ReconnectionAttemptsLeft--;
Program.Restart(); Program.Restart();
@ -340,7 +338,7 @@ namespace MinecraftClient
{ {
if (lastKeepAlive.AddSeconds(30) < DateTime.Now) if (lastKeepAlive.AddSeconds(30) < DateTime.Now)
{ {
OnConnectionLost(ChatBot.DisconnectReason.ConnectionLost, "Connection Timeout"); OnConnectionLost(ChatBot.DisconnectReason.ConnectionLost, Translations.Get("error.timeout"));
return; return;
} }
} }
@ -367,15 +365,15 @@ namespace MinecraftClient
string help_cmdname = Command.getArgs(command)[0].ToLower(); string help_cmdname = Command.getArgs(command)[0].ToLower();
if (help_cmdname == "help") if (help_cmdname == "help")
{ {
response_msg = "help <cmdname>: show brief help about a command."; response_msg = Translations.Get("icmd.help");
} }
else if (cmds.ContainsKey(help_cmdname)) else if (cmds.ContainsKey(help_cmdname))
{ {
response_msg = cmds[help_cmdname].CMDDesc; response_msg = cmds[help_cmdname].GetCmdDescTranslated();
} }
else response_msg = "Unknown command '" + command_name + "'. Use 'help' for command list."; else response_msg = Translations.Get("icmd.unknown", command_name);
} }
else response_msg = "help <cmdname>. Available commands: " + String.Join(", ", cmd_names.ToArray()) + ". For server help, use '" + Settings.internalCmdChar + "send /help' instead."; else response_msg = Translations.Get("icmd.list", String.Join(", ", cmd_names.ToArray()), Settings.internalCmdChar);
} }
else if (cmds.ContainsKey(command_name)) else if (cmds.ContainsKey(command_name))
{ {
@ -390,7 +388,7 @@ namespace MinecraftClient
{ {
if (!(e is ThreadAbortException)) if (!(e is ThreadAbortException))
{ {
ConsoleIO.WriteLogLine("OnInternalCommand: Got error from " + bot.ToString() + ": " + e.ToString()); ConsoleIO.WriteLogLine(Translations.Get("icmd.error", bot.ToString(), e.ToString()));
} }
else throw; //ThreadAbortException should not be caught else throw; //ThreadAbortException should not be caught
} }
@ -398,7 +396,7 @@ namespace MinecraftClient
} }
else else
{ {
response_msg = "Unknown command '" + command_name + "'. Use '" + (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar) + "help' for help."; response_msg = Translations.Get("icmd.unknown", command_name);
return false; return false;
} }
@ -419,8 +417,8 @@ namespace MinecraftClient
try try
{ {
Command cmd = (Command)Activator.CreateInstance(type); Command cmd = (Command)Activator.CreateInstance(type);
cmds[cmd.CMDName.ToLower()] = cmd; cmds[cmd.CmdName.ToLower()] = cmd;
cmd_names.Add(cmd.CMDName.ToLower()); cmd_names.Add(cmd.CmdName.ToLower());
foreach (string alias in cmd.getCMDAliases()) foreach (string alias in cmd.getCMDAliases())
cmds[alias.ToLower()] = cmd; cmds[alias.ToLower()] = cmd;
} }
@ -439,21 +437,7 @@ namespace MinecraftClient
/// </summary> /// </summary>
public void Disconnect() public void Disconnect()
{ {
foreach (ChatBot bot in bots.ToArray()) DispatchBotEvent(bot => bot.OnDisconnect(ChatBot.DisconnectReason.UserLogout, ""));
{
try
{
bot.OnDisconnect(ChatBot.DisconnectReason.UserLogout, "");
}
catch (Exception e)
{
if (!(e is ThreadAbortException))
{
ConsoleIO.WriteLogLine("OnDisconnect: Got error from " + bot.ToString() + ": " + e.ToString());
}
else throw; //ThreadAbortException should not be caught
}
}
botsOnHold.Clear(); botsOnHold.Clear();
botsOnHold.AddRange(bots); botsOnHold.AddRange(bots);
@ -498,22 +482,22 @@ namespace MinecraftClient
switch (reason) switch (reason)
{ {
case ChatBot.DisconnectReason.ConnectionLost: case ChatBot.DisconnectReason.ConnectionLost:
message = "Connection has been lost."; message = Translations.Get("mcc.disconnect.lost");
ConsoleIO.WriteLine(message); ConsoleIO.WriteLine(message);
break; break;
case ChatBot.DisconnectReason.InGameKick: case ChatBot.DisconnectReason.InGameKick:
ConsoleIO.WriteLine("Disconnected by Server :"); Translations.WriteLine("mcc.disconnect.server");
ConsoleIO.WriteLineFormatted(message); ConsoleIO.WriteLineFormatted(message);
break; break;
case ChatBot.DisconnectReason.LoginRejected: case ChatBot.DisconnectReason.LoginRejected:
ConsoleIO.WriteLine("Login failed :"); ConsoleIO.WriteLine("mcc.disconnect.login");
ConsoleIO.WriteLineFormatted(message); ConsoleIO.WriteLineFormatted(message);
break; break;
case ChatBot.DisconnectReason.UserLogout: case ChatBot.DisconnectReason.UserLogout:
throw new InvalidOperationException("User-initiated logout should be done by calling Disconnect()"); throw new InvalidOperationException(Translations.Get("exception.user_logout"));
} }
foreach (ChatBot bot in bots.ToArray()) foreach (ChatBot bot in bots.ToArray())
@ -605,7 +589,7 @@ namespace MinecraftClient
/// <param name="cmdDesc">Description/usage of the command</param> /// <param name="cmdDesc">Description/usage of the command</param>
/// <param name="callback">Method for handling the command</param> /// <param name="callback">Method for handling the command</param>
/// <returns>True if successfully registered</returns> /// <returns>True if successfully registered</returns>
public bool RegisterCommand(string cmdName, string cmdDesc, ChatBot.CommandRunner callback) public bool RegisterCommand(string cmdName, string cmdDesc, string cmdUsage, ChatBot.CommandRunner callback)
{ {
if (cmds.ContainsKey(cmdName.ToLower())) if (cmds.ContainsKey(cmdName.ToLower()))
{ {
@ -613,7 +597,7 @@ namespace MinecraftClient
} }
else else
{ {
Command cmd = new ChatBot.ChatBotCommand(cmdName, cmdDesc, callback); Command cmd = new ChatBot.ChatBotCommand(cmdName, cmdDesc, cmdUsage, callback);
cmds.Add(cmdName.ToLower(), cmd); cmds.Add(cmdName.ToLower(), cmd);
cmd_names.Add(cmdName.ToLower()); cmd_names.Add(cmdName.ToLower());
return true; return true;
@ -1550,7 +1534,7 @@ namespace MinecraftClient
{ {
inventoryHandlingRequested = false; inventoryHandlingRequested = false;
inventoryHandlingEnabled = true; inventoryHandlingEnabled = true;
ConsoleIO.WriteLogLine("Inventory handling is now enabled."); Translations.WriteLogLine("extra.inventory_enabled");
} }
ClearInventories(); ClearInventories();
@ -1567,7 +1551,7 @@ namespace MinecraftClient
{ {
terrainAndMovementsEnabled = true; terrainAndMovementsEnabled = true;
terrainAndMovementsRequested = false; terrainAndMovementsRequested = false;
ConsoleIO.WriteLogLine("Terrain and Movements is now enabled."); Translations.WriteLogLine("extra.terrainandmovement_enabled");
} }
if (terrainAndMovementsEnabled) if (terrainAndMovementsEnabled)
@ -1665,7 +1649,7 @@ namespace MinecraftClient
case Direction.South: case Direction.South:
break; break;
default: default:
throw new ArgumentException("Unknown direction", "direction"); throw new ArgumentException(Translations.Get("exception.unknown_direction"), "direction");
} }
UpdateLocation(location, yaw, pitch); UpdateLocation(location, yaw, pitch);
@ -1696,7 +1680,7 @@ namespace MinecraftClient
if (Settings.DisplayChatLinks) if (Settings.DisplayChatLinks)
foreach (string link in links) foreach (string link in links)
ConsoleIO.WriteLogLine("Link: " + link, false); ConsoleIO.WriteLogLine(Translations.Get("mcc.link", link), false);
DispatchBotEvent(bot => bot.GetText(text)); DispatchBotEvent(bot => bot.GetText(text));
DispatchBotEvent(bot => bot.GetText(text, json)); DispatchBotEvent(bot => bot.GetText(text, json));
@ -1724,8 +1708,8 @@ namespace MinecraftClient
if (inventoryID != 0) if (inventoryID != 0)
{ {
ConsoleIO.WriteLogLine("Inventory # " + inventoryID + " opened: " + inventory.Title); ConsoleIO.WriteLogLine(Translations.Get("extra.inventory_open", inventoryID, inventory.Title));
ConsoleIO.WriteLogLine("Use /inventory to interact with it."); Translations.WriteLogLine("extra.inventory_interact");
DispatchBotEvent(bot => bot.OnInventoryOpen(inventoryID)); DispatchBotEvent(bot => bot.OnInventoryOpen(inventoryID));
} }
} }
@ -1741,7 +1725,7 @@ namespace MinecraftClient
if (inventoryID != 0) if (inventoryID != 0)
{ {
ConsoleIO.WriteLogLine("Inventory # " + inventoryID + " closed."); ConsoleIO.WriteLogLine(Translations.Get("extra.inventory_close", inventoryID));
DispatchBotEvent(bot => bot.OnInventoryClose(inventoryID)); DispatchBotEvent(bot => bot.OnInventoryClose(inventoryID));
} }
} }
@ -2073,12 +2057,12 @@ namespace MinecraftClient
{ {
if (Settings.AutoRespawn) if (Settings.AutoRespawn)
{ {
ConsoleIO.WriteLogLine("You are dead. Automatically respawning after 1 second."); Translations.WriteLogLine("mcc.player_dead_respawn");
respawnTicks = 10; respawnTicks = 10;
} }
else else
{ {
ConsoleIO.WriteLogLine("You are dead. Type /respawn to respawn."); Translations.WriteLogLine("mcc.player_dead");
} }
DispatchBotEvent(bot => bot.OnDeath()); DispatchBotEvent(bot => bot.OnDeath());
} }

View file

@ -114,6 +114,11 @@
<Compile Include="Commands\Tps.cs" /> <Compile Include="Commands\Tps.cs" />
<Compile Include="Commands\Useblock.cs" /> <Compile Include="Commands\Useblock.cs" />
<Compile Include="Commands\UseItem.cs" /> <Compile Include="Commands\UseItem.cs" />
<Compile Include="DefaultConfigResource.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>DefaultConfigResource.resx</DependentUpon>
</Compile>
<Compile Include="INIFile.cs" /> <Compile Include="INIFile.cs" />
<Compile Include="Inventory\Container.cs" /> <Compile Include="Inventory\Container.cs" />
<Compile Include="Inventory\ContainerType.cs" /> <Compile Include="Inventory\ContainerType.cs" />
@ -208,6 +213,7 @@
<Compile Include="Protocol\DataTypeGenerator.cs" /> <Compile Include="Protocol\DataTypeGenerator.cs" />
<Compile Include="FileMonitor.cs" /> <Compile Include="FileMonitor.cs" />
<Compile Include="Protocol\ReplayHandler.cs" /> <Compile Include="Protocol\ReplayHandler.cs" />
<Compile Include="Translations.cs" />
<Compile Include="WinAPI\ConsoleIcon.cs" /> <Compile Include="WinAPI\ConsoleIcon.cs" />
<Compile Include="ConsoleIO.cs" /> <Compile Include="ConsoleIO.cs" />
<Compile Include="Crypto\Streams\BouncyAes\AesFastEngine.cs" /> <Compile Include="Crypto\Streams\BouncyAes\AesFastEngine.cs" />
@ -375,7 +381,16 @@
<Content Include="Protocol\Dns\Records\totla.txt" /> <Content Include="Protocol\Dns\Records\totla.txt" />
<Content Include="Resources\AppIcon.ico" /> <Content Include="Resources\AppIcon.ico" />
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup>
<EmbeddedResource Include="DefaultConfigResource.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>DefaultConfigResource.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="Resources\config\MinecraftClient.ini" />
<None Include="Resources\lang\en.ini" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

View file

@ -54,7 +54,7 @@ namespace MinecraftClient
//Debug input ? //Debug input ?
if (args.Length == 1 && args[0] == "--keyboard-debug") if (args.Length == 1 && args[0] == "--keyboard-debug")
{ {
Console.WriteLine("Keyboard debug mode: Press any key to display info"); ConsoleIO.WriteLine("Keyboard debug mode: Press any key to display info");
ConsoleIO.DebugReadInput(); ConsoleIO.DebugReadInput();
} }
@ -92,6 +92,9 @@ namespace MinecraftClient
} }
else Settings.WriteDefaultSettings("MinecraftClient.ini"); else Settings.WriteDefaultSettings("MinecraftClient.ini");
//Load external translation file. Should be called AFTER settings loaded
Translations.LoadExternalTranslationFile(Settings.Language);
//Other command-line arguments //Other command-line arguments
if (args.Length >= 1) if (args.Length >= 1)
{ {
@ -121,7 +124,7 @@ namespace MinecraftClient
//Test line to troubleshoot invisible colors //Test line to troubleshoot invisible colors
if (Settings.DebugMessages) if (Settings.DebugMessages)
{ {
ConsoleIO.WriteLineFormatted("Color test: Your terminal should display [0123456789ABCDEF]: [§00§11§22§33§44§55§66§77§88§99§aA§bB§cC§dD§eE§fF§r]"); Translations.WriteLineFormatted(Translations.Get("debug.color_test", "[0123456789ABCDEF]: [§00§11§22§33§44§55§66§77§88§99§aA§bB§cC§dD§eE§fF§r]"));
} }
//Load cached sessions from disk if necessary //Load cached sessions from disk if necessary
@ -129,14 +132,14 @@ namespace MinecraftClient
{ {
bool cacheLoaded = SessionCache.InitializeDiskCache(); bool cacheLoaded = SessionCache.InitializeDiskCache();
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted(cacheLoaded ? "§8Session data has been successfully loaded from disk." : "§8No sessions could be loaded from disk"); Translations.WriteLineFormatted(cacheLoaded ? "debug.session_cache_ok" : "debug.session_cache_fail");
} }
//Asking the user to type in missing data such as Username and Password //Asking the user to type in missing data such as Username and Password
if (Settings.Login == "") if (Settings.Login == "")
{ {
Console.Write(ConsoleIO.BasicIO ? "Please type the username or email of your choice.\n" : "Login : "); Console.Write(ConsoleIO.BasicIO ? Translations.Get("mcc.login_basic_io") + "\n" : Translations.Get("mcc.login"));
Settings.Login = Console.ReadLine(); Settings.Login = Console.ReadLine();
} }
if (Settings.Password == "" && (Settings.SessionCaching == CacheType.None || !SessionCache.Contains(Settings.Login.ToLower()))) if (Settings.Password == "" && (Settings.SessionCaching == CacheType.None || !SessionCache.Contains(Settings.Login.ToLower())))
@ -153,13 +156,13 @@ namespace MinecraftClient
/// </summary> /// </summary>
private static void RequestPassword() private static void RequestPassword()
{ {
Console.Write(ConsoleIO.BasicIO ? "Please type the password for " + Settings.Login + ".\n" : "Password : "); Console.Write(ConsoleIO.BasicIO ? Translations.Get("mcc.password_basic_io", Settings.Login) + "\n" : Translations.Get("mcc.password"));
Settings.Password = ConsoleIO.BasicIO ? Console.ReadLine() : ConsoleIO.ReadPassword(); Settings.Password = ConsoleIO.BasicIO ? Console.ReadLine() : ConsoleIO.ReadPassword();
if (Settings.Password == "") { Settings.Password = "-"; } if (Settings.Password == "") { Settings.Password = "-"; }
if (!ConsoleIO.BasicIO) if (!ConsoleIO.BasicIO)
{ {
//Hide password length //Hide password length
Console.CursorTop--; Console.Write("Password : <******>"); Console.CursorTop--; Console.Write(Translations.Get("mcc.password_hidden", "<******>"));
for (int i = 19; i < Console.BufferWidth; i++) { Console.Write(' '); } for (int i = 19; i < Console.BufferWidth; i++) { Console.Write(' '); }
} }
} }
@ -175,7 +178,7 @@ namespace MinecraftClient
if (Settings.Password == "-") if (Settings.Password == "-")
{ {
ConsoleIO.WriteLineFormatted("§8You chose to run in offline mode."); Translations.WriteLineFormatted("mcc.offline");
result = ProtocolHandler.LoginResult.Success; result = ProtocolHandler.LoginResult.Success;
session.PlayerID = "0"; session.PlayerID = "0";
session.PlayerName = Settings.Login; session.PlayerName = Settings.Login;
@ -189,16 +192,16 @@ namespace MinecraftClient
result = ProtocolHandler.GetTokenValidation(session); result = ProtocolHandler.GetTokenValidation(session);
if (result != ProtocolHandler.LoginResult.Success) if (result != ProtocolHandler.LoginResult.Success)
{ {
ConsoleIO.WriteLineFormatted("§8Cached session is invalid or expired."); Translations.WriteLineFormatted("mcc.session_invalid");
if (Settings.Password == "") if (Settings.Password == "")
RequestPassword(); RequestPassword();
} }
else ConsoleIO.WriteLineFormatted("§8Cached session is still valid for " + session.PlayerName + '.'); else ConsoleIO.WriteLineFormatted(Translations.Get("mcc.session_valid", session.PlayerName));
} }
if (result != ProtocolHandler.LoginResult.Success) if (result != ProtocolHandler.LoginResult.Success)
{ {
Console.WriteLine("Connecting to Minecraft.net..."); Translations.WriteLine("mcc.connecting");
result = ProtocolHandler.GetLogin(Settings.Login, Settings.Password, out session); result = ProtocolHandler.GetLogin(Settings.Login, Settings.Password, out session);
if (result == ProtocolHandler.LoginResult.Success && Settings.SessionCaching != CacheType.None) if (result == ProtocolHandler.LoginResult.Success && Settings.SessionCaching != CacheType.None)
@ -220,13 +223,13 @@ namespace MinecraftClient
ConsoleIcon.setPlayerIconAsync(Settings.Username); ConsoleIcon.setPlayerIconAsync(Settings.Username);
if (Settings.DebugMessages) if (Settings.DebugMessages)
Console.WriteLine("Success. (session ID: " + session.ID + ')'); Translations.WriteLine("debug.session_id", session.ID);
//ProtocolHandler.RealmsListWorlds(Settings.Username, PlayerID, sessionID); //TODO REMOVE //ProtocolHandler.RealmsListWorlds(Settings.Username, PlayerID, sessionID); //TODO REMOVE
if (Settings.ServerIP == "") if (Settings.ServerIP == "")
{ {
Console.Write("Server IP : "); Translations.Write("mcc.ip");
Settings.SetServerIP(Console.ReadLine()); Settings.SetServerIP(Console.ReadLine());
} }
@ -240,9 +243,9 @@ namespace MinecraftClient
if (protocolversion != 0) if (protocolversion != 0)
{ {
ConsoleIO.WriteLineFormatted("§8Using Minecraft version " + Settings.ServerVersion + " (protocol v" + protocolversion + ')'); ConsoleIO.WriteLineFormatted(Translations.Get("mcc.use_version", Settings.ServerVersion, protocolversion));
} }
else ConsoleIO.WriteLineFormatted("§8Unknown or not supported MC version '" + Settings.ServerVersion + "'.\nSwitching to autodetection mode."); else ConsoleIO.WriteLineFormatted(Translations.Get("mcc.unknown_version", Settings.ServerVersion));
if (useMcVersionOnce) if (useMcVersionOnce)
{ {
@ -254,11 +257,11 @@ namespace MinecraftClient
if (protocolversion == 0 || Settings.ServerMayHaveForge) if (protocolversion == 0 || Settings.ServerMayHaveForge)
{ {
if (protocolversion != 0) if (protocolversion != 0)
Console.WriteLine("Checking if server is running Forge..."); Translations.WriteLine("mcc.forge");
else Console.WriteLine("Retrieving Server Info..."); else Translations.WriteLine("mcc.retrieve");
if (!ProtocolHandler.GetServerInfo(Settings.ServerIP, Settings.ServerPort, ref protocolversion, ref forgeInfo)) if (!ProtocolHandler.GetServerInfo(Settings.ServerIP, Settings.ServerPort, ref protocolversion, ref forgeInfo))
{ {
HandleFailure("Failed to ping this IP.", true, ChatBots.AutoRelog.DisconnectReason.ConnectionLost); HandleFailure(Translations.Get("error.ping"), true, ChatBots.AutoRelog.DisconnectReason.ConnectionLost);
return; return;
} }
} }
@ -278,29 +281,30 @@ namespace MinecraftClient
if (Settings.ConsoleTitle != "") if (Settings.ConsoleTitle != "")
Console.Title = Settings.ExpandVars(Settings.ConsoleTitle); Console.Title = Settings.ExpandVars(Settings.ConsoleTitle);
} }
catch (NotSupportedException) { HandleFailure("Cannot connect to the server : This version is not supported !", true); } catch (NotSupportedException) { HandleFailure(Translations.Get("error.unsupported"), true); }
} }
else HandleFailure("Failed to determine server version.", true); else HandleFailure(Translations.Get("error.determine"), true);
} }
else else
{ {
string failureMessage = "Minecraft Login failed : "; string failureMessage = Translations.Get("error.login");
string failureReason = "";
switch (result) switch (result)
{ {
case ProtocolHandler.LoginResult.AccountMigrated: failureMessage += "Account migrated, use e-mail as username."; break; case ProtocolHandler.LoginResult.AccountMigrated: failureReason = "error.login.migrated"; break;
case ProtocolHandler.LoginResult.ServiceUnavailable: failureMessage += "Login servers are unavailable. Please try again later."; break; case ProtocolHandler.LoginResult.ServiceUnavailable: failureReason = "error.login.server"; break;
case ProtocolHandler.LoginResult.WrongPassword: failureMessage += "Incorrect password, blacklisted IP or too many logins."; break; case ProtocolHandler.LoginResult.WrongPassword: failureReason = "error.login.blocked"; break;
case ProtocolHandler.LoginResult.InvalidResponse: failureMessage += "Invalid server response."; break; case ProtocolHandler.LoginResult.InvalidResponse: failureReason = "error.login.response"; break;
case ProtocolHandler.LoginResult.NotPremium: failureMessage += "User not premium."; break; case ProtocolHandler.LoginResult.NotPremium: failureReason = "error.login.premium"; break;
case ProtocolHandler.LoginResult.OtherError: failureMessage += "Network error."; break; case ProtocolHandler.LoginResult.OtherError: failureReason = "error.login.network"; break;
case ProtocolHandler.LoginResult.SSLError: failureMessage += "SSL Error."; break; case ProtocolHandler.LoginResult.SSLError: failureReason = "error.login.ssl"; break;
default: failureMessage += "Unknown Error."; break; default: failureReason = "error.login.unknown"; break;
} }
failureMessage += Translations.Get(failureReason);
if (result == ProtocolHandler.LoginResult.SSLError && isUsingMono) if (result == ProtocolHandler.LoginResult.SSLError && isUsingMono)
{ {
ConsoleIO.WriteLineFormatted("§8It appears that you are using Mono to run this program." Translations.WriteLineFormatted("error.login.ssl_help");
+ '\n' + "The first time, you have to import HTTPS certificates using:"
+ '\n' + "mozroots --import --ask-remove");
return; return;
} }
HandleFailure(failureMessage, false, ChatBot.DisconnectReason.LoginRejected); HandleFailure(failureMessage, false, ChatBot.DisconnectReason.LoginRejected);
@ -319,10 +323,10 @@ namespace MinecraftClient
if (offlinePrompt != null) { offlinePrompt.Abort(); offlinePrompt = null; ConsoleIO.Reset(); } if (offlinePrompt != null) { offlinePrompt.Abort(); offlinePrompt = null; ConsoleIO.Reset(); }
if (delaySeconds > 0) if (delaySeconds > 0)
{ {
Console.WriteLine("Waiting " + delaySeconds + " seconds before restarting..."); Translations.WriteLine("mcc.restart_delay", delaySeconds);
System.Threading.Thread.Sleep(delaySeconds * 1000); System.Threading.Thread.Sleep(delaySeconds * 1000);
} }
Console.WriteLine("Restarting Minecraft Console Client..."); Translations.WriteLine("mcc.restart");
InitializeClient(); InitializeClient();
})).Start(); })).Start();
} }
@ -368,7 +372,7 @@ namespace MinecraftClient
{ {
if (versionError) if (versionError)
{ {
Console.Write("Server version : "); Translations.Write("mcc.server_version");
Settings.ServerVersion = Console.ReadLine(); Settings.ServerVersion = Console.ReadLine();
if (Settings.ServerVersion != "") if (Settings.ServerVersion != "")
{ {
@ -383,8 +387,8 @@ namespace MinecraftClient
offlinePrompt = new Thread(new ThreadStart(delegate offlinePrompt = new Thread(new ThreadStart(delegate
{ {
string command = " "; string command = " ";
ConsoleIO.WriteLineFormatted("Not connected to any server. Use '" + (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar) + "help' for help."); ConsoleIO.WriteLineFormatted(Translations.Get("mcc.disconnected", (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar)));
ConsoleIO.WriteLineFormatted("Or press Enter to exit Minecraft Console Client."); Translations.WriteLineFormatted("mcc.press_exit");
while (command.Length > 0) while (command.Length > 0)
{ {
if (!ConsoleIO.BasicIO) if (!ConsoleIO.BasicIO)
@ -414,10 +418,10 @@ namespace MinecraftClient
} }
else if (command.StartsWith("help")) else if (command.StartsWith("help"))
{ {
ConsoleIO.WriteLineFormatted("§8MCC: " + (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar) + new Commands.Reco().CMDDesc); ConsoleIO.WriteLineFormatted("§8MCC: " + (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar) + new Commands.Reco().GetCmdDescTranslated());
ConsoleIO.WriteLineFormatted("§8MCC: " + (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar) + new Commands.Connect().CMDDesc); ConsoleIO.WriteLineFormatted("§8MCC: " + (Settings.internalCmdChar == ' ' ? "" : "" + Settings.internalCmdChar) + new Commands.Connect().GetCmdDescTranslated());
} }
else ConsoleIO.WriteLineFormatted("§8Unknown command '" + command.Split(' ')[0] + "'."); else ConsoleIO.WriteLineFormatted(Translations.Get("icmd.unknown", command.Split(' ')[0]));
if (message != "") if (message != "")
ConsoleIO.WriteLineFormatted("§8MCC: " + message); ConsoleIO.WriteLineFormatted("§8MCC: " + message);

View file

@ -92,7 +92,7 @@ namespace MinecraftClient.Protocol
//File not found? Try downloading language file from Mojang's servers? //File not found? Try downloading language file from Mojang's servers?
if (!System.IO.File.Exists(Language_File)) if (!System.IO.File.Exists(Language_File))
{ {
ConsoleIO.WriteLineFormatted("§8Downloading '" + Settings.Language + ".lang' from Mojang servers..."); ConsoleIO.WriteLineFormatted(Translations.Get("chat.download", Settings.Language));
try try
{ {
string assets_index = DownloadString(Settings.TranslationsFile_Website_Index); string assets_index = DownloadString(Settings.TranslationsFile_Website_Index);
@ -101,7 +101,7 @@ namespace MinecraftClient.Protocol
string hash = tmp[1].Split('"')[0]; //Translations file identifier on Mojang's servers string hash = tmp[1].Split('"')[0]; //Translations file identifier on Mojang's servers
string translation_file_location = Settings.TranslationsFile_Website_Download + '/' + hash.Substring(0, 2) + '/' + hash; string translation_file_location = Settings.TranslationsFile_Website_Download + '/' + hash.Substring(0, 2) + '/' + hash;
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Performing request to " + translation_file_location); ConsoleIO.WriteLineFormatted(Translations.Get("chat.request", translation_file_location));
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
foreach (KeyValuePair<string, Json.JSONData> entry in Json.ParseJson(DownloadString(translation_file_location)).Properties) foreach (KeyValuePair<string, Json.JSONData> entry in Json.ParseJson(DownloadString(translation_file_location)).Properties)
@ -110,11 +110,11 @@ namespace MinecraftClient.Protocol
} }
System.IO.File.WriteAllText(Language_File, stringBuilder.ToString()); System.IO.File.WriteAllText(Language_File, stringBuilder.ToString());
ConsoleIO.WriteLineFormatted("§8Done. File saved as '" + Language_File + '\''); ConsoleIO.WriteLineFormatted(Translations.Get("chat.done", Language_File));
} }
catch catch
{ {
ConsoleIO.WriteLineFormatted("§8Failed to download the file."); Translations.WriteLineFormatted("chat.fail");
} }
} }
@ -123,7 +123,7 @@ namespace MinecraftClient.Protocol
&& System.IO.File.Exists(Settings.TranslationsFile_FromMCDir)) && System.IO.File.Exists(Settings.TranslationsFile_FromMCDir))
{ {
Language_File = Settings.TranslationsFile_FromMCDir; Language_File = Settings.TranslationsFile_FromMCDir;
ConsoleIO.WriteLineFormatted("§8Defaulting to en_GB.lang from your Minecraft directory."); Translations.WriteLineFormatted("chat.from_dir");
} }
//Load the external dictionnary of translation rules or display an error message //Load the external dictionnary of translation rules or display an error message
@ -143,12 +143,11 @@ namespace MinecraftClient.Protocol
} }
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Translations file loaded."); Translations.WriteLineFormatted("chat.loaded");
} }
else //No external dictionnary found. else //No external dictionnary found.
{ {
ConsoleIO.WriteLineFormatted("§8Translations file not found: \"" + Language_File + "\"" ConsoleIO.WriteLineFormatted(Translations.Get("chat.not_found", Language_File));
+ "\nSome messages won't be properly printed without this file.");
} }
} }

View file

@ -40,7 +40,7 @@ namespace MinecraftClient.Protocol.Handlers
public PacketTypePalette GetTypeHandler(int protocol) public PacketTypePalette GetTypeHandler(int protocol)
{ {
if (protocol > Protocol18Handler.MC1163Version) if (protocol > Protocol18Handler.MC1163Version)
throw new NotImplementedException("Please update packet type palette for this Minecraft version. See PacketTypePalette.cs"); throw new NotImplementedException(Translations.Get("exception.palette.packet"));
if (protocol <= Protocol18Handler.MC18Version) if (protocol <= Protocol18Handler.MC18Version)
return new PacketPalette17(); return new PacketPalette17();
else if (protocol <= Protocol18Handler.MC1112Version) else if (protocol <= Protocol18Handler.MC1112Version)

View file

@ -38,19 +38,19 @@ namespace MinecraftClient.Protocol.Handlers
if (Handler.GetTerrainEnabled()) if (Handler.GetTerrainEnabled())
{ {
ConsoleIO.WriteLineFormatted("§cTerrain & Movements currently not handled for that MC version."); Translations.WriteLineFormatted("extra.terrainandmovement_disabled");
Handler.SetTerrainEnabled(false); Handler.SetTerrainEnabled(false);
} }
if (handler.GetInventoryEnabled()) if (handler.GetInventoryEnabled())
{ {
ConsoleIO.WriteLineFormatted("§cInventories are currently not handled for that MC version."); Translations.WriteLineFormatted("extra.inventory_disabled");
handler.SetInventoryEnabled(false); handler.SetInventoryEnabled(false);
} }
if (handler.GetEntityHandlingEnabled()) if (handler.GetEntityHandlingEnabled())
{ {
ConsoleIO.WriteLineFormatted("§cEntities are currently not handled for that MC version."); Translations.WriteLineFormatted("extra.entity_disabled");
handler.SetEntityHandlingEnabled(false); handler.SetEntityHandlingEnabled(false);
} }
} }
@ -167,7 +167,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x84: readData(11); nbr = readNextShort(); if (nbr > 0) { readData(nbr); } break; case 0x84: readData(11); nbr = readNextShort(); if (nbr > 0) { readData(nbr); } break;
case 0x85: if (protocolversion >= 74) { readData(13); } break; case 0x85: if (protocolversion >= 74) { readData(13); } break;
case 0xC8: case 0xC8:
if (readNextInt() == 2022) { ConsoleIO.WriteLogLine("You are dead. Type /respawn to respawn."); } if (readNextInt() == 2022) { Translations.WriteLogLine("mcc.player_dead"); }
if (protocolversion >= 72) { readData(4); } else readData(1); if (protocolversion >= 72) { readData(4); } else readData(1);
break; break;
case 0xC9: case 0xC9:
@ -468,15 +468,15 @@ namespace MinecraftClient.Protocol.Handlers
byte[] token = readNextByteArray(); byte[] token = readNextByteArray();
if (serverID == "-") if (serverID == "-")
ConsoleIO.WriteLineFormatted("§8Server is in offline mode."); Translations.WriteLineFormatted("mcc.server_offline");
else if (Settings.DebugMessages) else if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Handshake successful. (Server ID: " + serverID + ')'); ConsoleIO.WriteLineFormatted(Translations.Get("mcc.handshake", serverID));
return StartEncryption(uuid, username, sessionID, token, serverID, PublicServerkey); return StartEncryption(uuid, username, sessionID, token, serverID, PublicServerkey);
} }
else else
{ {
ConsoleIO.WriteLineFormatted("§8Invalid response to Handshake packet"); Translations.WriteLineFormatted("error.invalid_response");
return false; return false;
} }
} }
@ -487,14 +487,14 @@ namespace MinecraftClient.Protocol.Handlers
byte[] secretKey = CryptoHandler.GenerateAESPrivateKey(); byte[] secretKey = CryptoHandler.GenerateAESPrivateKey();
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Crypto keys & hash generated."); Translations.WriteLineFormatted("debug.crypto");
if (serverIDhash != "-") if (serverIDhash != "-")
{ {
Console.WriteLine("Checking Session..."); Translations.WriteLine("mcc.session");
if (!ProtocolHandler.SessionCheck(uuid, sessionID, CryptoHandler.getServerHash(serverIDhash, serverKey, secretKey))) if (!ProtocolHandler.SessionCheck(uuid, sessionID, CryptoHandler.getServerHash(serverIDhash, serverKey, secretKey)))
{ {
handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, "Failed to check session."); handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, Translations.Get("mcc.session_fail"));
return false; return false;
} }
} }
@ -531,7 +531,7 @@ namespace MinecraftClient.Protocol.Handlers
} }
else else
{ {
ConsoleIO.WriteLineFormatted("§8Invalid response to StartEncryption packet"); Translations.WriteLineFormatted("error.invalid_encrypt");
return false; return false;
} }
} }
@ -837,7 +837,7 @@ namespace MinecraftClient.Protocol.Handlers
version = "B1.8.1 - 1.3.2"; version = "B1.8.1 - 1.3.2";
} }
ConsoleIO.WriteLineFormatted("§8Server version : MC " + version + " (protocol v" + protocolversion + ")."); ConsoleIO.WriteLineFormatted(Translations.Get("mcc.use_version", version, protocolversion));
return true; return true;
} }

View file

@ -81,19 +81,19 @@ namespace MinecraftClient.Protocol.Handlers
if (handler.GetTerrainEnabled() && protocolversion > MC1152Version) if (handler.GetTerrainEnabled() && protocolversion > MC1152Version)
{ {
ConsoleIO.WriteLineFormatted("§cTerrain & Movements currently not handled for that MC version."); Translations.WriteLineFormatted("extra.terrainandmovement_disabled");
handler.SetTerrainEnabled(false); handler.SetTerrainEnabled(false);
} }
if (handler.GetInventoryEnabled() && (protocolversion < MC110Version || protocolversion > MC1163Version)) if (handler.GetInventoryEnabled() && (protocolversion < MC110Version || protocolversion > MC1163Version))
{ {
ConsoleIO.WriteLineFormatted("§cInventories are currently not handled for that MC version."); Translations.WriteLineFormatted("extra.inventory_disabled");
handler.SetInventoryEnabled(false); handler.SetInventoryEnabled(false);
} }
if (handler.GetEntityHandlingEnabled() && (protocolversion < MC110Version || protocolversion > MC1163Version)) if (handler.GetEntityHandlingEnabled() && (protocolversion < MC110Version || protocolversion > MC1163Version))
{ {
ConsoleIO.WriteLineFormatted("§cEntities are currently not handled for that MC version."); Translations.WriteLineFormatted("extra.entity_disabled");
handler.SetEntityHandlingEnabled(false); handler.SetEntityHandlingEnabled(false);
} }
@ -101,7 +101,7 @@ namespace MinecraftClient.Protocol.Handlers
if (protocolversion >= MC113Version) if (protocolversion >= MC113Version)
{ {
if (protocolVersion > MC1152Version && handler.GetTerrainEnabled()) if (protocolVersion > MC1152Version && handler.GetTerrainEnabled())
throw new NotImplementedException("Please update block types handling for this Minecraft version. See Material.cs"); throw new NotImplementedException(Translations.Get("exception.palette.block"));
if (protocolVersion >= MC115Version) if (protocolVersion >= MC115Version)
Block.Palette = new Palette115(); Block.Palette = new Palette115();
else if (protocolVersion >= MC114Version) else if (protocolVersion >= MC114Version)
@ -114,7 +114,7 @@ namespace MinecraftClient.Protocol.Handlers
if (protocolversion >= MC113Version) if (protocolversion >= MC113Version)
{ {
if (protocolversion > MC1163Version && handler.GetEntityHandlingEnabled()) if (protocolversion > MC1163Version && handler.GetEntityHandlingEnabled())
throw new NotImplementedException("Please update entity types handling for this Minecraft version. See EntityType.cs"); throw new NotImplementedException(Translations.Get("exception.palette.entity"));
if (protocolversion >= MC1162Version) if (protocolversion >= MC1162Version)
entityPalette = new EntityPalette1162(); entityPalette = new EntityPalette1162();
else if (protocolversion >= MC116Version) else if (protocolversion >= MC116Version)
@ -131,7 +131,7 @@ namespace MinecraftClient.Protocol.Handlers
if (protocolversion >= MC116Version) if (protocolversion >= MC116Version)
{ {
if (protocolversion > MC1163Version && handler.GetInventoryEnabled()) if (protocolversion > MC1163Version && handler.GetInventoryEnabled())
throw new NotImplementedException("Please update item types handling for this Minecraft version. See ItemType.cs"); throw new NotImplementedException(Translations.Get("exception.palette.item"));
if (protocolversion >= MC1162Version) if (protocolversion >= MC1162Version)
itemPalette = new ItemPalette1162(); itemPalette = new ItemPalette1162();
else itemPalette = new ItemPalette1161(); else itemPalette = new ItemPalette1161();
@ -1004,7 +1004,7 @@ namespace MinecraftClient.Protocol.Handlers
if (innerException is ThreadAbortException || innerException is SocketException || innerException.InnerException is SocketException) if (innerException is ThreadAbortException || innerException is SocketException || innerException.InnerException is SocketException)
throw; //Thread abort or Connection lost rather than invalid data throw; //Thread abort or Connection lost rather than invalid data
throw new System.IO.InvalidDataException( throw new System.IO.InvalidDataException(
String.Format("Failed to process incoming packet of type {0}. (PacketID: {1}, Protocol: {2}, LoginPhase: {3}, InnerException: {4}).", Translations.Get("exception.packet_process",
packetPalette.GetIncommingTypeById(packetID), packetPalette.GetIncommingTypeById(packetID),
packetID, packetID,
protocolversion, protocolversion,
@ -1120,12 +1120,12 @@ namespace MinecraftClient.Protocol.Handlers
} }
else if (packetID == 0x02) //Login successful else if (packetID == 0x02) //Login successful
{ {
ConsoleIO.WriteLineFormatted("§8Server is in offline mode."); Translations.WriteLineFormatted("mcc.server_offline");
login_phase = false; login_phase = false;
if (!pForge.CompleteForgeHandshake()) if (!pForge.CompleteForgeHandshake())
{ {
ConsoleIO.WriteLineFormatted("§8Forge Login Handshake did not complete successfully"); Translations.WriteLineFormatted("error.forge");
return false; return false;
} }
@ -1146,14 +1146,14 @@ namespace MinecraftClient.Protocol.Handlers
byte[] secretKey = CryptoHandler.GenerateAESPrivateKey(); byte[] secretKey = CryptoHandler.GenerateAESPrivateKey();
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Crypto keys & hash generated."); Translations.WriteLineFormatted("debug.crypto");
if (serverIDhash != "-") if (serverIDhash != "-")
{ {
Console.WriteLine("Checking Session..."); Translations.WriteLine("mcc.session");
if (!ProtocolHandler.SessionCheck(uuid, sessionID, CryptoHandler.getServerHash(serverIDhash, serverKey, secretKey))) if (!ProtocolHandler.SessionCheck(uuid, sessionID, CryptoHandler.getServerHash(serverIDhash, serverKey, secretKey)))
{ {
handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, "Failed to check session."); handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, Translations.Get("mcc.session_fail"));
return false; return false;
} }
} }
@ -1185,7 +1185,7 @@ namespace MinecraftClient.Protocol.Handlers
if (!pForge.CompleteForgeHandshake()) if (!pForge.CompleteForgeHandshake())
{ {
ConsoleIO.WriteLineFormatted("§8Forge StartEncryption Handshake did not complete successfully"); Translations.WriteLineFormatted("error.forge_encrypt");
return false; return false;
} }
@ -1321,7 +1321,7 @@ namespace MinecraftClient.Protocol.Handlers
// Check for forge on the server. // Check for forge on the server.
Protocol18Forge.ServerInfoCheckForge(jsonData, ref forgeInfo); Protocol18Forge.ServerInfoCheckForge(jsonData, ref forgeInfo);
ConsoleIO.WriteLineFormatted("§8Server version : " + version + " (protocol v" + protocolversion + (forgeInfo != null ? ", with Forge)." : ").")); ConsoleIO.WriteLineFormatted(Translations.Get("mcc.server_protocol", version, protocolversion + (forgeInfo != null ? Translations.Get("mcc.with_forge") : "")));
return true; return true;
} }

View file

@ -134,7 +134,7 @@ namespace MinecraftClient.Protocol.Handlers
byte fmlProtocolVersion = dataTypes.ReadNextByte(packetData); byte fmlProtocolVersion = dataTypes.ReadNextByte(packetData);
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Forge protocol version : " + fmlProtocolVersion); ConsoleIO.WriteLineFormatted(Translations.Get("forge.version", fmlProtocolVersion));
if (fmlProtocolVersion >= 1) if (fmlProtocolVersion >= 1)
currentDimension = dataTypes.ReadNextInt(packetData); currentDimension = dataTypes.ReadNextInt(packetData);
@ -144,7 +144,7 @@ namespace MinecraftClient.Protocol.Handlers
// Then tell the server that we're running the same mods. // Then tell the server that we're running the same mods.
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Sending falsified mod list to server..."); Translations.WriteLineFormatted("forge.send_mod");
byte[][] mods = new byte[forgeInfo.Mods.Count][]; byte[][] mods = new byte[forgeInfo.Mods.Count][];
for (int i = 0; i < forgeInfo.Mods.Count; i++) for (int i = 0; i < forgeInfo.Mods.Count; i++)
{ {
@ -164,7 +164,7 @@ namespace MinecraftClient.Protocol.Handlers
Thread.Sleep(2000); Thread.Sleep(2000);
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Accepting server mod list..."); Translations.WriteLineFormatted("forge.accept");
// Tell the server that yes, we are OK with the mods it has // Tell the server that yes, we are OK with the mods it has
// even though we don't actually care what mods it has. // even though we don't actually care what mods it has.
@ -186,7 +186,7 @@ namespace MinecraftClient.Protocol.Handlers
int registrySize = dataTypes.ReadNextVarInt(packetData); int registrySize = dataTypes.ReadNextVarInt(packetData);
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Received registry with " + registrySize + " entries"); ConsoleIO.WriteLineFormatted(Translations.Get("forge.registry", registrySize));
fmlHandshakeState = FMLHandshakeClientState.PENDINGCOMPLETE; fmlHandshakeState = FMLHandshakeClientState.PENDINGCOMPLETE;
} }
@ -198,7 +198,7 @@ namespace MinecraftClient.Protocol.Handlers
string registryName = dataTypes.ReadNextString(packetData); string registryName = dataTypes.ReadNextString(packetData);
int registrySize = dataTypes.ReadNextVarInt(packetData); int registrySize = dataTypes.ReadNextVarInt(packetData);
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Received registry " + registryName + " with " + registrySize + " entries"); ConsoleIO.WriteLineFormatted(Translations.Get("forge.registry_2", registryName, registrySize));
if (!hasNextRegistry) if (!hasNextRegistry)
fmlHandshakeState = FMLHandshakeClientState.PENDINGCOMPLETE; fmlHandshakeState = FMLHandshakeClientState.PENDINGCOMPLETE;
} }
@ -210,7 +210,7 @@ namespace MinecraftClient.Protocol.Handlers
if (discriminator != FMLHandshakeDiscriminator.HandshakeAck) if (discriminator != FMLHandshakeDiscriminator.HandshakeAck)
return false; return false;
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Accepting server registries..."); Translations.WriteLineFormatted("forge.accept_registry");
SendForgeHandshakePacket(FMLHandshakeDiscriminator.HandshakeAck, SendForgeHandshakePacket(FMLHandshakeDiscriminator.HandshakeAck,
new byte[] { (byte)FMLHandshakeClientState.PENDINGCOMPLETE }); new byte[] { (byte)FMLHandshakeClientState.PENDINGCOMPLETE });
fmlHandshakeState = FMLHandshakeClientState.COMPLETE; fmlHandshakeState = FMLHandshakeClientState.COMPLETE;
@ -224,7 +224,7 @@ namespace MinecraftClient.Protocol.Handlers
SendForgeHandshakePacket(FMLHandshakeDiscriminator.HandshakeAck, SendForgeHandshakePacket(FMLHandshakeDiscriminator.HandshakeAck,
new byte[] { (byte)FMLHandshakeClientState.COMPLETE }); new byte[] { (byte)FMLHandshakeClientState.COMPLETE });
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLine("Forge server connection complete!"); Translations.WriteLine("forge.complete");
fmlHandshakeState = FMLHandshakeClientState.DONE; fmlHandshakeState = FMLHandshakeClientState.DONE;
return true; return true;
} }
@ -304,7 +304,7 @@ namespace MinecraftClient.Protocol.Handlers
// [1]: Version is usually set to "FML2" for FML stuff and "1" for mods // [1]: Version is usually set to "FML2" for FML stuff and "1" for mods
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Received FML2 Server Mod List"); Translations.WriteLineFormatted("forge.fml2.mod");
List<string> mods = new List<string>(); List<string> mods = new List<string>();
int modCount = dataTypes.ReadNextVarInt(packetData); int modCount = dataTypes.ReadNextVarInt(packetData);
@ -336,7 +336,7 @@ namespace MinecraftClient.Protocol.Handlers
// In MCC, we just want to send a valid response so we'll reply back with data collected from the server. // In MCC, we just want to send a valid response so we'll reply back with data collected from the server.
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Sending back FML2 Client Mod List"); Translations.WriteLineFormatted("forge.fml2.mod_send");
// Packet ID 2: Client to Server Mod List // Packet ID 2: Client to Server Mod List
fmlResponsePacket.AddRange(dataTypes.GetVarInt(2)); fmlResponsePacket.AddRange(dataTypes.GetVarInt(2));
@ -374,7 +374,7 @@ namespace MinecraftClient.Protocol.Handlers
if (Settings.DebugMessages) if (Settings.DebugMessages)
{ {
string registryName = dataTypes.ReadNextString(packetData); string registryName = dataTypes.ReadNextString(packetData);
ConsoleIO.WriteLineFormatted("§8Acknowledging FML2 Server Registry: " + registryName); ConsoleIO.WriteLineFormatted(Translations.Get("forge.fml2.registry", registryName));
} }
fmlResponsePacket.AddRange(dataTypes.GetVarInt(99)); fmlResponsePacket.AddRange(dataTypes.GetVarInt(99));
@ -393,7 +393,7 @@ namespace MinecraftClient.Protocol.Handlers
if (Settings.DebugMessages) if (Settings.DebugMessages)
{ {
string configName = dataTypes.ReadNextString(packetData); string configName = dataTypes.ReadNextString(packetData);
ConsoleIO.WriteLineFormatted("§8Acknowledging FML2 Server Config: " + configName); ConsoleIO.WriteLineFormatted(Translations.Get("forge.fml2.config", configName));
} }
fmlResponsePacket.AddRange(dataTypes.GetVarInt(99)); fmlResponsePacket.AddRange(dataTypes.GetVarInt(99));
@ -402,7 +402,7 @@ namespace MinecraftClient.Protocol.Handlers
default: default:
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Got Unknown FML2 Handshake message no. " + packetID); ConsoleIO.WriteLineFormatted(Translations.Get("forge.fml2.unknown", packetID));
break; break;
} }
@ -418,7 +418,7 @@ namespace MinecraftClient.Protocol.Handlers
} }
else if (Settings.DebugMessages) else if (Settings.DebugMessages)
{ {
ConsoleIO.WriteLineFormatted("§8Ignoring Unknown FML2 LoginMessage channel: " + fmlChannel); ConsoleIO.WriteLineFormatted(Translations.Get("forge.fml2.unknown_channel", fmlChannel));
} }
} }
return false; return false;
@ -483,10 +483,10 @@ namespace MinecraftClient.Protocol.Handlers
forgeInfo = new ForgeInfo(modData, fmlVersion); forgeInfo = new ForgeInfo(modData, fmlVersion);
if (forgeInfo.Mods.Any()) if (forgeInfo.Mods.Any())
{ {
ConsoleIO.WriteLineFormatted(String.Format("§8Server is running Forge with {0} mods.", forgeInfo.Mods.Count)); ConsoleIO.WriteLineFormatted(Translations.Get("forge.with_mod", forgeInfo.Mods.Count));
if (Settings.DebugMessages) if (Settings.DebugMessages)
{ {
ConsoleIO.WriteLineFormatted("§8Mod list:"); Translations.WriteLineFormatted("forge.mod_list");
foreach (ForgeInfo.ForgeMod mod in forgeInfo.Mods) foreach (ForgeInfo.ForgeMod mod in forgeInfo.Mods)
ConsoleIO.WriteLineFormatted("§8 " + mod.ToString()); ConsoleIO.WriteLineFormatted("§8 " + mod.ToString());
} }
@ -494,7 +494,7 @@ namespace MinecraftClient.Protocol.Handlers
} }
else else
{ {
ConsoleIO.WriteLineFormatted("§8Server is running Forge without mods."); Translations.WriteLineFormatted("forge.no_mod");
forgeInfo = null; forgeInfo = null;
} }
} }

View file

@ -39,7 +39,7 @@ namespace MinecraftClient.Protocol
{ {
try try
{ {
Console.WriteLine("Resolving {0}...", domainVal); Translations.WriteLine("mcc.resolve", domainVal);
Heijden.DNS.Response response = new Heijden.DNS.Resolver().Query("_minecraft._tcp." + domainVal, Heijden.DNS.QType.SRV); Heijden.DNS.Response response = new Heijden.DNS.Resolver().Query("_minecraft._tcp." + domainVal, Heijden.DNS.QType.SRV);
Heijden.DNS.RecordSRV[] srvRecords = response.RecordsSRV; Heijden.DNS.RecordSRV[] srvRecords = response.RecordsSRV;
if (srvRecords != null && srvRecords.Any()) if (srvRecords != null && srvRecords.Any())
@ -51,7 +51,7 @@ namespace MinecraftClient.Protocol
.ThenBy(record => Guid.NewGuid()) .ThenBy(record => Guid.NewGuid())
.First(); .First();
string target = result.TARGET.Trim('.'); string target = result.TARGET.Trim('.');
ConsoleIO.WriteLineFormatted(String.Format("§8Found server {0}:{1} for domain {2}", target, result.PORT, domainVal)); ConsoleIO.WriteLineFormatted(Translations.Get("mcc.found", target, result.PORT, domainVal));
domainVal = target; domainVal = target;
portVal = result.PORT; portVal = result.PORT;
foundService = true; foundService = true;
@ -59,7 +59,7 @@ namespace MinecraftClient.Protocol
} }
catch (Exception e) catch (Exception e)
{ {
ConsoleIO.WriteLineFormatted(String.Format("§8Failed to perform SRV lookup for {0}\n{1}: {2}", domainVal, e.GetType().FullName, e.Message)); ConsoleIO.WriteLineFormatted(Translations.Get("mcc.not_found", domainVal, e.GetType().FullName, e.Message));
} }
}, TimeSpan.FromSeconds(Settings.ResolveSrvRecordsShortTimeout ? 10 : 30)); }, TimeSpan.FromSeconds(Settings.ResolveSrvRecordsShortTimeout ? 10 : 30));
} }
@ -90,7 +90,7 @@ namespace MinecraftClient.Protocol
{ {
success = true; success = true;
} }
else ConsoleIO.WriteLineFormatted("§8Unexpected response from the server (is that a Minecraft server?)"); else Translations.WriteLineFormatted("error.unexpect_response");
} }
catch (Exception e) catch (Exception e)
{ {
@ -99,9 +99,9 @@ namespace MinecraftClient.Protocol
}, TimeSpan.FromSeconds(Settings.ResolveSrvRecordsShortTimeout ? 10 : 30))) }, TimeSpan.FromSeconds(Settings.ResolveSrvRecordsShortTimeout ? 10 : 30)))
{ {
if (protocolversion != 0 && protocolversion != protocolversionTmp) if (protocolversion != 0 && protocolversion != protocolversionTmp)
ConsoleIO.WriteLineFormatted("§8Server reports a different version than manually set. Login may not work."); Translations.WriteLineFormatted("error.version_different");
if (protocolversion == 0 && protocolversionTmp <= 1) if (protocolversion == 0 && protocolversionTmp <= 1)
ConsoleIO.WriteLineFormatted("§8Server does not report its protocol version, autodetection will not work."); Translations.WriteLineFormatted("error.no_version_report");
if (protocolversion == 0) if (protocolversion == 0)
protocolversion = protocolversionTmp; protocolversion = protocolversionTmp;
forgeInfo = forgeInfoTmp; forgeInfo = forgeInfoTmp;
@ -109,7 +109,7 @@ namespace MinecraftClient.Protocol
} }
else else
{ {
ConsoleIO.WriteLineFormatted("§8A timeout occured while attempting to connect to this IP."); Translations.WriteLineFormatted("error.connection_timeout");
return false; return false;
} }
} }
@ -129,7 +129,7 @@ namespace MinecraftClient.Protocol
int[] supportedVersions_Protocol18 = { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, 477, 480, 485, 490, 498, 573, 575, 578, 735, 736, 751, 753 }; int[] supportedVersions_Protocol18 = { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, 477, 480, 485, 490, 498, 573, 575, 578, 735, 736, 751, 753 };
if (Array.IndexOf(supportedVersions_Protocol18, ProtocolVersion) > -1) if (Array.IndexOf(supportedVersions_Protocol18, ProtocolVersion) > -1)
return new Protocol18Handler(Client, ProtocolVersion, Handler, forgeInfo); return new Protocol18Handler(Client, ProtocolVersion, Handler, forgeInfo);
throw new NotSupportedException("The protocol version no." + ProtocolVersion + " is not supported."); throw new NotSupportedException(Translations.Get("exception.version_unsupport", ProtocolVersion));
} }
/// <summary> /// <summary>
@ -359,7 +359,7 @@ namespace MinecraftClient.Protocol
} }
else else
{ {
ConsoleIO.WriteLineFormatted("§8Got error code from server: " + code); ConsoleIO.WriteLineFormatted(Translations.Get("error.http_code", code));
return LoginResult.OtherError; return LoginResult.OtherError;
} }
} }
@ -466,7 +466,7 @@ namespace MinecraftClient.Protocol
} }
else else
{ {
ConsoleIO.WriteLineFormatted("§8Got error code from server while refreshing authentication: " + code); ConsoleIO.WriteLineFormatted(Translations.Get("error.auth", code));
return LoginResult.OtherError; return LoginResult.OtherError;
} }
} }
@ -568,7 +568,7 @@ namespace MinecraftClient.Protocol
try try
{ {
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Performing request to " + host); ConsoleIO.WriteLineFormatted(Translations.Get("debug.request", host));
TcpClient client = ProxyHandler.newTcpClient(host, 443, true); TcpClient client = ProxyHandler.newTcpClient(host, 443, true);
SslStream stream = new SslStream(client.GetStream()); SslStream stream = new SslStream(client.GetStream());

View file

@ -124,7 +124,7 @@ namespace MinecraftClient.Protocol.Session
if (File.Exists(SessionCacheFileMinecraft)) if (File.Exists(SessionCacheFileMinecraft))
{ {
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Loading Minecraft profiles: " + Path.GetFileName(SessionCacheFileMinecraft)); ConsoleIO.WriteLineFormatted(Translations.Get("cache.loading", Path.GetFileName(SessionCacheFileMinecraft)));
Json.JSONData mcSession = new Json.JSONData(Json.JSONData.DataType.String); Json.JSONData mcSession = new Json.JSONData(Json.JSONData.DataType.String);
try try
{ {
@ -158,7 +158,7 @@ namespace MinecraftClient.Protocol.Session
clientID clientID
)); ));
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Loaded session: " + login + ':' + session.ID); ConsoleIO.WriteLineFormatted(Translations.Get("cache.loaded", login, session.ID));
sessions[login] = session; sessions[login] = session;
} }
catch (InvalidDataException) { /* Not a valid session */ } catch (InvalidDataException) { /* Not a valid session */ }
@ -172,7 +172,7 @@ namespace MinecraftClient.Protocol.Session
if (File.Exists(SessionCacheFileSerialized)) if (File.Exists(SessionCacheFileSerialized))
{ {
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Converting session cache from disk: " + SessionCacheFileSerialized); ConsoleIO.WriteLineFormatted(Translations.Get("cache.converting", SessionCacheFileSerialized));
try try
{ {
@ -182,18 +182,18 @@ namespace MinecraftClient.Protocol.Session
foreach (KeyValuePair<string, SessionToken> item in sessionsTemp) foreach (KeyValuePair<string, SessionToken> item in sessionsTemp)
{ {
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Loaded session: " + item.Key + ':' + item.Value.ID); ConsoleIO.WriteLineFormatted(Translations.Get("cache.loaded", item.Key, item.Value.ID));
sessions[item.Key] = item.Value; sessions[item.Key] = item.Value;
} }
} }
} }
catch (IOException ex) catch (IOException ex)
{ {
ConsoleIO.WriteLineFormatted("§8Failed to read serialized session cache from disk: " + ex.Message); ConsoleIO.WriteLineFormatted(Translations.Get("cache.read_fail", ex.Message));
} }
catch (SerializationException ex2) catch (SerializationException ex2)
{ {
ConsoleIO.WriteLineFormatted("§8Got malformed data while reading serialized session cache from disk: " + ex2.Message); ConsoleIO.WriteLineFormatted(Translations.Get("cache.malformed", ex2.Message));
} }
} }
@ -201,7 +201,7 @@ namespace MinecraftClient.Protocol.Session
if (File.Exists(SessionCacheFilePlaintext)) if (File.Exists(SessionCacheFilePlaintext))
{ {
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Loading session cache from disk: " + SessionCacheFilePlaintext); ConsoleIO.WriteLineFormatted(Translations.Get("cache.loading_session", SessionCacheFilePlaintext));
try try
{ {
@ -217,25 +217,25 @@ namespace MinecraftClient.Protocol.Session
string login = keyValue[0].ToLower(); string login = keyValue[0].ToLower();
SessionToken session = SessionToken.FromString(keyValue[1]); SessionToken session = SessionToken.FromString(keyValue[1]);
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Loaded session: " + login + ':' + session.ID); ConsoleIO.WriteLineFormatted(Translations.Get("cache.loaded", login, session.ID));
sessions[login] = session; sessions[login] = session;
} }
catch (InvalidDataException e) catch (InvalidDataException e)
{ {
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Ignoring session token string '" + keyValue[1] + "': " + e.Message); ConsoleIO.WriteLineFormatted(Translations.Get("cache.ignore_string", keyValue[1], e.Message));
} }
} }
else if (Settings.DebugMessages) else if (Settings.DebugMessages)
{ {
ConsoleIO.WriteLineFormatted("§8Ignoring invalid session token line: " + line); ConsoleIO.WriteLineFormatted(Translations.Get("cache.ignore_line", line));
} }
} }
} }
} }
catch (IOException e) catch (IOException e)
{ {
ConsoleIO.WriteLineFormatted("§8Failed to read session cache from disk: " + e.Message); ConsoleIO.WriteLineFormatted(Translations.Get("cache.read_fail_plain", e.Message));
} }
} }
@ -248,7 +248,7 @@ namespace MinecraftClient.Protocol.Session
private static void SaveToDisk() private static void SaveToDisk()
{ {
if (Settings.DebugMessages) if (Settings.DebugMessages)
ConsoleIO.WriteLineFormatted("§8Saving session cache to disk"); Translations.WriteLineFormatted("cache.saving");
List<string> sessionCacheLines = new List<string>(); List<string> sessionCacheLines = new List<string>();
sessionCacheLines.Add("# Generated by MCC v" + Program.Version + " - Edit at own risk!"); sessionCacheLines.Add("# Generated by MCC v" + Program.Version + " - Edit at own risk!");
@ -262,7 +262,7 @@ namespace MinecraftClient.Protocol.Session
} }
catch (IOException e) catch (IOException e)
{ {
ConsoleIO.WriteLineFormatted("§8Failed to write session cache to disk: " + e.Message); ConsoleIO.WriteLineFormatted(Translations.Get("cache.save_fail", e.Message));
} }
} }
} }

View file

@ -52,7 +52,7 @@ namespace MinecraftClient.Proxy
if (!proxy_ok) if (!proxy_ok)
{ {
ConsoleIO.WriteLineFormatted("§8Connected to proxy " + Settings.ProxyHost + ':' + Settings.ProxyPort); ConsoleIO.WriteLineFormatted(Translations.Get("proxy.connected", Settings.ProxyHost, Settings.ProxyPort));
proxy_ok = true; proxy_ok = true;
} }

View file

@ -0,0 +1,167 @@
# Startup Config File
[Main]
# General settings
# Leave blank to prompt user on startup
# Use "-" as password for offline mode
login=
password=
serverip=
# Advanced settings
language=en_GB
consoletitle=%username%@%serverip% - Minecraft Console Client
internalcmdchar=slash # Use 'none', 'slash' or 'backslash'
splitmessagedelay=2 # Seconds between each part of a long message
botowners=Player1,Player2,Player3 # Name list or myfile.txt, one name per line. !Server admins can impersonate owners!
botmessagedelay=2 # Seconds to delay between message a bot makes to avoid accidental spam
mcversion=auto # Use 'auto' or '1.X.X' values
mcforge=auto # Use 'auto' or 'false'
brandinfo=mcc # Use 'mcc','vanilla', or 'none'
chatbotlogfile= # Leave empty for no logfile
privatemsgscmdname=tell # Used by RemoteControl bot
showsystemmessages=true # System messages for server ops
showxpbarmessages=true # Messages displayed above xp bar
showchatlinks=true # Show links embedded in chat messages
terrainandmovements=false # Uses more ram, cpu, bandwidth
inventoryhandling=false # Toggle inventory handling (beta)
entityhandling=false # Toggle entity handling (beta)
sessioncache=disk # How to retain session tokens. Use 'none', 'memory' or 'disk'
resolvesrvrecords=fast # Use 'false', 'fast' (5s timeout), or 'true'. Required for joining some servers.
accountlist=accounts.txt # See README > 'Servers and Accounts file' for more info about this file
serverlist=servers.txt # See README > 'Servers and Accounts file' for more info about this file
playerheadicon=true # Only works on Windows XP-8 or Windows 10 with old console
exitonfailure=false # Disable pauses on error, for using MCC in non-interactive scripts
debugmessages=false # Please enable this before submitting bug reports. Thanks!
scriptcache=true # Cache compiled scripts for faster load on low-end devices
timestamps=false # Prepend timestamps to chat messages
autorespawn=false # Toggle auto respawn if client player was dead (make sure your spawn point is safe)
[AppVars]
# yourvar=yourvalue
# can be used in some other fields as %yourvar%
# %username% and %serverip% are reserved variables.
[Proxy]
enabled=false # Use 'false', 'true', or 'login' for login only
type=HTTP # Supported types: HTTP, SOCKS4, SOCKS4a, SOCKS5
server=0.0.0.0:0000 # Proxy server must allow HTTPS for login, and non-443 ports for playing
username= # Only required for password-protected proxies
password= # Only required for password-protected proxies
[ChatFormat]
# Do not forget to uncomment (remove '#') these settings if modifying them
builtins=true # MCC built-in support for common message formats
# public=^<([a-zA-Z0-9_]+)> (.+)$
# private=^([a-zA-Z0-9_]+) whispers to you: (.+)$
# tprequest=^([a-zA-Z0-9_]+) has requested (?:to|that you) teleport to (?:you|them)\.$
[MCSettings]
enabled=true # If disabled, settings below are not sent to the server
locale=en_US # Use any language implemented in Minecraft
renderdistance=medium # Use tiny, short, medium, far, or chunk amount [0 - 255]
difficulty=normal # MC 1.7- difficulty. peaceful, easy, normal, difficult
chatmode=enabled # Use 'enabled', 'commands', or 'disabled'. Allows to mute yourself...
chatcolors=true # Allows disabling chat colors server-side
main_hand=left # MC 1.9+ main hand. left or right
skin_cape=true
skin_hat=true
skin_jacket=false
skin_sleeve_left=false
skin_sleeve_right=false
skin_pants_left=false
skin_pants_right=false
# Bot Settings
[Alerts]
enabled=false
alertsfile=alerts.txt
excludesfile=alerts-exclude.txt
beeponalert=true
[AntiAFK]
enabled=false
delay=600 #10 = 1s
command=/ping
[AutoRelog]
enabled=false
delay=10
retries=3 #-1 = unlimited
ignorekickmessage=false
kickmessagesfile=kickmessages.txt
[ChatLog]
enabled=false
timestamps=true
filter=messages
logfile=chatlog-%username%-%serverip%.txt
[Hangman]
enabled=false
english=true
wordsfile=hangman-en.txt
fichiermots=hangman-fr.txt
[ScriptScheduler]
enabled=false
tasksfile=tasks.ini
[RemoteControl]
enabled=false
autotpaccept=true
tpaccepteveryone=false
[AutoRespond]
enabled=false
matchesfile=matches.ini
[AutoAttack]
# Entity Handling NEED to be enabled first
enabled=false
mode=single # single or multi. single target one mob per attack. multi target all mobs in range per attack
priority=distance # health or distance. Only needed when using single mode
[AutoFishing]
# Entity Handling NEED to be enabled first
enabled=false
antidespawn=false
[AutoEat]
# Inventory Handling NEED to be enabled first
enabled=false
threshold=6
[AutoCraft]
# Inventory Handling NEED to be enabled first
# Enable terrainandmovements if you need to use crafting table
enabled=false
configfile=autocraft\config.ini
[Mailer]
# Let the bot act like a mail plugin
enabled=false
database=MailerDatabase.ini
ignorelist=MailerIgnoreList.ini
publicinteractions=false
maxmailsperplayer=10
maxdatabasesize=10000
retentiondays=30
[AutoDrop]
# Inventory Handling NEED to be enabled first
enabled=false
mode=include # include, exclude or everything. Include: drop item IN the list. Exclude: drop item NOT IN the list
items= # separate each item with comma ','
# For the naming of the items, please see
# https://github.com/ORelio/Minecraft-Console-Client/blob/master/MinecraftClient/Inventory/ItemType.cs
[ReplayMod]
# Enable recording the game and replay it later using Replay Mod
# You MUST exit the program using /quit command or the replay will NOT be saved!
enabled=false
backupinterval=300 # How long should replay file be auto-saved, in seconds. Use -1 for disabled

View file

@ -0,0 +1,466 @@
[mcc]
# Messages from MCC itself
mcc.login=Login :
mcc.login_basic_io=Please type the username or email of your choice.
mcc.password=Password :
mcc.password_basic_io=Please type the password for {0}.
mcc.password_hidden=Password : {0}
mcc.offline=§8You chose to run in offline mode.
mcc.session_invalid=§8Cached session is invalid or expired.
mcc.session_valid=§8Cached session is still valid for {0}.
mcc.connecting=Connecting to Minecraft.net...
mcc.ip=Server IP :
mcc.use_version=§8Using Minecraft version {0} (protocol v{1})
mcc.unknown_version=§8Unknown or not supported MC version {0}.\nSwitching to autodetection mode.
mcc.forge=Checking if server is running Forge...
mcc.resolve=Resolving {0}...
mcc.found=§8Found server {0}:{1} for domain {2}
mcc.not_found=§8Failed to perform SRV lookup for {0}\n{1}: {2}
mcc.retrieve=Retrieving Server Info...
mcc.restart=Restarting Minecraft Console Client...
mcc.restart_delay=Waiting {0} seconds before restarting...
mcc.server_version=Server version :
mcc.disconnected=Not connected to any server. Use '{0}help' for help.
mcc.press_exit=Or press Enter to exit Minecraft Console Client.
mcc.version_supported=Version is supported.\nLogging in...
mcc.single_cmd=§7Command §8 {0} §7 sent.
mcc.joined=Server was successfully joined.\nType '{0}quit' to leave the server.
mcc.reconnect=Waiting 5 seconds ({0} attempts left)...
mcc.disconnect.lost=Connection has been lost.
mcc.disconnect.server=Disconnected by Server :
mcc.disconnect.login=Login failed :
mcc.link=Link: {0}
mcc.player_dead_respawn=You are dead. Automatically respawning after 1 second.
mcc.player_dead=You are dead. Type /respawn to respawn.
mcc.server_offline=§8Server is in offline mode.
mcc.session=Checking Session...
mcc.session_fail=Failed to check session.
mcc.server_protocol=§8Server version : {0} (protocol v{1})
mcc.with_forge=, with Forge
mcc.handshake=§8Handshake successful. (Server ID: {0})
[debug]
# Messages from MCC Debug Mode
debug.color_test=Color test: Your terminal should display {0}
debug.session_cache_ok=§8Session data has been successfully loaded from disk.
debug.session_cache_fail=§8No sessions could be loaded from disk
debug.session_id=Success. (session ID: {0})
debug.crypto=§8Crypto keys & hash generated.
debug.request=§8Performing request to {0}
[error]
# Error messages from MCC
error.ping=Failed to ping this IP.
error.unsupported=Cannot connect to the server : This version is not supported !
error.determine=Failed to determine server version.
error.login=Minecraft Login failed :
error.login.migrated=Account migrated, use e-mail as username.
error.login.server=Login servers are unavailable. Please try again later.
error.login.blocked=Incorrect password, blacklisted IP or too many logins.
error.login.response=Invalid server response.
error.login.premium=User not premium.
error.login.network=Network error.
error.login.ssl=SSL Error.
error.login.unknown=Unknown Error.
error.login.ssl_help=§8It appears that you are using Mono to run this program.\nThe first time, you have to import HTTPS certificates using:\nmozroots --import --ask-remove
error.login_failed=Failed to login to this server.
error.join=Failed to join this server.
error.connect=Failed to connect to this IP.
error.timeout=Connection Timeout
error.unexpect_response=§8Unexpected response from the server (is that a Minecraft server?)
error.invalid_response=§8Invalid response to Handshake packet
error.invalid_encrypt=§8Invalid response to StartEncryption packet
error.version_different=§8Server reports a different version than manually set. Login may not work.
error.no_version_report=§8Server does not report its protocol version, autodetection will not work.
error.connection_timeout=§8A timeout occured while attempting to connect to this IP.
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.http_code=§8Got error code from server: {0}
error.auth=§8Got error code from server while refreshing authentication: {0}
[internal command]
# MCC internal help command
icmd.help=help <cmdname>: show brief help about a command.
icmd.unknown=Unknown command '{0}'. Use 'help' for command list.
icmd.list=help <cmdname>. Available commands: {0}. For server help, use '{1}send /help' instead.
icmd.error=OnInternalCommand: Got error from {0}: {1}
[exception]
# Exception messages threw by MCC
exception.user_logout=User-initiated logout should be done by calling Disconnect()
exception.unknown_direction=Unknown direction
exception.palette.block=Please update block types handling for this Minecraft version. See Material.cs
exception.palette.entity=Please update entity types handling for this Minecraft version. See EntityType.cs
exception.palette.item=Please update item types handling for this Minecraft version. See ItemType.cs
exception.palette.packet=Please update packet type palette for this Minecraft version. See PacketTypePalette.cs
exception.packet_process=Failed to process incoming packet of type {0}. (PacketID: {1}, Protocol: {2}, LoginPhase: {3}, InnerException: {4}).
exception.version_unsupport=The protocol version no.{0} is not supported.
exception.chatbot.init=ChatBot methods should NOT be called in the constructor as API handler is not initialized yet. Override Initialize() or AfterGameJoined() instead to perform initialization tasks.
exception.csrunner.invalid_head=The provided script does not have a valid MCCScript header
[chatbot]
# ChatBot API
chatbot.reconnect=[{0}] Disconnecting and Reconnecting to the Server
[filemonitor]
# FileMonitor
filemonitor.init=§8[{0}] Initializing FileSystemWatcher for file: {1}
filemonitor.fail=§8[{0}] Failed to initialize FileSystemWatcher, retrying using Polling
[extra]
# Inventory, Terrain & Movements, Entity related messages
# Terrain & Movements
extra.terrainandmovement_enabled=Terrain and Movements is now enabled.
extra.terrainandmovement_disabled=§cTerrain & Movements currently not handled for that MC version.
extra.terrainandmovement_required=Please enable Terrain and Movements in the config file first.
# Inventory
extra.inventory_enabled=Inventory handling is now enabled.
extra.inventory_disabled=§cInventories are currently not handled for that MC version.
extra.inventory_required=Please enable InventoryHandling in the config file first.
extra.inventory_interact=Use /inventory to interact with it.
extra.inventory_open=Inventory # {0} opened: {1}
extra.inventory_close=Inventory # {0} closed.
# Entity
extra.entity_disabled=§cEntities are currently not handled for that MC version.
extra.entity_required=Please enable EntityHandling in the config file first.
[forge]
# Messages from Forge handler
forge.version=§8Forge protocol version : {0}
forge.send_mod=§8Sending falsified mod list to server...
forge.accept=§8Accepting server mod list...
forge.registry=§8Received registry with {0} entries
forge.registry_2=§8Received registry {0} with {1} entries
forge.accept_registry=§8Accepting server registries...
forge.complete=Forge server connection complete!
forge.with_mod=§8Server is running Forge with {0} mods.
forge.no_mod=§8Server is running Forge without mods.
forge.mod_list=§8Mod list:
# FML2
forge.fml2.mod=§8Received FML2 Server Mod List
forge.fml2.mod_send=§8Sending back FML2 Client Mod List
forge.fml2.registry=§8Acknowledging FML2 Server Registry: {0}
forge.fml2.config=§8Acknowledging FML2 Server Config: {0}
forge.fml2.unknown=§8Got Unknown FML2 Handshake message no. {0}
forge.fml2.unknown_channel=§8Ignoring Unknown FML2 LoginMessage channel: {0}
[cache]
# Session Cache
cache.loading=§8Loading Minecraft profiles: {0}
cache.loaded=§8Loaded session: {0}:{1}
cache.converting=§8Converting session cache from disk: {0}
cache.read_fail=§8Failed to read serialized session cache from disk: {0}
cache.malformed=§8Got malformed data while reading serialized session cache from disk: {0}
cache.loading_session=§8Loading session cache from disk: {0}
cache.ignore_string=§8Ignoring session token string '{0}': {1}
cache.ignore_line=§8Ignoring invalid session token line: {0}
cache.read_fail_plain=§8Failed to read session cache from disk: {0}
cache.saving=§8Saving session cache to disk
cache.save_fail=§8Failed to write session cache to disk: {0}
[proxy]
proxy.connected=§8Connected to proxy {0}:{1}
[chat]
# Chat Parser
chat.download=§8Downloading '{0}.lang' from Mojang servers...
chat.request=§8Performing request to {0}
chat.done=§8Done. File saved as '{0}'
chat.fail=§8Failed to download the file.
chat.from_dir=§8Defaulting to en_GB.lang from your Minecraft directory.
chat.loaded=§8Translations file loaded.
chat.not_found=§8Translations file not found: '{0}'\nSome messages won't be properly printed without this file.
[general]
# General message/information (i.e. Done)
general.done=Done
general.fail=Fail
general.bot_unload=This bot will be unloaded.
general.available_cmd=Available commands: {0}
[cmd]
# Commands. Naming style: cmd.<className>.<msg...>
# Animation
cmd.animation.desc=Swing your arm.
# ChangeSlot
cmd.changeSlot.desc=Change hotbar
cmd.changeSlot.nan=Could not change slot: Not a Number
cmd.changeSlot.changed=Changed to slot {0}
cmd.changeSlot.fail=Could not change slot
# Connect
cmd.connect.desc=connect to the specified server.
cmd.connect.unknown=Unknown account '{0}'.
cmd.connect.invalid_ip=Invalid server IP '{0}'.
# Debug
cmd.debug.desc=toggle debug messages.
cmd.debug.state_on=Debug messages are now ON
cmd.debug.state_off=Debug messages are now OFF
# Dig
cmd.dig.desc=attempt to break a block
cmd.dig.too_far=You are too far away from this block.
cmd.dig.no_block=No block at this location (Air)
cmd.dig.dig=Attempting to dig block at {0} {1} {2}
cmd.dig.fail=Failed to start digging block.
# Entitycmd
cmd.entityCmd.attacked=Entity attacked
cmd.entityCmd.used=Entity used
cmd.entityCmd.not_found=Entity not found
cmd.entityCmd.entity=Entity
cmd.entityCmd.entities=Entities
cmd.entityCmd.nickname=Nickname
cmd.entityCmd.customname=Custom Name
cmd.entityCmd.latency=Latency
cmd.entityCmd.item=Item
cmd.entityCmd.equipment=Equipment
cmd.entityCmd.mainhand=Main Hand
cmd.entityCmd.offhane=Off Hand
cmd.entityCmd.helmet=Helmet
cmd.entityCmd.chestplate=Chestplate
cmd.entityCmd.leggings=Leggings
cmd.entityCmd.boots=Boots
cmd.entityCmd.pose=Pose
cmd.entityCmd.health=Health
cmd.entityCmd.distance=Distance
cmd.entityCmd.location=Location
cmd.entityCmd.type=Type
# Exit
cmd.exit.desc=disconnect from the server.
# Health
cmd.health.desc=Display Health and Food saturation.
cmd.health.response=Health: {0}, Saturation: {1}, Level: {2}, TotalExperience: {3}
# Inventory
cmd.inventory.desc=Inventory command
cmd.inventory.creative_done=Requested {0} x{1} in slot #{2}
cmd.inventory.creative_fail=Failed to request Creative Give
cmd.inventory.need_creative=You need Gamemode Creative
cmd.inventory.container_not_found=Cannot find container, please retry with explicit ID
cmd.inventory.close=Closing Inventoy #{0}
cmd.inventory.close_fail=Failed to close Inventory #{0}
cmd.inventory.not_exist=Inventory #{0} do not exist
cmd.inventory.inventory=Inventory
cmd.inventory.inventories=Inventories
cmd.inventory.hotbar=Your selected hotbar is {0}
cmd.inventory.damage=Damage
cmd.inventory.left=Left
cmd.inventory.right=Right
cmd.inventory.middle=Middle
cmd.inventory.clicking={0} clicking slot {1} in window #{2}
cmd.inventory.no_item=No item in slot #{0}
cmd.inventory.drop=Dropped 1 item from slot #{0}
cmd.inventory.drop_stack=Dropped whole item stack from slot #{0}
# Inventory Help
cmd.inventory.help.basic=Basic usage
cmd.inventory.help.available=Available actions
cmd.inventory.help.help=\n{0} Use '/inventory help <action>' for action help.\nCreative mode give: {1}\n'player' and 'container' can be simplified to 'p' and 'c'.\nNote that parameters in '[]' are optional.
cmd.inventory.help.usage=Usage
cmd.inventory.help.list=List your inventory.
cmd.inventory.help.close=Close an opened container.
cmd.inventory.help.click=Click on an item.
cmd.inventory.help.drop=Drop an item from inventory.
cmd.inventory.help.unknown=Unknown action.
# List
cmd.list.desc=get the player list.
cmd.list.players=PlayerList: {0}
# Log
cmd.log.desc=log some text to the console.
# Look
cmd.look.desc=look at direction or coordinates.
cmd.look.unknown=Unknown direction '{0}'
cmd.look.at=Looking at YAW: {0} PITCH: {1}
cmd.look.block=Looking at {0}
# Move
cmd.move.desc=walk or start walking.
cmd.move.enable=Enabling Terrain and Movements on next server login, respawn or world change.
cmd.move.disable=Disabling Terrain and Movements.
cmd.move.moving=Moving {0}
cmd.move.dir_fail=Cannot move in that direction.
cmd.move.walk=Walking to {0}
cmd.move.fail=Failed to compute path to {0}
# Reco
cmd.reco.desc=restart and reconnect to the server.
# Respawn
cmd.respawn.desc=Use this to respawn if you are dead.
cmd.respawn.done=You have respawned.
# Script
cmd.script.desc=run a script file.
# Send
cmd.send.desc=send a chat message or command.
# Set
cmd.set.desc=set a custom %variable%.
cmd.set.format=variable name must be A-Za-z0-9.
# Sneak
cmd.sneak.desc=Toggles sneaking
cmd.sneak.on=You are sneaking now
cmd.sneak.off=You aren't sneaking anymore
# Tps
cmd.tps.desc=Display server current tps (tick per second). May not be accurate
cmd.tps.current=Current tps
# Useblock
cmd.useblock.desc=Place a block or open chest
# Useitem
cmd.useitem.desc=Use (left click) an item on the hand
cmd.useitem.use=Used an item
[bot]
# ChatBots. Naming style: bot.<className>.<msg...>
# AutoAttack
bot.autoAttack.mode=Unknown attack mode: {0}. Using single mode as default.
bot.autoAttack.priority=Unknown priority: {0}. Using distance priority as default.
# AutoCraft
bot.autoCraft.cmd=Auto-crafting ChatBot command
bot.autoCraft.alias=Auto-crafting ChatBot command alias
bot.autoCraft.cmd.list=Total {0} recipes loaded: {1}
bot.autoCraft.cmd.resetcfg=Resetting your config to default
bot.autoCraft.recipe_not_exist=Specified recipe name does not exist. Check your config file.
bot.autoCraft.no_recipe_name=Please specify the recipe name you want to craft.
bot.autoCraft.stop=AutoCraft stopped
bot.autoCraft.available_cmd=Available commands: {0}. Use /autocraft help <cmd name> for more information. You may use /ac as command alias.
bot.autoCraft.help.load=Load the config file.
bot.autoCraft.help.list=List loaded recipes name.
bot.autoCraft.help.reload=Reload the config file.
bot.autoCraft.help.resetcfg=Write the default example config to default location.
bot.autoCraft.help.start=Start the crafting. Usage: /autocraft start <recipe name>
bot.autoCraft.help.stop=Stop the current running crafting process
bot.autoCraft.help.help=Get the command description. Usage: /autocraft help <command name>
bot.autoCraft.loaded=Successfully loaded
bot.autoCraft.start=Starting AutoCraft: {0}
bot.autoCraft.start_fail=AutoCraft cannot be started. Check your available materials for crafting {0}
bot.autoCraft.table_not_found=table not found
bot.autoCraft.close_inventory=Inventory #{0} was closed by AutoCraft
bot.autoCraft.missing_material=Missing material: {0}
bot.autoCraft.aborted=Crafting aborted! Check your available materials.
bot.autoCraft.craft_fail=Crafting failed! Waiting for more materials
bot.autoCraft.timeout=Action timeout! Reason: {0}
bot.autoCraft.error.config=Error while parsing config: {0}
bot.autoCraft.exception.empty=Empty configuration file: {0}
bot.autoCraft.exception.invalid=Invalid configuration file: {0}
bot.autoCraft.exception.item_miss=Missing item in recipe: {0}
bot.autoCraft.exception.invalid_table=Invalid tablelocation format: {0}
bot.autoCraft.exception.item_name=Invalid item name in recipe {0} at {1}
bot.autoCraft.exception.name_miss=Missing recipe name while parsing a recipe
bot.autoCraft.exception.slot=Invalid slot field in recipe: {0}
bot.autoCraft.exception.duplicate=Duplicate recipe name specified: {0}
bot.autoCraft.debug.no_config=No config found. Writing a new one.
# AutoDrop
bot.autoDrop.cmd=AutoDrop ChatBot command
bot.autoDrop.alias=AutoDrop ChatBot command alias
bot.autoDrop.on=AutoDrop enabled
bot.autoDrop.off=AutoDrop disabled
bot.autoDrop.added=Added item {0}
bot.autoDrop.incorrect_name=Incorrect item name {0}. Please try again
bot.autoDrop.removed=Removed item {0}
bot.autoDrop.not_in_list=Item not in the list
bot.autoDrop.no_item=No item in the list
bot.autoDrop.list=Total {0} in the list:\n {1}
# AutoFish
bot.autoFish.throw=Threw a fishing rod
bot.autoFish.caught=Caught a fish!
bot.autoFish.no_rod=No Fishing Rod on hand. Maybe broken?
# AutoRelog
bot.autoRelog.launch=Launching with {0} reconnection attempts
bot.autoRelog.no_kick_msg=Initializing without a kick message file
bot.autoRelog.loading=Loading messages from file: {0}
bot.autoRelog.loaded=Loaded message: {0}
bot.autoRelog.not_found=File not found: {0}
bot.autoRelog.curr_dir=Current directory was: {0}
bot.autoRelog.ignore=Disconnection initiated by User or MCC bot. Ignoring.
bot.autoRelog.disconnect_msg=Got disconnected with message: {0}
bot.autoRelog.reconnect_always=Ignoring kick message, reconnecting anyway.
bot.autoRelog.reconnect=Message contains '{0}'. Reconnecting.
bot.autoRelog.reconnect_ignore=Message not containing any defined keywords. Ignoring.
bot.autoRelog.wait=Waiting {0} seconds before reconnecting...
# ChatLog
bot.chatLog.invalid_file=Path '{0}' contains invalid characters.
# Mailer
bot.mailer.init=Initializing Mailer with settings:
bot.mailer.init.db= - Database File: {0}
bot.mailer.init.ignore= - Ignore List: {0}
bot.mailer.init.public= - Public Interactions: {0}
bot.mailer.init.max_mails= - Max Mails per Player: {0}
bot.mailer.init.db_size= - Max Database Size: {0}
bot.mailer.init.mail_retention= - Mail Retention: {0}
bot.mailer.init_fail.db_size=Cannot enable Mailer: Max Database Size must be greater than zero. Please review the settings.
bot.mailer.init_fail.max_mails=Cannot enable Mailer: Max Mails per Player must be greater than zero. Please review the settings.
bot.mailer.init_fail.mail_retention=Cannot enable Mailer: Mail Retention must be greater than zero. Please review the settings.
bot.mailer.create.db=Creating new database file: {0}
bot.mailer.create.ignore=Creating new ignore list: {0}
bot.mailer.load.db=Loading database file: {0}
bot.mailer.load.ignore=Loading ignore list:
bot.mailer.cmd=mailer command
bot.mailer.saving=Saving message: {0}
bot.mailer.user_ignored={0} is ignored!
bot.mailer.process_mails=Looking for mails to send @ {0}
bot.mailer.delivered=Delivered: {0}
bot.mailer.cmd.getmails=--- Mails in database ---\n{0}
bot.mailer.cmd.getignored=--- Ignore list ---\n{0}
bot.mailer.cmd.ignore.added=Added {0} to the ignore list!
bot.mailer.cmd.ignore.removed=Removed {0} from the ignore list!
bot.mailer.cmd.ignore.invalid=Missing or invalid name. Usage: {0} <username>
bot.mailer.cmd.help=See usage
# ReplayCapture
bot.replayCapture.cmd=replay command
bot.replayCapture.created=Replay file created.
bot.replayCapture.stopped=Record stopped.
bot.replayCapture.restart=Record was stopped. Restart the program to start another record.
# Script
bot.script.not_found=§8[MCC] [{0}] Cannot find script file: {1}
bot.script.file_not_found=File not found: '{0}'
bot.script.fail=Script '{0}' failed to run ({1}).
bot.script.pm.loaded=Script '{0}' loaded.
# ScriptScheduler
bot.scriptScheduler.loading=Loading tasks from '{0}'
bot.scriptScheduler.not_found=File not found: '{0}'
bot.scriptScheduler.loaded_task=Loaded task:\n{0}
bot.scriptScheduler.no_trigger=This task will never trigger:\n{0}
bot.scriptScheduler.no_action=No action for task:\n{0}
bot.scriptScheduler.running_time=Time / Running action: {0}
bot.scriptScheduler.running_inverval=Interval / Running action: {0}
bot.scriptScheduler.running_login=Login / Running action: {0}
bot.scriptScheduler.task=triggeronfirstlogin: {0}\n triggeronlogin: {1}\n triggerontime: {2}\n triggeroninterval: {3}\n timevalue: {4}\n timeinterval: {5}\n action: {6}
# TestBot
bot.testBot.told=Bot: {0} told me : {1}
bot.testBot.said=Bot: {0} said : {1}

View file

@ -204,7 +204,7 @@ namespace MinecraftClient
/// <param name="settingsfile">File to load</param> /// <param name="settingsfile">File to load</param>
public static void LoadSettings(string settingsfile) public static void LoadSettings(string settingsfile)
{ {
ConsoleIO.WriteLogLine(String.Format("[Settings] Loading Settings from {0}", System.IO.Path.GetFullPath(settingsfile))); ConsoleIO.WriteLogLine("[Settings] Loading Settings from " + Path.GetFullPath(settingsfile));
if (File.Exists(settingsfile)) if (File.Exists(settingsfile))
{ {
try try
@ -635,175 +635,8 @@ namespace MinecraftClient
/// <param name="settingsfile">File to (over)write</param> /// <param name="settingsfile">File to (over)write</param>
public static void WriteDefaultSettings(string settingsfile) public static void WriteDefaultSettings(string settingsfile)
{ {
System.IO.File.WriteAllText(settingsfile, "# Minecraft Console Client v" + Program.Version + "\r\n" // Use embedded default config
+ "# Startup Config File\r\n" File.WriteAllText(settingsfile, "# Minecraft Console Client v" + Program.Version + "\r\n" + DefaultConfigResource.MinecraftClient, Encoding.UTF8);
+ "\r\n"
+ "[Main]\r\n"
+ "\r\n"
+ "# General settings\r\n"
+ "# Leave blank to prompt user on startup\r\n"
+ "# Use \"-\" as password for offline mode\r\n"
+ "\r\n"
+ "login=\r\n"
+ "password=\r\n"
+ "serverip=\r\n"
+ "\r\n"
+ "# Advanced settings\r\n"
+ "\r\n"
+ "language=en_GB\r\n"
+ "consoletitle=%username%@%serverip% - Minecraft Console Client\r\n"
+ "internalcmdchar=slash # Use 'none', 'slash' or 'backslash'\r\n"
+ "splitmessagedelay=2 # Seconds between each part of a long message\r\n"
+ "botowners=Player1,Player2,Player3 # Name list or myfile.txt, one name per line. !Server admins can impersonate owners!\r\n"
+ "botmessagedelay=2 # Seconds to delay between message a bot makes to avoid accidental spam\r\n"
+ "mcversion=auto # Use 'auto' or '1.X.X' values\r\n"
+ "mcforge=auto # Use 'auto' or 'false'\r\n"
+ "brandinfo=mcc # Use 'mcc','vanilla', or 'none'\r\n"
+ "chatbotlogfile= # Leave empty for no logfile\r\n"
+ "privatemsgscmdname=tell # Used by RemoteControl bot\r\n"
+ "showsystemmessages=true # System messages for server ops\r\n"
+ "showxpbarmessages=true # Messages displayed above xp bar\r\n"
+ "showchatlinks=true # Show links embedded in chat messages\r\n"
+ "terrainandmovements=false # Uses more ram, cpu, bandwidth\r\n"
+ "inventoryhandling=false # Toggle inventory handling (beta)\r\n"
+ "entityhandling=false # Toggle entity handling (beta)\r\n"
+ "sessioncache=disk # How to retain session tokens. Use 'none', 'memory' or 'disk'\r\n"
+ "resolvesrvrecords=fast # Use 'false', 'fast' (5s timeout), or 'true'. Required for joining some servers.\r\n"
+ "accountlist=accounts.txt # See README > 'Servers and Accounts file' for more info about this file\r\n"
+ "serverlist=servers.txt # See README > 'Servers and Accounts file' for more info about this file\r\n"
+ "playerheadicon=true # Only works on Windows XP-8 or Windows 10 with old console\r\n"
+ "exitonfailure=false # Disable pauses on error, for using MCC in non-interactive scripts\r\n"
+ "debugmessages=false # Please enable this before submitting bug reports. Thanks!\r\n"
+ "scriptcache=true # Cache compiled scripts for faster load on low-end devices\r\n"
+ "timestamps=false # Prepend timestamps to chat messages\r\n"
+ "autorespawn=false # Toggle auto respawn if client player was dead (make sure your spawn point is safe)\r\n"
+ "\r\n"
+ "[AppVars]\r\n"
+ "# yourvar=yourvalue\r\n"
+ "# can be used in some other fields as %yourvar%\r\n"
+ "# %username% and %serverip% are reserved variables.\r\n"
+ "\r\n"
+ "[Proxy]\r\n"
+ "enabled=false # Use 'false', 'true', or 'login' for login only\r\n"
+ "type=HTTP # Supported types: HTTP, SOCKS4, SOCKS4a, SOCKS5\r\n"
+ "server=0.0.0.0:0000 # Proxy server must allow HTTPS for login, and non-443 ports for playing\r\n"
+ "username= # Only required for password-protected proxies\r\n"
+ "password= # Only required for password-protected proxies\r\n"
+ "\r\n"
+ "[ChatFormat]\r\n"
+ "# Do not forget to uncomment (remove '#') these settings if modifying them\r\n"
+ "builtins=true # MCC built-in support for common message formats\r\n"
+ "# public=^<([a-zA-Z0-9_]+)> (.+)$\r\n"
+ "# private=^([a-zA-Z0-9_]+) whispers to you: (.+)$\r\n"
+ "# tprequest=^([a-zA-Z0-9_]+) has requested (?:to|that you) teleport to (?:you|them)\\.$\r\n"
+ "\r\n"
+ "[MCSettings]\r\n"
+ "enabled=true # If disabled, settings below are not sent to the server\r\n"
+ "locale=en_US # Use any language implemented in Minecraft\r\n"
+ "renderdistance=medium # Use tiny, short, medium, far, or chunk amount [0 - 255]\r\n"
+ "difficulty=normal # MC 1.7- difficulty. peaceful, easy, normal, difficult\r\n"
+ "chatmode=enabled # Use 'enabled', 'commands', or 'disabled'. Allows to mute yourself...\r\n"
+ "chatcolors=true # Allows disabling chat colors server-side\r\n"
+ "main_hand=left # MC 1.9+ main hand. left or right\r\n"
+ "skin_cape=true\r\n"
+ "skin_hat=true\r\n"
+ "skin_jacket=false\r\n"
+ "skin_sleeve_left=false\r\n"
+ "skin_sleeve_right=false\r\n"
+ "skin_pants_left=false\r\n"
+ "skin_pants_right=false"
+ "\r\n"
+ "# Bot Settings\r\n"
+ "\r\n"
+ "[Alerts]\r\n"
+ "enabled=false\r\n"
+ "alertsfile=alerts.txt\r\n"
+ "excludesfile=alerts-exclude.txt\r\n"
+ "beeponalert=true\r\n"
+ "\r\n"
+ "[AntiAFK]\r\n"
+ "enabled=false\r\n"
+ "delay=600 #10 = 1s\r\n"
+ "command=/ping\r\n"
+ "\r\n"
+ "[AutoRelog]\r\n"
+ "enabled=false\r\n"
+ "delay=10\r\n"
+ "retries=3 #-1 = unlimited\r\n"
+ "ignorekickmessage=false\r\n"
+ "kickmessagesfile=kickmessages.txt\r\n"
+ "\r\n"
+ "[ChatLog]\r\n"
+ "enabled=false\r\n"
+ "timestamps=true\r\n"
+ "filter=messages\r\n"
+ "logfile=chatlog-%username%-%serverip%.txt\r\n"
+ "\r\n"
+ "[Hangman]\r\n"
+ "enabled=false\r\n"
+ "english=true\r\n"
+ "wordsfile=hangman-en.txt\r\n"
+ "fichiermots=hangman-fr.txt\r\n"
+ "\r\n"
+ "[ScriptScheduler]\r\n"
+ "enabled=false\r\n"
+ "tasksfile=tasks.ini\r\n"
+ "\r\n"
+ "[RemoteControl]\r\n"
+ "enabled=false\r\n"
+ "autotpaccept=true\r\n"
+ "tpaccepteveryone=false\r\n"
+ "\r\n"
+ "[AutoRespond]\r\n"
+ "enabled=false\r\n"
+ "matchesfile=matches.ini\r\n"
+ "\r\n"
+ "[AutoAttack]\r\n"
+ "# Entity Handling NEED to be enabled first\r\n"
+ "enabled=false\r\n"
+ "mode=single # single or multi. single target one mob per attack. multi target all mobs in range per attack\r\n"
+ "priority=distance # health or distance. Only needed when using single mode\r\n"
+ "\r\n"
+ "[AutoFishing]\r\n"
+ "# Entity Handling NEED to be enabled first\r\n"
+ "enabled=false\r\n"
+ "antidespawn=false\r\n"
+ "\r\n"
+ "[AutoEat]\r\n"
+ "# Inventory Handling NEED to be enabled first\r\n"
+ "enabled=false\r\n"
+ "threshold=6\r\n"
+ "\r\n"
+ "[AutoCraft]\r\n"
+ "# Inventory Handling NEED to be enabled first\r\n"
+ "# Enable terrainandmovements if you need to use crafting table\r\n"
+ "enabled=false\r\n"
+ "configfile=autocraft\\config.ini\r\n"
+ "\r\n"
+ "[Mailer]\r\n"
+ "# Let the bot act like a mail plugin\r\n"
+ "enabled=false\r\n"
+ "database=MailerDatabase.ini\r\n"
+ "ignorelist=MailerIgnoreList.ini\r\n"
+ "publicinteractions=false\r\n"
+ "maxmailsperplayer=10\r\n"
+ "maxdatabasesize=10000\r\n"
+ "retentiondays=30\r\n"
+ "\r\n"
+ "[AutoDrop]\r\n"
+ "# Inventory Handling NEED to be enabled first\r\n"
+ "enabled=false\r\n"
+ "mode=include # include, exclude or everything. Include: drop item IN the list. Exclude: drop item NOT IN the list\r\n"
+ "items= # separate each item with comma ','\r\n"
+ "# For the naming of the items, please see \r\n"
+ "# https://github.com/ORelio/Minecraft-Console-Client/blob/master/MinecraftClient/Inventory/ItemType.cs \r\n"
+ "\r\n"
+ "[ReplayMod]\r\n"
+ "# Enable recording the game and replay it later using Replay Mod\r\n"
+ "# You MUST exit the program using /quit command or the replay will NOT be saved!\r\n"
+ "enabled=false\r\n"
+ "backupinterval=300 # How long should replay file be auto-saved, in seconds. Use -1 for disabled\r\n"
+ "\r\n", Encoding.UTF8);
} }
/// <summary> /// <summary>
@ -818,7 +651,7 @@ namespace MinecraftClient
return Convert.ToInt32(str.Trim()); return Convert.ToInt32(str.Trim());
} }
catch { catch {
ConsoleIO.WriteLogLine("Failed to convert '" + str + "' into an int. Please check your settings."); ConsoleIO.WriteLogLine(Translations.Get("error.setting.str2int", str));
return 0; return 0;
} }
} }

View file

@ -0,0 +1,240 @@
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
namespace MinecraftClient
{
/// <summary>
/// Allows to localize MinecraftClient in different languages
/// </summary>
/// <remarks>
/// By ORelio (c) 2015-2018 - CDDL 1.0
/// </remarks>
public static class Translations
{
private static Dictionary<string, string> translations;
private static string translationFilePath = "lang" + Path.DirectorySeparatorChar + "mcc";
private static string defaultTranslation = "en.ini";
private static Regex translationKeyRegex = new Regex(@"\(\[(.*?)\]\)", RegexOptions.Compiled); // Extract string inside ([ ])
/// <summary>
/// Return a tranlation for the requested text. Support string formatting
/// </summary>
/// <param name="msgName">text identifier</param>
/// <returns>returns translation for this identifier</returns>
public static string Get(string msgName, params object[] args)
{
if (translations.ContainsKey(msgName))
{
if (args.Length > 0)
{
return string.Format(translations[msgName], args);
}
else return translations[msgName];
}
return msgName.ToUpper();
}
/// <summary>
/// Return a tranlation for the requested text. Support string formatting. If not found, return the original text
/// </summary>
/// <param name="msgName">text identifier</param>
/// <param name="args"></param>
/// <returns>Translated text or original text if not found</returns>
/// <remarks>Useful when not sure msgName is a translation mapping key or a normal text</remarks>
public static string TryGet(string msgName, params object[] args)
{
if (translations.ContainsKey(msgName))
return Get(msgName, args);
else return msgName;
}
/// <summary>
/// Replace the translation key inside a sentence to translated text. Wrap the key in ([translation.key])
/// </summary>
/// <example>
/// e.g. I only want to replace ([this])
/// would only translate "this" without touching other words.
/// </example>
/// <param name="msg">Sentence for replace</param>
/// <param name="args"></param>
/// <returns>Translated sentence</returns>
public static string Replace(string msg, params object[] args)
{
string translated = translationKeyRegex.Replace(msg, new MatchEvaluator(ReplaceKey));
if (args.Length > 0)
return string.Format(translated, args);
else return translated;
}
private static string ReplaceKey(Match m)
{
return Get(m.Groups[1].Value);
}
/// <summary>
/// Initialize translations depending on system language.
/// English is the default for all unknown system languages.
/// </summary>
static Translations()
{
translations = new Dictionary<string, string>();
LoadDefaultTranslationsFile();
}
/// <summary>
/// Load default translation file (English)
/// </summary>
/// <remarks>
/// This will be loaded during program start up.
/// </remarks>
private static void LoadDefaultTranslationsFile()
{
string[] engLang = DefaultConfigResource.TranslationEnglish.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); // use embedded translations
ParseTranslationContent(engLang);
}
/// <summary>
/// Load translation file depends on system language or by giving a file path. Default to English if translation file does not exist
/// </summary>
public static void LoadExternalTranslationFile(string language)
{
/*
* External translation files
* These files are loaded from the installation directory as:
* Lang/abc.ini, e.g. Lang/eng.ini which is the default language file
* Useful for adding new translations of fixing typos without recompiling
*/
// Try to convert Minecraft language file name to two letters language name
if (language == "zh_cn")
language = "zh-CHS";
else if (language == "zh_tw")
language = "zh-CHT";
else
language = language.Split('_')[0];
string systemLanguage = string.IsNullOrEmpty(CultureInfo.CurrentCulture.Parent.Name) // Parent.Name might be empty
? CultureInfo.CurrentCulture.Name
: CultureInfo.CurrentCulture.Parent.Name;
string langDir = AppDomain.CurrentDomain.BaseDirectory + Path.DirectorySeparatorChar + translationFilePath + Path.DirectorySeparatorChar;
string langFileSystemLanguage = langDir + systemLanguage + ".ini";
string langFileConfigLanguage = langDir + language + ".ini";
if (File.Exists(langFileConfigLanguage))
{// Language set in ini config
ParseTranslationContent(File.ReadAllLines(langFileConfigLanguage));
return;
}
else
{
if (Settings.DebugMessages)
ConsoleIO.WriteLogLine("[Translations] No translation file found for " + language + ". (Looked '" + langFileConfigLanguage + "'");
}
if (File.Exists(langFileSystemLanguage))
{// Fallback to system language
ParseTranslationContent(File.ReadAllLines(langFileSystemLanguage));
return;
}
else
{
if (Settings.DebugMessages)
ConsoleIO.WriteLogLine("[Translations] No translation file found for system language (" + systemLanguage + "). (Looked '" + langFileSystemLanguage + "'");
}
}
/// <summary>
/// Parse the given array to translation map
/// </summary>
/// <param name="content">Content of the translation file (in ini format)</param>
private static void ParseTranslationContent(string[] content)
{
foreach (string lineRaw in content)
{
string line = lineRaw.Trim();
if (line.Length <= 0)
continue;
if (line.StartsWith("#")) // ignore comment line started with #
continue;
if (line[0] == '[' && line[line.Length - 1] == ']') // ignore section
continue;
string translationName = line.Split('=')[0];
if (line.Length > (translationName.Length + 1))
{
string translationValue = line.Substring(translationName.Length + 1).Replace("\\n", "\n");
translations[translationName] = translationValue;
}
}
}
/// <summary>
/// Write the default translation file (English) to the disk.
/// </summary>
private static void WriteDefaultTranslation()
{
string defaultPath = AppDomain.CurrentDomain.BaseDirectory + Path.DirectorySeparatorChar + translationFilePath + Path.DirectorySeparatorChar + defaultTranslation;
if (!Directory.Exists(translationFilePath))
{
Directory.CreateDirectory(translationFilePath);
}
File.WriteAllText(defaultPath, DefaultConfigResource.TranslationEnglish, Encoding.UTF8);
}
#region Console writing method wrapper
/// <summary>
/// Translate the key and write the result to the standard output, without newline character
/// </summary>
/// <param name="key">Translation key</param>
public static void Write(string key)
{
ConsoleIO.Write(Get(key));
}
/// <summary>
/// Translate the key and write a Minecraft-Like formatted string to the standard output, using §c color codes
/// See minecraft.gamepedia.com/Classic_server_protocol#Color_Codes for more info
/// </summary>
/// <param name="key">Translation key</param>
/// <param name="acceptnewlines">If false, space are printed instead of newlines</param>
/// <param name="displayTimestamp">
/// If false, no timestamp is prepended.
/// If true, "hh-mm-ss" timestamp will be prepended.
/// If unspecified, value is retrieved from EnableTimestamps.
/// </param>
public static void WriteLineFormatted(string key, bool acceptnewlines = true, bool? displayTimestamp = null)
{
ConsoleIO.WriteLineFormatted(Get(key), acceptnewlines, displayTimestamp);
}
/// <summary>
/// Translate the key, format the result and write it to the standard output with a trailing newline. Support string formatting
/// </summary>
/// <param name="key">Translation key</param>
/// <param name="args"></param>
public static void WriteLine(string key, params object[] args)
{
if (args.Length > 0)
ConsoleIO.WriteLine(string.Format(Get(key), args));
else ConsoleIO.WriteLine(Get(key));
}
/// <summary>
/// Translate the key and write the result with a prefixed log line. Prefix is set in LogPrefix.
/// </summary>
/// <param name="key">Translation key</param>
/// <param name="acceptnewlines">Allow line breaks</param>
public static void WriteLogLine(string key, bool acceptnewlines = true)
{
ConsoleIO.WriteLogLine(Get(key), acceptnewlines);
}
#endregion
}
}