mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
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:
parent
3224c59eab
commit
3ce91188c7
22 changed files with 321 additions and 135 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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,18 +70,49 @@ 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 (csharp) //C# compiled script
|
||||
{
|
||||
//Initialize thread on first update
|
||||
if (thread == null)
|
||||
{
|
||||
tpause = new ManualResetEvent(false);
|
||||
thread = new Thread(() =>
|
||||
{
|
||||
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
|
||||
|
|
@ -82,13 +121,12 @@ namespace MinecraftClient.ChatBots
|
|||
{
|
||||
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)
|
||||
{
|
||||
if (instruction_line[0] != '#' && instruction_line[0] != '/' && instruction_line[1] != '/')
|
||||
{
|
||||
instruction_line = Settings.expandVars(instruction_line);
|
||||
instruction_line = Settings.ExpandVars(instruction_line);
|
||||
string instruction_name = instruction_line.Split(' ')[0];
|
||||
switch (instruction_name.ToLower())
|
||||
{
|
||||
|
|
@ -102,15 +140,15 @@ namespace MinecraftClient.ChatBots
|
|||
sleepticks = ticks;
|
||||
break;
|
||||
default:
|
||||
if (!performInternalCommand(instruction_line))
|
||||
if (!PerformInternalCommand(instruction_line))
|
||||
{
|
||||
sleepticks = 0; Update(); //Unknown command : process next line immediately
|
||||
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
|
||||
else { Update(); } //Comment: process next line immediately
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -121,4 +159,63 @@ namespace MinecraftClient.ChatBots
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 "";
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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] + "'.";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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"))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
15
MinecraftClient/config/sample-script.cs
Normal file
15
MinecraftClient/config/sample-script.cs
Normal 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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue