mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Add support for C# script extensions
- Allow defining function for use into the script - Allow defining a ChatBot for loading it into MCC - Improve sample script and add more examples - Todo add new documentation into the readme file
This commit is contained in:
parent
a6b3bf0481
commit
e29b4ee545
6 changed files with 115 additions and 26 deletions
|
|
@ -33,9 +33,10 @@ namespace MinecraftClient
|
||||||
{
|
{
|
||||||
public enum DisconnectReason { InGameKick, LoginRejected, ConnectionLost };
|
public enum DisconnectReason { InGameKick, LoginRejected, ConnectionLost };
|
||||||
|
|
||||||
//Will be automatically set on bot loading, don't worry about this
|
//Handler will be automatically set on bot loading, don't worry about this
|
||||||
public void SetHandler(McTcpClient handler) { this._handler = handler; }
|
public void SetHandler(McTcpClient handler) { this._handler = handler; }
|
||||||
public void SetMaster(ChatBot master) { this.master = master; }
|
protected void SetMaster(ChatBot master) { this.master = master; }
|
||||||
|
protected void LoadBot(ChatBot bot) { Handler.BotUnLoad(bot); Handler.BotLoad(bot); }
|
||||||
private McTcpClient Handler { get { return master != null ? master.Handler : _handler; } }
|
private McTcpClient Handler { get { return master != null ? master.Handler : _handler; } }
|
||||||
private McTcpClient _handler = null;
|
private McTcpClient _handler = null;
|
||||||
private ChatBot master = null;
|
private ChatBot master = null;
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ namespace MinecraftClient.ChatBots
|
||||||
tpause = new ManualResetEvent(false);
|
tpause = new ManualResetEvent(false);
|
||||||
thread = new Thread(() =>
|
thread = new Thread(() =>
|
||||||
{
|
{
|
||||||
if (!RunCSharpScript(String.Join("\n", lines), file, tpause) && owner != null)
|
if (!RunCSharpScript() && owner != null)
|
||||||
SendPrivateMessage(owner, "Script '" + file + "' failed to run.");
|
SendPrivateMessage(owner, "Script '" + file + "' failed to run.");
|
||||||
});
|
});
|
||||||
thread.Start();
|
thread.Start();
|
||||||
|
|
@ -160,16 +160,37 @@ namespace MinecraftClient.ChatBots
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool RunCSharpScript(string script, string filename = "C# Script", ManualResetEvent tpause = null)
|
private bool RunCSharpScript()
|
||||||
{
|
{
|
||||||
//Script compatibility check for handling future versions differently
|
//Script compatibility check for handling future versions differently
|
||||||
if (!script.ToLower().StartsWith("//mccscript 1.0"))
|
if (lines.Length < 1 || lines[0] != "//MCCScript 1.0")
|
||||||
{
|
{
|
||||||
ConsoleIO.WriteLineFormatted("§8Script file '" + filename + "' does not start with a valid //MCCScript comment.");
|
LogToConsole("Script file '" + file + "' does not start with a valid //MCCScript identifier.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create a simple ChatBot class from the given script, allowing access to ChatBot API
|
//Process different sections of the script file
|
||||||
|
bool scriptMain = true;
|
||||||
|
List<string> script = new List<string>();
|
||||||
|
List<string> extensions = new List<string>();
|
||||||
|
foreach (string line in lines)
|
||||||
|
{
|
||||||
|
if (line.StartsWith("//MCCScript"))
|
||||||
|
{
|
||||||
|
if (line.EndsWith("Extensions"))
|
||||||
|
scriptMain = false;
|
||||||
|
}
|
||||||
|
else if (scriptMain)
|
||||||
|
{
|
||||||
|
script.Add(line);
|
||||||
|
//Add breakpoints for step-by-step execution of the script
|
||||||
|
if (tpause != null && line.Trim().EndsWith(";"))
|
||||||
|
script.Add("tpause.WaitOne();");
|
||||||
|
}
|
||||||
|
else extensions.Add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Generate a ChatBot class, allowing access to the ChatBot API
|
||||||
string code = String.Join("\n", new string[]
|
string code = String.Join("\n", new string[]
|
||||||
{
|
{
|
||||||
"using System;",
|
"using System;",
|
||||||
|
|
@ -178,12 +199,12 @@ namespace MinecraftClient.ChatBots
|
||||||
"using MinecraftClient;",
|
"using MinecraftClient;",
|
||||||
"namespace ScriptLoader {",
|
"namespace ScriptLoader {",
|
||||||
"public class Script : ChatBot {",
|
"public class Script : ChatBot {",
|
||||||
"public void Run(ChatBot master, ManualResetEvent tpause) {",
|
"public void __run(ChatBot master, ManualResetEvent tpause) {",
|
||||||
"SetMaster(master);",
|
"SetMaster(master);",
|
||||||
tpause != null
|
String.Join("\n", script),
|
||||||
? script.Replace(";\n", ";\ntpause.WaitOne();\n")
|
"}",
|
||||||
: script,
|
String.Join("\n", extensions),
|
||||||
"}}}",
|
"}}",
|
||||||
});
|
});
|
||||||
|
|
||||||
//Compile the C# class in memory using all the currently loaded assemblies
|
//Compile the C# class in memory using all the currently loaded assemblies
|
||||||
|
|
@ -202,16 +223,16 @@ namespace MinecraftClient.ChatBots
|
||||||
//Process compile warnings and errors
|
//Process compile warnings and errors
|
||||||
if (result.Errors.Count > 0)
|
if (result.Errors.Count > 0)
|
||||||
{
|
{
|
||||||
ConsoleIO.WriteLineFormatted("§8Error loading '" + filename + "':\n" + result.Errors[0].ErrorText);
|
LogToConsole("Error loading '" + file + "':\n" + result.Errors[0].ErrorText);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Run the compiled script with exception handling
|
//Run the compiled script with exception handling
|
||||||
object compiledScript = result.CompiledAssembly.CreateInstance("ScriptLoader.Script");
|
object compiledScript = result.CompiledAssembly.CreateInstance("ScriptLoader.Script");
|
||||||
try { compiledScript.GetType().GetMethod("Run").Invoke(compiledScript, new object[] { this, tpause }); }
|
try { compiledScript.GetType().GetMethod("__run").Invoke(compiledScript, new object[] { this, tpause }); }
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
ConsoleIO.WriteLineFormatted("§8Runtime error for '" + filename + "':\n" + e);
|
LogToConsole("Runtime error for '" + file + "':\n" + e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -94,9 +94,9 @@ namespace MinecraftClient
|
||||||
public static string AutoRespond_Matches = "matches.ini";
|
public static string AutoRespond_Matches = "matches.ini";
|
||||||
|
|
||||||
//Custom app variables and Minecraft accounts
|
//Custom app variables and Minecraft accounts
|
||||||
private static Dictionary<string, string> AppVars = new Dictionary<string, string>();
|
private static readonly Dictionary<string, string> AppVars = new Dictionary<string, string>();
|
||||||
private static Dictionary<string, KeyValuePair<string, string>> Accounts = new Dictionary<string, KeyValuePair<string, string>>();
|
private static readonly Dictionary<string, KeyValuePair<string, string>> Accounts = new Dictionary<string, KeyValuePair<string, string>>();
|
||||||
private static Dictionary<string, KeyValuePair<string, ushort>> Servers = new Dictionary<string, KeyValuePair<string, ushort>>();
|
private static readonly Dictionary<string, KeyValuePair<string, ushort>> Servers = new Dictionary<string, KeyValuePair<string, ushort>>();
|
||||||
|
|
||||||
private enum ParseMode { Default, Main, AppVars, Proxy, AntiAFK, Hangman, Alerts, ChatLog, AutoRelog, ScriptScheduler, RemoteControl, AutoRespond };
|
private enum ParseMode { Default, Main, AppVars, Proxy, AntiAFK, Hangman, Alerts, ChatLog, AutoRelog, ScriptScheduler, RemoteControl, AutoRespond };
|
||||||
|
|
||||||
|
|
@ -490,6 +490,8 @@ namespace MinecraftClient
|
||||||
/// <returns>True if the parameters were valid</returns>
|
/// <returns>True if the parameters were valid</returns>
|
||||||
|
|
||||||
public static bool SetVar(string varName, string varData)
|
public static bool SetVar(string varName, string varData)
|
||||||
|
{
|
||||||
|
lock (AppVars)
|
||||||
{
|
{
|
||||||
varName = new string(varName.TakeWhile(char.IsLetterOrDigit).ToArray()).ToLower();
|
varName = new string(varName.TakeWhile(char.IsLetterOrDigit).ToArray()).ToLower();
|
||||||
if (varName.Length > 0)
|
if (varName.Length > 0)
|
||||||
|
|
@ -499,6 +501,7 @@ namespace MinecraftClient
|
||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a custom %variable% or null if the variable does not exist
|
/// Get a custom %variable% or null if the variable does not exist
|
||||||
|
|
|
||||||
30
MinecraftClient/config/sample-script-extended.cs
Normal file
30
MinecraftClient/config/sample-script-extended.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
//MCCScript 1.0
|
||||||
|
|
||||||
|
/* This script demonstrates how to add fields and methods */
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
int count = GetVarAsInt("test") + 1;
|
||||||
|
SetVar("test", count);
|
||||||
|
SendHelloWorld(count);
|
||||||
|
SleepBetweenSends();
|
||||||
|
}
|
||||||
|
|
||||||
|
//MCCScript Extensions
|
||||||
|
|
||||||
|
/* Here you can define methods for use into your script */
|
||||||
|
|
||||||
|
void SendHelloWorld(int count)
|
||||||
|
{
|
||||||
|
/* Warning: Do not make more than one server-related call into a method
|
||||||
|
* defined as a script extension eg SendText or switching servers,
|
||||||
|
* as execution flow is not managed in the Extensions section */
|
||||||
|
|
||||||
|
SendText("Hello World no. " + count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SleepBetweenSends()
|
||||||
|
{
|
||||||
|
LogToConsole("Sleeping for 5 seconds...");
|
||||||
|
Thread.Sleep(5000);
|
||||||
|
}
|
||||||
35
MinecraftClient/config/sample-script-with-chatbot.cs
Normal file
35
MinecraftClient/config/sample-script-with-chatbot.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
//MCCScript 1.0
|
||||||
|
|
||||||
|
/* This is a sample script that will load a ChatBot into Minecraft Console Client
|
||||||
|
* Simply execute the script once with /script or the script scheduler to load the bot */
|
||||||
|
|
||||||
|
LoadBot(new ExampleBot());
|
||||||
|
|
||||||
|
//MCCScript Extensions
|
||||||
|
|
||||||
|
/* The ChatBot class must be defined as an extension of the script in the Extensions section
|
||||||
|
* The class can override common methods from ChatBot.cs, take a look at MCC's source code */
|
||||||
|
|
||||||
|
public class ExampleBot : ChatBot
|
||||||
|
{
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
LogToConsole("Sucessfully Initialized!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void GetText(string text)
|
||||||
|
{
|
||||||
|
string message = "";
|
||||||
|
string username = "";
|
||||||
|
text = GetVerbatim(text);
|
||||||
|
|
||||||
|
if (IsChatMessage(text, ref message, ref username))
|
||||||
|
{
|
||||||
|
LogToConsole("Public message from " + username + ": " + message);
|
||||||
|
}
|
||||||
|
else if (IsPrivateMessage(text, ref message, ref username))
|
||||||
|
{
|
||||||
|
LogToConsole("Private message from " + username + ": " + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,10 +6,9 @@
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
int count = GetVarAsInt("test");
|
int count = GetVarAsInt("test") + 1;
|
||||||
count++;
|
|
||||||
SetVar("test", count);
|
SetVar("test", count);
|
||||||
SendText("Hello World no. " + count);
|
SendText("Hello World no. " + count);
|
||||||
PerformInternalCommand("log Sleeping for 5 seconds...");
|
LogToConsole("Sleeping for 5 seconds...");
|
||||||
Thread.Sleep(5000);
|
Thread.Sleep(5000);
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue