Add support for C# scripts in scripting bot

- Now scripts can also be written in C#
- C# scripts can access ChatBot API
- Add more methods in ChatBot API
- Add an example of C# script file
- Coding style fixes: method names ucfirst
This commit is contained in:
ORelio 2015-06-20 22:58:18 +02:00
parent 3224c59eab
commit 3ce91188c7
22 changed files with 321 additions and 135 deletions

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
namespace MinecraftClient
{
@ -33,8 +34,11 @@ namespace MinecraftClient
public enum DisconnectReason { InGameKick, LoginRejected, ConnectionLost };
//Will be automatically set on bot loading, don't worry about this
public void SetHandler(McTcpClient handler) { this.handler = handler; }
private McTcpClient handler;
public void SetHandler(McTcpClient handler) { this._handler = handler; }
public void SetMaster(ChatBot master) { this.master = master; }
private McTcpClient Handler { get { return master != null ? master.Handler : _handler; } }
private McTcpClient _handler = null;
private ChatBot master = null;
/* ================================================== */
/* Main methods to override for creating your bot */
@ -80,10 +84,12 @@ namespace MinecraftClient
/// <param name="text">Text to send to the server</param>
/// <returns>True if the text was sent with no error</returns>
protected bool SendText(string text)
protected bool SendText(object text)
{
LogToConsole("Sending '" + text + "'");
return handler.SendText(text);
bool result = Handler.SendText(text is string ? (string)text : text.ToString());
Thread.Sleep(1000);
return result;
}
/// <summary>
@ -92,10 +98,10 @@ namespace MinecraftClient
/// <param name="command">The command to process</param>
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
protected bool performInternalCommand(string command)
protected bool PerformInternalCommand(string command)
{
string temp = "";
return handler.performInternalCommand(command, ref temp);
return Handler.PerformInternalCommand(command, ref temp);
}
/// <summary>
@ -105,16 +111,16 @@ namespace MinecraftClient
/// <param name="response_msg">May contain a confirmation or error message after processing the command, or "" otherwise.</param>
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
protected bool performInternalCommand(string command, ref string response_msg)
protected bool PerformInternalCommand(string command, ref string response_msg)
{
return handler.performInternalCommand(command, ref response_msg);
return Handler.PerformInternalCommand(command, ref response_msg);
}
/// <summary>
/// Remove color codes ("§c") from a text message received from the server
/// </summary>
protected static string getVerbatim(string text)
protected static string GetVerbatim(string text)
{
if ( String.IsNullOrEmpty(text) )
return String.Empty;
@ -135,7 +141,7 @@ namespace MinecraftClient
/// Verify that a string contains only a-z A-Z 0-9 and _ characters.
/// </summary>
protected static bool isValidName(string username)
protected static bool IsValidName(string username)
{
if ( String.IsNullOrEmpty(username) )
return false;
@ -158,9 +164,9 @@ namespace MinecraftClient
/// <param name="sender">if it's a private message, this will contain the player name that sends the message</param>
/// <returns>Returns true if the text is a private message</returns>
protected static bool isPrivateMessage(string text, ref string message, ref string sender)
protected static bool IsPrivateMessage(string text, ref string message, ref string sender)
{
text = getVerbatim(text);
text = GetVerbatim(text);
if (text == "") { return false; }
string[] tmp = text.Split(' ');
@ -177,7 +183,7 @@ namespace MinecraftClient
}
else message = text.Substring(tmp[0].Length + 10); //MC 1.5
sender = tmp[0];
return isValidName(sender);
return IsValidName(sender);
}
//Detect Essentials (Bukkit) /m messages
@ -189,7 +195,7 @@ namespace MinecraftClient
message = text.Substring(tmp[0].Length + 4 + tmp[2].Length + 1);
sender = tmp[0].Substring(1);
if (sender[0] == '~') { sender = sender.Substring(1); }
return isValidName(sender);
return IsValidName(sender);
}
//Detect Essentials (Bukkit) /me messages with some custom rank
@ -201,7 +207,7 @@ namespace MinecraftClient
message = text.Substring(tmp[0].Length + 1 + tmp[1].Length + 4 + tmp[2].Length + 1);
sender = tmp[0].Substring(1);
if (sender[0] == '~') { sender = sender.Substring(1); }
return isValidName(sender);
return IsValidName(sender);
}
//Detect HeroChat PMsend
@ -210,7 +216,7 @@ namespace MinecraftClient
{
sender = text.Substring(5).Split(':')[0];
message = text.Substring(text.IndexOf(':') + 2);
return isValidName(sender);
return IsValidName(sender);
}
else return false;
@ -226,10 +232,10 @@ namespace MinecraftClient
/// <param name="sender">if it's message, this will contain the player name that sends the message</param>
/// <returns>Returns true if the text is a chat message</returns>
protected static bool isChatMessage(string text, ref string message, ref string sender)
protected static bool IsChatMessage(string text, ref string message, ref string sender)
{
text = getVerbatim(text);
text = GetVerbatim(text);
string[] tmp = text.Split(' ');
if (text.Length > 0)
{
@ -251,7 +257,7 @@ namespace MinecraftClient
tmp2 = sender.Split(' ');
sender = tmp2[tmp2.Length - 1];
if (sender[0] == '~') { sender = sender.Substring(1); }
return isValidName(sender);
return IsValidName(sender);
}
catch (IndexOutOfRangeException) { return false; }
}
@ -264,7 +270,7 @@ namespace MinecraftClient
int name_start = text.Substring(0, name_end).LastIndexOf(']') + 2;
sender = text.Substring(name_start, name_end - name_start);
message = text.Substring(name_end + 2);
return isValidName(sender);
return IsValidName(sender);
}
}
return false;
@ -277,14 +283,14 @@ namespace MinecraftClient
/// <param name="sender">Will contain the sender's username, if it's a teleport request</param>
/// <returns>Returns true if the text is a teleport request</returns>
protected static bool isTeleportRequest(string text, ref string sender)
protected static bool IsTeleportRequest(string text, ref string sender)
{
text = getVerbatim(text);
text = GetVerbatim(text);
sender = text.Split(' ')[0];
if (text.EndsWith("has requested to teleport to you.")
|| text.EndsWith("has requested that you teleport to them."))
{
return isValidName(sender);
return IsValidName(sender);
}
else return false;
}
@ -294,10 +300,10 @@ namespace MinecraftClient
/// </summary>
/// <param name="text">Log text to write</param>
public static void LogToConsole(string text)
public static void LogToConsole(object text)
{
ConsoleIO.WriteLineFormatted("§8[BOT] " + text);
string logfile = Settings.expandVars(Settings.chatbotLogFile);
string logfile = Settings.ExpandVars(Settings.chatbotLogFile);
if (!String.IsNullOrEmpty(logfile))
{
@ -309,7 +315,7 @@ namespace MinecraftClient
catch { return; /* Invalid file name or access denied */ }
}
File.AppendAllLines(logfile, new string[] { getTimestamp() + ' ' + text });
File.AppendAllLines(logfile, new string[] { GetTimestamp() + ' ' + text });
}
}
@ -340,7 +346,7 @@ namespace MinecraftClient
protected void UnloadBot()
{
handler.BotUnLoad(this);
Handler.BotUnLoad(this);
}
/// <summary>
@ -362,14 +368,14 @@ namespace MinecraftClient
protected void RunScript(string filename, string playername = "")
{
handler.BotLoad(new ChatBots.Script(filename, playername));
Handler.BotLoad(new ChatBots.Script(filename, playername));
}
/// <summary>
/// Get a Y-M-D h:m:s timestamp representing the current system date and time
/// </summary>
protected static string getTimestamp()
protected static string GetTimestamp()
{
DateTime time = DateTime.Now;
return String.Format("{0}-{1}-{2} {3}:{4}:{5}",
@ -404,5 +410,59 @@ namespace MinecraftClient
return new string[0];
}
}
/// <summary>
/// Set a custom %variable% which will be available through expandVars()
/// </summary>
/// <param name="varName">Name of the variable</param>
/// <param name="varData">Value of the variable</param>
/// <returns>True if the parameters were valid</returns>
protected static bool SetVar(string varName, object varData)
{
return Settings.SetVar(varName, varData.ToString());
}
/// <summary>
/// Get a custom %variable% or null if the variable does not exist
/// </summary>
/// <param name="varName">Variable name</param>
/// <returns>The value or null if the variable does not exists</returns>
protected static string GetVar(string varName)
{
return Settings.GetVar(varName);
}
/// <summary>
/// Get a custom %variable% as an Integer or null if the variable does not exist
/// </summary>
/// <param name="varName">Variable name</param>
/// <returns>The value or null if the variable does not exists</returns>
protected static int GetVarAsInt(string varName)
{
return Settings.str2int(Settings.GetVar(varName));
}
/// <summary>
/// Load login/password using an account alias
/// </summary>
/// <returns>True if the account was found and loaded</returns>
protected static bool SetAccount(string accountAlias)
{
return Settings.SetAccount(accountAlias);
}
/// <summary>
/// Load server information in ServerIP and ServerPort variables from a "serverip:port" couple or server alias
/// </summary>
/// <returns>True if the server IP was valid and loaded, false otherwise</returns>
protected static bool SetServerIP(string server)
{
return Settings.SetServerIP(server);
}
}
}

View file

@ -30,7 +30,7 @@ namespace MinecraftClient.ChatBots
public override void GetText(string text)
{
//Remove color codes and convert to lowercase
text = getVerbatim(text).ToLower();
text = GetVerbatim(text).ToLower();
//Proceed only if no exclusions are found in text
if (!excludelist.Any(exclusion => text.Contains(exclusion)))

View file

@ -47,7 +47,7 @@ namespace MinecraftClient.ChatBots
public override bool OnDisconnect(DisconnectReason reason, string message)
{
message = getVerbatim(message);
message = GetVerbatim(message);
string comp = message.ToLower();
foreach (string msg in dictionary)
{

View file

@ -182,14 +182,14 @@ namespace MinecraftClient.ChatBots
public override void GetText(string text)
{
//Remove colour codes
text = getVerbatim(text).ToLower();
text = GetVerbatim(text).ToLower();
//Check if this is a valid message
string sender = "", message = "";
bool chatMessage = isChatMessage(text, ref message, ref sender);
bool chatMessage = IsChatMessage(text, ref message, ref sender);
bool privateMessage = false;
if (!chatMessage)
privateMessage = isPrivateMessage(text, ref message, ref sender);
privateMessage = IsPrivateMessage(text, ref message, ref sender);
//Process only chat messages sent by another user
if ((chatMessage || privateMessage) && sender != Settings.Username)
@ -201,7 +201,7 @@ namespace MinecraftClient.ChatBots
{
string response = null;
LogToConsole(header + toPerform);
performInternalCommand(toPerform, ref response);
PerformInternalCommand(toPerform, ref response);
if (!String.IsNullOrEmpty(response))
LogToConsole(header + response);
}

View file

@ -69,15 +69,15 @@ namespace MinecraftClient.ChatBots
public override void GetText(string text)
{
text = getVerbatim(text);
text = GetVerbatim(text);
string sender = "";
string message = "";
if (saveChat && isChatMessage(text, ref message, ref sender))
if (saveChat && IsChatMessage(text, ref message, ref sender))
{
save("Chat " + sender + ": " + message);
}
else if (savePrivate && isPrivateMessage(text, ref message, ref sender))
else if (savePrivate && IsPrivateMessage(text, ref message, ref sender))
{
save("Private " + sender + ": " + message);
}
@ -90,7 +90,7 @@ namespace MinecraftClient.ChatBots
private void save(string tosave)
{
if (dateandtime)
tosave = getTimestamp() + ' ' + tosave;
tosave = GetTimestamp() + ' ' + tosave;
string directory = Path.GetDirectoryName(logfile);
if (!String.IsNullOrEmpty(directory) && !Directory.Exists(directory))

View file

@ -52,9 +52,9 @@ namespace MinecraftClient.ChatBots
{
string message = "";
string username = "";
text = getVerbatim(text);
text = GetVerbatim(text);
if (isPrivateMessage(text, ref message, ref username))
if (IsPrivateMessage(text, ref message, ref username))
{
if (Settings.Bots_Owners.Contains(username.ToLower()))
{
@ -73,7 +73,7 @@ namespace MinecraftClient.ChatBots
}
else
{
if (running && isChatMessage(text, ref message, ref username))
if (running && IsChatMessage(text, ref message, ref username))
{
if (message.Length == 1)
{

View file

@ -46,7 +46,7 @@ namespace MinecraftClient.ChatBots
LogToConsole("Saving Player List");
DateTime now = DateTime.Now;
string TimeStamp = "[" + now.Year + '/' + now.Month + '/' + now.Day + ' ' + now.Hour + ':' + now.Minute + ']';
System.IO.File.AppendAllText(file, TimeStamp + "\n" + getVerbatim(text) + "\n\n");
System.IO.File.AppendAllText(file, TimeStamp + "\n" + GetVerbatim(text) + "\n\n");
}
}
}

View file

@ -13,19 +13,19 @@ namespace MinecraftClient.ChatBots
{
public override void GetText(string text)
{
text = getVerbatim(text);
text = GetVerbatim(text);
string command = "", sender = "";
if (isPrivateMessage(text, ref command, ref sender) && Settings.Bots_Owners.Contains(sender.ToLower().Trim()))
if (IsPrivateMessage(text, ref command, ref sender) && Settings.Bots_Owners.Contains(sender.ToLower().Trim()))
{
string response = "";
performInternalCommand(command, ref response);
PerformInternalCommand(command, ref response);
if (response.Length > 0)
{
SendPrivateMessage(sender, response);
}
}
else if (Settings.RemoteCtrl_AutoTpaccept
&& isTeleportRequest(text, ref sender)
&& IsTeleportRequest(text, ref sender)
&& (Settings.RemoteCtrl_AutoTpaccept_Everyone || Settings.Bots_Owners.Contains(sender.ToLower().Trim())))
{
SendText("/tpaccept");

View file

@ -2,6 +2,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
namespace MinecraftClient.ChatBots
{
@ -14,9 +17,11 @@ namespace MinecraftClient.ChatBots
private string file;
private string[] lines = new string[0];
private int sleepticks = 10;
private int sleepticks_interval = 10;
private int nextline = 0;
private string owner;
private bool csharp;
private Thread thread;
private ManualResetEvent tpause;
public Script(string filename)
{
@ -38,10 +43,13 @@ namespace MinecraftClient.ChatBots
{
filename,
filename + ".txt",
filename + ".cs",
"scripts" + dir_slash + filename,
"scripts" + dir_slash + filename + ".txt",
"scripts" + dir_slash + filename + ".cs",
"config" + dir_slash + filename,
"config" + dir_slash + filename + ".txt",
"config" + dir_slash + filename + ".cs",
};
foreach (string possible_file in files)
@ -62,63 +70,152 @@ namespace MinecraftClient.ChatBots
if (lookForScript(ref file))
{
lines = System.IO.File.ReadAllLines(file);
if (owner != null) { SendPrivateMessage(owner, "Script '" + file + "' loaded."); }
csharp = file.EndsWith(".cs");
thread = null;
if (owner != null)
SendPrivateMessage(owner, "Script '" + file + "' loaded.");
}
else
{
LogToConsole("File not found: '" + file + "'");
if (owner != null)
SendPrivateMessage(owner, "File not found: '" + file + "'");
UnloadBot(); //No need to keep the bot active
}
}
public override void Update()
{
if (sleepticks > 0) { sleepticks--; }
else
if (csharp) //C# compiled script
{
if (nextline < lines.Length) //Is there an instruction left to interpret?
//Initialize thread on first update
if (thread == null)
{
string instruction_line = lines[nextline].Trim(); // Removes all whitespaces at start and end of current line
nextline++; //Move the cursor so that the next time the following line will be interpreted
sleepticks = sleepticks_interval; //Used to delay next command sending and prevent from beign kicked for spamming
if (instruction_line.Length > 1)
tpause = new ManualResetEvent(false);
thread = new Thread(() =>
{
if (instruction_line[0] != '#' && instruction_line[0] != '/' && instruction_line[1] != '/')
{
instruction_line = Settings.expandVars(instruction_line);
string instruction_name = instruction_line.Split(' ')[0];
switch (instruction_name.ToLower())
{
case "wait":
int ticks = 10;
try
{
ticks = Convert.ToInt32(instruction_line.Substring(5, instruction_line.Length - 5));
}
catch { }
sleepticks = ticks;
break;
default:
if (!performInternalCommand(instruction_line))
{
sleepticks = 0; Update(); //Unknown command : process next line immediately
}
else if (instruction_name.ToLower() != "log") { LogToConsole(instruction_line); }
break;
}
}
else { sleepticks = 0; Update(); } //Comment: process next line immediately
}
if (!RunCSharpScript(String.Join("\n", lines), file, tpause) && owner != null)
SendPrivateMessage(owner, "Script '" + file + "' failed to run.");
});
thread.Start();
}
//Let the thread run for a short span of time
if (thread != null)
{
tpause.Set();
tpause.Reset();
if (thread.Join(100))
UnloadBot();
}
}
else //Classic MCC script interpreter
{
if (sleepticks > 0) { sleepticks--; }
else
{
//No more instructions to interpret
UnloadBot();
if (nextline < lines.Length) //Is there an instruction left to interpret?
{
string instruction_line = lines[nextline].Trim(); // Removes all whitespaces at start and end of current line
nextline++; //Move the cursor so that the next time the following line will be interpreted
if (instruction_line.Length > 1)
{
if (instruction_line[0] != '#' && instruction_line[0] != '/' && instruction_line[1] != '/')
{
instruction_line = Settings.ExpandVars(instruction_line);
string instruction_name = instruction_line.Split(' ')[0];
switch (instruction_name.ToLower())
{
case "wait":
int ticks = 10;
try
{
ticks = Convert.ToInt32(instruction_line.Substring(5, instruction_line.Length - 5));
}
catch { }
sleepticks = ticks;
break;
default:
if (!PerformInternalCommand(instruction_line))
{
Update(); //Unknown command : process next line immediately
}
else if (instruction_name.ToLower() != "log") { LogToConsole(instruction_line); }
break;
}
}
else { Update(); } //Comment: process next line immediately
}
}
else
{
//No more instructions to interpret
UnloadBot();
}
}
}
}
private bool RunCSharpScript(string script, string filename = "C# Script", ManualResetEvent tpause = null)
{
//Script compatibility check for handling future versions differently
if (!script.ToLower().StartsWith("//mccscript 1.0"))
{
ConsoleIO.WriteLineFormatted("§8Script file '" + filename + "' does not start with a valid //MCCScript comment.");
return false;
}
//Create a simple ChatBot class from the given script, allowing access to ChatBot API
string code = String.Join("\n", new string[]
{
"using System;",
"using System.IO;",
"using System.Threading;",
"using MinecraftClient;",
"namespace ScriptLoader {",
"public class Script : ChatBot {",
"public void Run(ChatBot master, ManualResetEvent tpause) {",
"SetMaster(master);",
tpause != null
? script.Replace(";\n", ";\ntpause.WaitOne();\n")
: script,
"}}}",
});
//Compile the C# class in memory using all the currently loaded assemblies
CSharpCodeProvider compiler = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
parameters.ReferencedAssemblies
.AddRange(AppDomain.CurrentDomain
.GetAssemblies()
.Where(a => !a.IsDynamic)
.Select(a => a.Location).ToArray());
parameters.CompilerOptions = "/t:library";
parameters.GenerateInMemory = true;
CompilerResults result
= compiler.CompileAssemblyFromSource(parameters, code);
//Process compile warnings and errors
if (result.Errors.Count > 0)
{
ConsoleIO.WriteLineFormatted("§8Error loading '" + filename + "':\n" + result.Errors[0].ErrorText);
return false;
}
//Run the compiled script with exception handling
object compiledScript = result.CompiledAssembly.CreateInstance("ScriptLoader.Script");
try { compiledScript.GetType().GetMethod("Run").Invoke(compiledScript, new object[] { this, tpause }); }
catch (Exception e)
{
ConsoleIO.WriteLineFormatted("§8Runtime error for '" + filename + "':\n" + e);
return false;
}
return true;
}
}
}

View file

@ -15,13 +15,13 @@ namespace MinecraftClient.ChatBots
{
string message = "";
string username = "";
text = getVerbatim(text);
text = GetVerbatim(text);
if (isPrivateMessage(text, ref message, ref username))
if (IsPrivateMessage(text, ref message, ref username))
{
ConsoleIO.WriteLine("Bot: " + username + " told me : " + message);
}
else if (isChatMessage(text, ref message, ref username))
else if (IsChatMessage(text, ref message, ref username))
{
ConsoleIO.WriteLine("Bot: " + username + " said : " + message);
}

View file

@ -17,13 +17,13 @@ namespace MinecraftClient.Commands
string[] args = getArgs(command);
if (args.Length > 1)
{
if (!Settings.setAccount(args[1]))
if (!Settings.SetAccount(args[1]))
{
return "Unknown account '" + args[1] + "'.";
}
}
if (Settings.setServerIP(args[0]))
if (Settings.SetServerIP(args[0]))
{
Program.Restart();
return "";

View file

@ -12,7 +12,7 @@ namespace MinecraftClient.Commands
public override string Run(McTcpClient handler, string command)
{
return "PlayerList: " + String.Join(", ", handler.getOnlinePlayers());
return "PlayerList: " + String.Join(", ", handler.GetOnlinePlayers());
}
}
}

View file

@ -15,7 +15,7 @@ namespace MinecraftClient.Commands
string[] args = getArgs(command);
if (args.Length > 0)
{
if (!Settings.setAccount(args[0]))
if (!Settings.SetAccount(args[0]))
{
return "Unknown account '" + args[0] + "'.";
}

View file

@ -17,7 +17,7 @@ namespace MinecraftClient.Commands
string[] temp = getArg(command).Split('=');
if (temp.Length > 1)
{
if (Settings.setVar(temp[0], getArg(command).Substring(temp[0].Length + 1)))
if (Settings.SetVar(temp[0], getArg(command).Substring(temp[0].Length + 1)))
{
return ""; //Success
}

View file

@ -34,11 +34,11 @@ namespace MinecraftClient
private string uuid;
private string sessionid;
public int getServerPort() { return port; }
public string getServerHost() { return host; }
public string getUsername() { return username; }
public string getUserUUID() { return uuid; }
public string getSessionID() { return sessionid; }
public int GetServerPort() { return port; }
public string GetServerHost() { return host; }
public string GetUsername() { return username; }
public string GetUserUUID() { return uuid; }
public string GetSessionID() { return sessionid; }
TcpClient client;
IMinecraftCom handler;
@ -101,10 +101,10 @@ namespace MinecraftClient
if (Settings.AntiAFK_Enabled) { BotLoad(new ChatBots.AntiAFK(Settings.AntiAFK_Delay)); }
if (Settings.Hangman_Enabled) { BotLoad(new ChatBots.HangmanGame(Settings.Hangman_English)); }
if (Settings.Alerts_Enabled) { BotLoad(new ChatBots.Alerts()); }
if (Settings.ChatLog_Enabled) { BotLoad(new ChatBots.ChatLog(Settings.expandVars(Settings.ChatLog_File), Settings.ChatLog_Filter, Settings.ChatLog_DateTime)); }
if (Settings.PlayerLog_Enabled) { BotLoad(new ChatBots.PlayerListLogger(Settings.PlayerLog_Delay, Settings.expandVars(Settings.PlayerLog_File))); }
if (Settings.ChatLog_Enabled) { BotLoad(new ChatBots.ChatLog(Settings.ExpandVars(Settings.ChatLog_File), Settings.ChatLog_Filter, Settings.ChatLog_DateTime)); }
if (Settings.PlayerLog_Enabled) { BotLoad(new ChatBots.PlayerListLogger(Settings.PlayerLog_Delay, Settings.ExpandVars(Settings.PlayerLog_File))); }
if (Settings.AutoRelog_Enabled) { BotLoad(new ChatBots.AutoRelog(Settings.AutoRelog_Delay, Settings.AutoRelog_Retries)); }
if (Settings.ScriptScheduler_Enabled) { BotLoad(new ChatBots.ScriptScheduler(Settings.expandVars(Settings.ScriptScheduler_TasksFile))); }
if (Settings.ScriptScheduler_Enabled) { BotLoad(new ChatBots.ScriptScheduler(Settings.ExpandVars(Settings.ScriptScheduler_TasksFile))); }
if (Settings.RemoteCtrl_Enabled) { BotLoad(new ChatBots.RemoteControl()); }
if (Settings.AutoRespond_Enabled) { BotLoad(new ChatBots.AutoRespond(Settings.AutoRespond_Matches)); }
}
@ -209,7 +209,7 @@ namespace MinecraftClient
{
string response_msg = "";
string command = Settings.internalCmdChar == ' ' ? text : text.Substring(1);
if (!performInternalCommand(Settings.expandVars(command), ref response_msg) && Settings.internalCmdChar == '/')
if (!PerformInternalCommand(Settings.ExpandVars(command), ref response_msg) && Settings.internalCmdChar == '/')
{
SendText(text);
}
@ -234,7 +234,7 @@ namespace MinecraftClient
/// <param name="response_msg">May contain a confirmation or error message after processing the command, or "" otherwise.</param>
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
public bool performInternalCommand(string command, ref string response_msg)
public bool PerformInternalCommand(string command, ref string response_msg)
{
/* Load commands from the 'Commands' namespace */
@ -314,7 +314,8 @@ namespace MinecraftClient
Thread.Sleep(1000);
if (client != null) { client.Close(); }
if (client != null)
client.Close();
}
/// <summary>
@ -476,7 +477,7 @@ namespace MinecraftClient
/// </summary>
/// <returns>Online player names</returns>
public string[] getOnlinePlayers()
public string[] GetOnlinePlayers()
{
lock (onlinePlayers)
{

View file

@ -63,7 +63,7 @@ namespace MinecraftClient
Settings.Password = args[1];
if (args.Length >= 3)
{
Settings.setServerIP(args[2]);
Settings.SetServerIP(args[2]);
//Single command?
if (args.Length >= 4)
@ -77,7 +77,7 @@ namespace MinecraftClient
if (Settings.ConsoleTitle != "")
{
Settings.Username = "New Window";
Console.Title = Settings.expandVars(Settings.ConsoleTitle);
Console.Title = Settings.ExpandVars(Settings.ConsoleTitle);
}
//Asking the user to type in missing data such as Username and Password
@ -130,7 +130,7 @@ namespace MinecraftClient
if (result == ProtocolHandler.LoginResult.Success)
{
if (Settings.ConsoleTitle != "")
Console.Title = Settings.expandVars(Settings.ConsoleTitle);
Console.Title = Settings.ExpandVars(Settings.ConsoleTitle);
if (Settings.playerHeadAsIcon)
ConsoleIcon.setPlayerIconAsync(Settings.Username);
@ -140,7 +140,7 @@ namespace MinecraftClient
if (Settings.ServerIP == "")
{
Console.Write("Server IP : ");
Settings.setServerIP(Console.ReadLine());
Settings.SetServerIP(Console.ReadLine());
}
//Get server version
@ -186,7 +186,7 @@ namespace MinecraftClient
//Update console title
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); }
}
@ -306,15 +306,15 @@ namespace MinecraftClient
if (command.StartsWith("reco"))
{
message = new Commands.Reco().Run(null, Settings.expandVars(command));
message = new Commands.Reco().Run(null, Settings.ExpandVars(command));
}
else if (command.StartsWith("connect"))
{
message = new Commands.Connect().Run(null, Settings.expandVars(command));
message = new Commands.Connect().Run(null, Settings.ExpandVars(command));
}
else if (command.StartsWith("exit") || command.StartsWith("quit"))
{
message = new Commands.Exit().Run(null, Settings.expandVars(command));
message = new Commands.Exit().Run(null, Settings.ExpandVars(command));
}
else if (command.StartsWith("help"))
{

View file

@ -505,7 +505,7 @@ namespace MinecraftClient.Protocol.Handlers
public bool Login()
{
if (Handshake(handler.getUserUUID(), handler.getUsername(), handler.getSessionID(), handler.getServerHost(), handler.getServerPort()))
if (Handshake(handler.GetUserUUID(), handler.GetUsername(), handler.GetSessionID(), handler.GetServerHost(), handler.GetServerPort()))
{
Send(new byte[] { 0xCD, 0 });
try

View file

@ -349,16 +349,16 @@ namespace MinecraftClient.Protocol.Handlers
{
byte[] packet_id = getVarInt(0);
byte[] protocol_version = getVarInt(protocolversion);
byte[] server_adress_val = Encoding.UTF8.GetBytes(handler.getServerHost());
byte[] server_adress_val = Encoding.UTF8.GetBytes(handler.GetServerHost());
byte[] server_adress_len = getVarInt(server_adress_val.Length);
byte[] server_port = BitConverter.GetBytes((ushort)handler.getServerPort()); Array.Reverse(server_port);
byte[] server_port = BitConverter.GetBytes((ushort)handler.GetServerPort()); Array.Reverse(server_port);
byte[] next_state = getVarInt(2);
byte[] handshake_packet = concatBytes(packet_id, protocol_version, server_adress_len, server_adress_val, server_port, next_state);
byte[] handshake_packet_tosend = concatBytes(getVarInt(handshake_packet.Length), handshake_packet);
Send(handshake_packet_tosend);
byte[] username_val = Encoding.UTF8.GetBytes(handler.getUsername());
byte[] username_val = Encoding.UTF8.GetBytes(handler.GetUsername());
byte[] username_len = getVarInt(username_val.Length);
byte[] login_packet = concatBytes(packet_id, username_len, username_val);
byte[] login_packet_tosend = concatBytes(getVarInt(login_packet.Length), login_packet);
@ -377,7 +377,7 @@ namespace MinecraftClient.Protocol.Handlers
string serverID = readNextString();
byte[] Serverkey = readNextByteArray();
byte[] token = readNextByteArray();
return StartEncryption(handler.getUserUUID(), handler.getSessionID(), token, serverID, Serverkey);
return StartEncryption(handler.GetUserUUID(), handler.GetSessionID(), token, serverID, Serverkey);
}
else if (pid == 0x02) //Login successful
{

View file

@ -449,15 +449,15 @@ namespace MinecraftClient.Protocol.Handlers
public bool Login()
{
byte[] protocol_version = getVarInt(protocolversion);
byte[] server_adress_val = Encoding.UTF8.GetBytes(handler.getServerHost());
byte[] server_adress_val = Encoding.UTF8.GetBytes(handler.GetServerHost());
byte[] server_adress_len = getVarInt(server_adress_val.Length);
byte[] server_port = BitConverter.GetBytes((ushort)handler.getServerPort()); Array.Reverse(server_port);
byte[] server_port = BitConverter.GetBytes((ushort)handler.GetServerPort()); Array.Reverse(server_port);
byte[] next_state = getVarInt(2);
byte[] handshake_packet = concatBytes(protocol_version, server_adress_len, server_adress_val, server_port, next_state);
SendPacket(0x00, handshake_packet);
byte[] username_val = Encoding.UTF8.GetBytes(handler.getUsername());
byte[] username_val = Encoding.UTF8.GetBytes(handler.GetUsername());
byte[] username_len = getVarInt(username_val.Length);
byte[] login_packet = concatBytes(username_len, username_val);
@ -478,7 +478,7 @@ namespace MinecraftClient.Protocol.Handlers
string serverID = readNextString(ref packetData);
byte[] Serverkey = readNextByteArray(ref packetData);
byte[] token = readNextByteArray(ref packetData);
return StartEncryption(handler.getUserUUID(), handler.getSessionID(), token, serverID, Serverkey);
return StartEncryption(handler.GetUserUUID(), handler.GetSessionID(), token, serverID, Serverkey);
}
else if (packetID == 0x02) //Login successful
{

View file

@ -16,12 +16,12 @@ namespace MinecraftClient.Protocol
/* The MinecraftCom Hanler must
* provide these getters */
int getServerPort();
string getServerHost();
string getUsername();
string getUserUUID();
string getSessionID();
string[] getOnlinePlayers();
int GetServerPort();
string GetServerHost();
string GetUsername();
string GetUserUUID();
string GetSessionID();
string[] GetOnlinePlayers();
/// <summary>
/// This method is called when the protocol handler receives a chat message

View file

@ -149,7 +149,7 @@ namespace MinecraftClient
{
case "login": Login = argValue; break;
case "password": Password = argValue; break;
case "serverip": setServerIP(argValue); break;
case "serverip": SetServerIP(argValue); break;
case "singlecommand": SingleCommand = argValue; break;
case "language": Language = argValue; break;
case "consoletitle": ConsoleTitle = argValue; break;
@ -204,7 +204,7 @@ namespace MinecraftClient
if (server_data.Length == 2
&& server_data[0] != "localhost"
&& !server_data[0].Contains('.')
&& setServerIP(server_data[1]))
&& SetServerIP(server_data[1]))
Servers[server_data[0]]
= new KeyValuePair<string, ushort>(ServerIP, ServerPort);
}
@ -313,7 +313,7 @@ namespace MinecraftClient
break;
case ParseMode.AppVars:
setVar(argName, argValue);
SetVar(argName, argValue);
break;
case ParseMode.AutoRespond:
@ -433,7 +433,7 @@ namespace MinecraftClient
/// </summary>
/// <returns>True if the account was found and loaded</returns>
public static bool setAccount(string accountAlias)
public static bool SetAccount(string accountAlias)
{
accountAlias = accountAlias.ToLower();
if (Accounts.ContainsKey(accountAlias))
@ -450,7 +450,7 @@ namespace MinecraftClient
/// </summary>
/// <returns>True if the server IP was valid and loaded, false otherwise</returns>
public static bool setServerIP(string server)
public static bool SetServerIP(string server)
{
server = server.ToLower();
string[] sip = server.Split(':');
@ -489,7 +489,7 @@ namespace MinecraftClient
/// <param name="varData">Value of the variable</param>
/// <returns>True if the parameters were valid</returns>
public static bool setVar(string varName, string varData)
public static bool SetVar(string varName, string varData)
{
varName = new string(varName.TakeWhile(char.IsLetterOrDigit).ToArray()).ToLower();
if (varName.Length > 0)
@ -500,13 +500,26 @@ namespace MinecraftClient
else return false;
}
/// <summary>
/// Get a custom %variable% or null if the variable does not exist
/// </summary>
/// <param name="varName">Variable name</param>
/// <returns>The value or null if the variable does not exists</returns>
public static string GetVar(string varName)
{
if (AppVars.ContainsKey(varName))
return AppVars[varName];
return null;
}
/// <summary>
/// Replace %variables% with their value
/// </summary>
/// <param name="str">String to parse</param>
/// <returns>Modifier string</returns>
public static string expandVars(string str)
public static string ExpandVars(string str)
{
StringBuilder result = new StringBuilder();
for (int i = 0; i < str.Length; i++)

View file

@ -0,0 +1,15 @@
//MCCScript 1.0
/* This is a sample script for Minecraft Console Client
* The code provided in this file will be compiled at runtime and executed
* Allowed instructions: Any C# code AND all methods provided by the bot API */
for (int i = 0; i < 5; i++)
{
int count = GetVarAsInt("test");
count++;
SetVar("test", count);
SendText("Hello World no. " + count);
PerformInternalCommand("log Sleeping for 5 seconds...");
Thread.Sleep(5000);
}