mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Fix all warnings & Trim (#2226)
* Fix AutoFishing crash * Fix all warnings * Remove DotNetZip. * Fix the usage of HttpClient.
This commit is contained in:
parent
4aa6c1c99f
commit
1d52d1eadd
227 changed files with 2201 additions and 43564 deletions
|
|
@ -1,11 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using DynamicRun.Builder;
|
||||
|
||||
namespace MinecraftClient
|
||||
|
|
@ -15,7 +13,7 @@ namespace MinecraftClient
|
|||
/// </summary>
|
||||
class CSharpRunner
|
||||
{
|
||||
private static readonly Dictionary<ulong, byte[]> CompileCache = new Dictionary<ulong, byte[]>();
|
||||
private static readonly Dictionary<ulong, byte[]> CompileCache = new();
|
||||
|
||||
/// <summary>
|
||||
/// Run the specified C# script file
|
||||
|
|
@ -27,7 +25,7 @@ namespace MinecraftClient
|
|||
/// <param name="run">Set to false to compile and cache the script without launching it</param>
|
||||
/// <exception cref="CSharpException">Thrown if an error occured</exception>
|
||||
/// <returns>Result of the execution, returned by the script</returns>
|
||||
public static object? Run(ChatBot apiHandler, string[] lines, string[] args, Dictionary<string, object> localVars, bool run = true)
|
||||
public static object? Run(ChatBot apiHandler, string[] lines, string[] args, Dictionary<string, object>? localVars, bool run = true)
|
||||
{
|
||||
//Script compatibility check for handling future versions differently
|
||||
if (lines.Length < 1 || lines[0] != "//MCCScript 1.0")
|
||||
|
|
@ -37,9 +35,9 @@ namespace MinecraftClient
|
|||
//Script hash for determining if it was previously compiled
|
||||
ulong scriptHash = QuickHash(lines);
|
||||
byte[]? assembly = null;
|
||||
|
||||
Compiler compiler = new Compiler();
|
||||
CompileRunner runner = new CompileRunner();
|
||||
|
||||
Compiler compiler = new();
|
||||
CompileRunner runner = new();
|
||||
|
||||
//No need to compile two scripts at the same time
|
||||
lock (CompileCache)
|
||||
|
|
@ -49,10 +47,10 @@ namespace MinecraftClient
|
|||
{
|
||||
//Process different sections of the script file
|
||||
bool scriptMain = true;
|
||||
List<string> script = new List<string>();
|
||||
List<string> extensions = new List<string>();
|
||||
List<string> libs = new List<string>();
|
||||
List<string> dlls = new List<string>();
|
||||
List<string> script = new();
|
||||
List<string> extensions = new();
|
||||
List<string> libs = new();
|
||||
List<string> dlls = new();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (line.StartsWith("//using"))
|
||||
|
|
@ -105,7 +103,7 @@ namespace MinecraftClient
|
|||
|
||||
//Compile the C# class in memory using all the currently loaded assemblies
|
||||
var result = compiler.Compile(code, Guid.NewGuid().ToString());
|
||||
|
||||
|
||||
//Process compile warnings and errors
|
||||
if (result.Failures != null)
|
||||
throw new CSharpException(CSErrorType.LoadError,
|
||||
|
|
@ -123,7 +121,8 @@ namespace MinecraftClient
|
|||
//Run the compiled assembly with exception handling
|
||||
if (run)
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
var compiled = runner.Execute(assembly!, args, localVars, apiHandler);
|
||||
return compiled;
|
||||
}
|
||||
|
|
@ -164,10 +163,10 @@ namespace MinecraftClient
|
|||
/// </summary>
|
||||
public class CSharpException : Exception
|
||||
{
|
||||
private CSErrorType _type;
|
||||
private readonly CSErrorType _type;
|
||||
public CSErrorType ExceptionType { get { return _type; } }
|
||||
public override string Message { get { return InnerException.Message; } }
|
||||
public override string ToString() { return InnerException.ToString(); }
|
||||
public override string Message { get { return InnerException!.Message; } }
|
||||
public override string ToString() { return InnerException!.ToString(); }
|
||||
public CSharpException(CSErrorType type, Exception inner)
|
||||
: base(inner != null ? inner.Message : "", inner)
|
||||
{
|
||||
|
|
@ -183,7 +182,7 @@ namespace MinecraftClient
|
|||
/// <summary>
|
||||
/// Holds local variables passed along with the script
|
||||
/// </summary>
|
||||
private Dictionary<string, object> localVars;
|
||||
private readonly Dictionary<string, object>? localVars;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new C# API Wrapper
|
||||
|
|
@ -191,7 +190,7 @@ namespace MinecraftClient
|
|||
/// <param name="apiHandler">ChatBot API Handler</param>
|
||||
/// <param name="tickHandler">ChatBot tick handler</param>
|
||||
/// <param name="localVars">Local variables passed along with the script</param>
|
||||
public CSharpAPI(ChatBot apiHandler, Dictionary<string , object> localVars)
|
||||
public CSharpAPI(ChatBot apiHandler, Dictionary<string, object>? localVars)
|
||||
{
|
||||
SetMaster(apiHandler);
|
||||
this.localVars = localVars;
|
||||
|
|
@ -215,8 +214,7 @@ namespace MinecraftClient
|
|||
/// <returns>TRUE if successfully sent (Deprectated, always returns TRUE for compatibility purposes with existing scripts)</returns>
|
||||
public bool SendText(object text)
|
||||
{
|
||||
base.SendText(text is string ? (string)text : text.ToString());
|
||||
return true;
|
||||
return base.SendText(text is string str ? str : (text.ToString() ?? string.Empty));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -225,12 +223,10 @@ namespace MinecraftClient
|
|||
/// <param name="command">The command to process</param>
|
||||
/// <param name="localVars">Local variables passed along with the internal command</param>
|
||||
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
|
||||
new public bool PerformInternalCommand(string command, Dictionary<string, object> localVars = null)
|
||||
new public bool PerformInternalCommand(string command, Dictionary<string, object>? localVars = null)
|
||||
{
|
||||
if (localVars == null)
|
||||
localVars = this.localVars;
|
||||
bool result = base.PerformInternalCommand(command, localVars);
|
||||
return result;
|
||||
localVars ??= this.localVars;
|
||||
return base.PerformInternalCommand(command, localVars);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -243,7 +239,8 @@ namespace MinecraftClient
|
|||
{
|
||||
if (extraAttempts == -999999)
|
||||
base.ReconnectToTheServer();
|
||||
else base.ReconnectToTheServer(extraAttempts);
|
||||
else
|
||||
base.ReconnectToTheServer(extraAttempts);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -291,11 +288,12 @@ namespace MinecraftClient
|
|||
/// </summary>
|
||||
/// <param name="varName">Name of the variable</param>
|
||||
/// <returns>Value of the variable or null if no variable</returns>
|
||||
public object GetVar(string varName)
|
||||
public object? GetVar(string varName)
|
||||
{
|
||||
if (localVars != null && localVars.ContainsKey(varName))
|
||||
return localVars[varName];
|
||||
return Settings.GetVar(varName);
|
||||
else
|
||||
return Settings.GetVar(varName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -317,26 +315,26 @@ namespace MinecraftClient
|
|||
/// <typeparam name="T">Variable type</typeparam>
|
||||
/// <param name="varName">Variable name</param>
|
||||
/// <returns>Variable as specified type or default value for this type</returns>
|
||||
public T GetVar<T>(string varName)
|
||||
public T? GetVar<T>(string varName)
|
||||
{
|
||||
object value = GetVar(varName);
|
||||
if (value is T)
|
||||
return (T)value;
|
||||
object? value = GetVar(varName);
|
||||
if (value is T Tval)
|
||||
return Tval;
|
||||
if (value != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
|
||||
if (converter != null)
|
||||
return (T)converter.ConvertFromString(value.ToString());
|
||||
return (T?)converter.ConvertFromString(value.ToString() ?? string.Empty);
|
||||
}
|
||||
catch (NotSupportedException) { /* Was worth trying */ }
|
||||
}
|
||||
return default(T);
|
||||
return default;
|
||||
}
|
||||
|
||||
//Named shortcuts for GetVar<type>(varname)
|
||||
public string GetVarAsString(string varName) { return GetVar<string>(varName); }
|
||||
public string? GetVarAsString(string varName) { return GetVar<string>(varName); }
|
||||
public int GetVarAsInt(string varName) { return GetVar<int>(varName); }
|
||||
public double GetVarAsDouble(string varName) { return GetVar<double>(varName); }
|
||||
public bool GetVarAsBool(string varName) { return GetVar<bool>(varName); }
|
||||
|
|
@ -374,12 +372,18 @@ namespace MinecraftClient
|
|||
/// <param name="script">Script to call</param>
|
||||
/// <param name="args">Arguments to pass to the script</param>
|
||||
/// <returns>An object returned by the script, or null</returns>
|
||||
public object CallScript(string script, string[] args)
|
||||
public object? CallScript(string script, string[] args)
|
||||
{
|
||||
string[] lines = null;
|
||||
ChatBots.Script.LookForScript(ref script);
|
||||
try { lines = File.ReadAllLines(script, Encoding.UTF8); }
|
||||
catch (Exception e) { throw new CSharpException(CSErrorType.FileReadError, e); }
|
||||
string[] lines;
|
||||
try
|
||||
{
|
||||
lines = File.ReadAllLines(script, Encoding.UTF8);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CSharpException(CSErrorType.FileReadError, e);
|
||||
}
|
||||
return CSharpRunner.Run(this, lines, args, localVars);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Text.RegularExpressions;
|
||||
using MinecraftClient.Inventory;
|
||||
using MinecraftClient.Mapping;
|
||||
|
|
@ -32,17 +31,17 @@ namespace MinecraftClient
|
|||
public enum DisconnectReason { InGameKick, LoginRejected, ConnectionLost, UserLogout };
|
||||
|
||||
//Handler will be automatically set on bot loading, don't worry about this
|
||||
public void SetHandler(McClient handler) { this._handler = handler; }
|
||||
public void SetHandler(McClient handler) { _handler = handler; }
|
||||
protected void SetMaster(ChatBot master) { this.master = master; }
|
||||
protected void LoadBot(ChatBot bot) { Handler.BotUnLoad(bot); Handler.BotLoad(bot); }
|
||||
protected List<ChatBot> GetLoadedChatBots() { return Handler.GetLoadedChatBots(); }
|
||||
protected void UnLoadBot(ChatBot bot) { Handler.BotUnLoad(bot); }
|
||||
private McClient _handler = null;
|
||||
private ChatBot master = null;
|
||||
private List<string> registeredPluginChannels = new List<String>();
|
||||
private List<string> registeredCommands = new List<string>();
|
||||
private object delayTasksLock = new object();
|
||||
private List<TaskWithDelay> delayedTasks = new List<TaskWithDelay>();
|
||||
private McClient? _handler = null;
|
||||
private ChatBot? master = null;
|
||||
private readonly List<string> registeredPluginChannels = new();
|
||||
private readonly List<string> registeredCommands = new();
|
||||
private readonly object delayTasksLock = new();
|
||||
private readonly List<TaskWithDelay> delayedTasks = new();
|
||||
private McClient Handler
|
||||
{
|
||||
get
|
||||
|
|
@ -67,7 +66,7 @@ namespace MinecraftClient
|
|||
{
|
||||
if (delayedTasks.Count > 0)
|
||||
{
|
||||
List<int> tasksToRemove = new List<int>();
|
||||
List<int> tasksToRemove = new();
|
||||
for (int i = 0; i < delayedTasks.Count; i++)
|
||||
{
|
||||
if (delayedTasks[i].Tick())
|
||||
|
|
@ -310,7 +309,7 @@ namespace MinecraftClient
|
|||
/// <param name="entity"> Entity</param>
|
||||
/// <param name="slot"> Equipment slot. 0: main hand, 1: off hand, 2–5: armor slot (2: boots, 3: leggings, 4: chestplate, 5: helmet)</param>
|
||||
/// <param name="item"> Item)</param>
|
||||
public virtual void OnEntityEquipment(Entity entity, int slot, Item item) { }
|
||||
public virtual void OnEntityEquipment(Entity entity, int slot, Item? item) { }
|
||||
|
||||
/// <summary>
|
||||
/// Called when an entity has effect applied
|
||||
|
|
@ -439,9 +438,9 @@ namespace MinecraftClient
|
|||
/// <param name="command">The command to process</param>
|
||||
/// <param name="localVars">Local variables passed along with the command</param>
|
||||
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
|
||||
protected bool PerformInternalCommand(string command, Dictionary<string, object> localVars = null)
|
||||
protected bool PerformInternalCommand(string command, Dictionary<string, object>? localVars = null)
|
||||
{
|
||||
string temp = "";
|
||||
string? temp = "";
|
||||
return Handler.PerformInternalCommand(command, ref temp, localVars);
|
||||
}
|
||||
|
||||
|
|
@ -452,7 +451,7 @@ namespace MinecraftClient
|
|||
/// <param name="response_msg">May contain a confirmation or error message after processing the command, or "" otherwise.</param>
|
||||
/// <param name="localVars">Local variables passed along with the command</param>
|
||||
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
|
||||
protected bool PerformInternalCommand(string command, ref string response_msg, Dictionary<string, object> localVars = null)
|
||||
protected bool PerformInternalCommand(string command, ref string? response_msg, Dictionary<string, object>? localVars = null)
|
||||
{
|
||||
return Handler.PerformInternalCommand(command, ref response_msg, localVars);
|
||||
}
|
||||
|
|
@ -460,7 +459,7 @@ namespace MinecraftClient
|
|||
/// <summary>
|
||||
/// Remove color codes ("§c") from a text message received from the server
|
||||
/// </summary>
|
||||
public static string GetVerbatim(string text)
|
||||
public static string GetVerbatim(string? text)
|
||||
{
|
||||
if (String.IsNullOrEmpty(text))
|
||||
return String.Empty;
|
||||
|
|
@ -534,9 +533,9 @@ namespace MinecraftClient
|
|||
{
|
||||
if (tmp.Length > 4 && tmp[2] == "to" && tmp[3] == "you:")
|
||||
{
|
||||
message = text.Substring(tmp[0].Length + 18); //MC 1.7
|
||||
message = text[(tmp[0].Length + 18)..]; //MC 1.7
|
||||
}
|
||||
else message = text.Substring(tmp[0].Length + 10); //MC 1.5
|
||||
else message = text[(tmp[0].Length + 10)..]; //MC 1.5
|
||||
sender = tmp[0];
|
||||
return IsValidName(sender);
|
||||
}
|
||||
|
|
@ -547,9 +546,9 @@ namespace MinecraftClient
|
|||
else if (text[0] == '[' && tmp.Length > 3 && tmp[1] == "->"
|
||||
&& (tmp[2].ToLower() == "me]" || tmp[2].ToLower() == "moi]")) //'me' is replaced by 'moi' in french servers
|
||||
{
|
||||
message = text.Substring(tmp[0].Length + 4 + tmp[2].Length + 1);
|
||||
sender = tmp[0].Substring(1);
|
||||
if (sender[0] == '~') { sender = sender.Substring(1); }
|
||||
message = text[(tmp[0].Length + 4 + tmp[2].Length + 1)..];
|
||||
sender = tmp[0][1..];
|
||||
if (sender[0] == '~') { sender = sender[1..]; }
|
||||
return IsValidName(sender);
|
||||
}
|
||||
|
||||
|
|
@ -558,22 +557,22 @@ namespace MinecraftClient
|
|||
else if (text[0] == '[' && tmp.Length > 3 && tmp[1] == "@"
|
||||
&& (tmp[2].ToLower() == "me]" || tmp[2].ToLower() == "moi]")) //'me' is replaced by 'moi' in french servers
|
||||
{
|
||||
message = text.Substring(tmp[0].Length + 4 + tmp[2].Length + 0);
|
||||
sender = tmp[0].Substring(1);
|
||||
if (sender[0] == '~') { sender = sender.Substring(1); }
|
||||
message = text[(tmp[0].Length + 4 + tmp[2].Length + 0)..];
|
||||
sender = tmp[0][1..];
|
||||
if (sender[0] == '~') { sender = sender[1..]; }
|
||||
return IsValidName(sender);
|
||||
}
|
||||
|
||||
//Detect Essentials (Bukkit) /me messages with some custom prefix
|
||||
//[Prefix] [Someone -> me] message
|
||||
//[Prefix] [~Someone -> me] message
|
||||
else if (text[0] == '[' && tmp[0][tmp[0].Length - 1] == ']'
|
||||
else if (text[0] == '[' && tmp[0][^1] == ']'
|
||||
&& tmp[1][0] == '[' && tmp.Length > 4 && tmp[2] == "->"
|
||||
&& (tmp[3].ToLower() == "me]" || tmp[3].ToLower() == "moi]"))
|
||||
{
|
||||
message = text.Substring(tmp[0].Length + 1 + tmp[1].Length + 4 + tmp[3].Length + 1);
|
||||
sender = tmp[1].Substring(1);
|
||||
if (sender[0] == '~') { sender = sender.Substring(1); }
|
||||
message = text[(tmp[0].Length + 1 + tmp[1].Length + 4 + tmp[3].Length + 1)..];
|
||||
sender = tmp[1][1..];
|
||||
if (sender[0] == '~') { sender = sender[1..]; }
|
||||
return IsValidName(sender);
|
||||
}
|
||||
|
||||
|
|
@ -583,9 +582,9 @@ namespace MinecraftClient
|
|||
else if (text[0] == '[' && tmp.Length > 3 && tmp[2] == "->"
|
||||
&& (tmp[3].ToLower() == "me]" || tmp[3].ToLower() == "moi]"))
|
||||
{
|
||||
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); }
|
||||
message = text[(tmp[0].Length + 1 + tmp[1].Length + 4 + tmp[2].Length + 1)..];
|
||||
sender = tmp[0][1..];
|
||||
if (sender[0] == '~') { sender = sender[1..]; }
|
||||
return IsValidName(sender);
|
||||
}
|
||||
|
||||
|
|
@ -593,8 +592,8 @@ namespace MinecraftClient
|
|||
//From Someone: message
|
||||
else if (text.StartsWith("From "))
|
||||
{
|
||||
sender = text.Substring(5).Split(':')[0];
|
||||
message = text.Substring(text.IndexOf(':') + 2);
|
||||
sender = text[5..].Split(':')[0];
|
||||
message = text[(text.IndexOf(':') + 2)..];
|
||||
return IsValidName(sender);
|
||||
}
|
||||
else return false;
|
||||
|
|
@ -646,15 +645,15 @@ namespace MinecraftClient
|
|||
{
|
||||
try
|
||||
{
|
||||
text = text.Substring(1);
|
||||
text = text[1..];
|
||||
string[] tmp2 = text.Split('>');
|
||||
sender = tmp2[0];
|
||||
message = text.Substring(sender.Length + 2);
|
||||
message = text[(sender.Length + 2)..];
|
||||
if (message.Length > 1 && message[0] == ' ')
|
||||
{ message = message.Substring(1); }
|
||||
{ message = message[1..]; }
|
||||
tmp2 = sender.Split(' ');
|
||||
sender = tmp2[tmp2.Length - 1];
|
||||
if (sender[0] == '~') { sender = sender.Substring(1); }
|
||||
sender = tmp2[^1];
|
||||
if (sender[0] == '~') { sender = sender[1..]; }
|
||||
return IsValidName(sender);
|
||||
}
|
||||
catch (IndexOutOfRangeException) { /* Not a vanilla/faction message */ }
|
||||
|
|
@ -669,9 +668,9 @@ namespace MinecraftClient
|
|||
try
|
||||
{
|
||||
int name_end = text.IndexOf(':');
|
||||
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);
|
||||
int name_start = text[..name_end].LastIndexOf(']') + 2;
|
||||
sender = text[name_start..name_end];
|
||||
message = text[(name_end + 2)..];
|
||||
return IsValidName(sender);
|
||||
}
|
||||
catch (IndexOutOfRangeException) { /* Not a herochat message */ }
|
||||
|
|
@ -698,7 +697,7 @@ namespace MinecraftClient
|
|||
if (prefix.All(c => char.IsLetterOrDigit(c) || new char[] { '*', '<', '>', '_' }.Contains(c))
|
||||
&& semicolon == ":")
|
||||
{
|
||||
message = text.Substring(prefix.Length + user.Length + 4);
|
||||
message = text[(prefix.Length + user.Length + 4)..];
|
||||
return IsValidName(user);
|
||||
}
|
||||
}
|
||||
|
|
@ -750,13 +749,12 @@ namespace MinecraftClient
|
|||
|| (tmp[0].StartsWith("[") && tmp[0].EndsWith("]")))
|
||||
&& tmp.Length > 1)
|
||||
sender = tmp[1];
|
||||
|
||||
//Username has requested...
|
||||
else sender = tmp[0];
|
||||
else //Username has requested..
|
||||
sender = tmp[0];
|
||||
|
||||
//~Username has requested...
|
||||
if (sender.Length > 1 && sender[0] == '~')
|
||||
sender = sender.Substring(1);
|
||||
sender = sender[1..];
|
||||
|
||||
//Final check on username validity
|
||||
return IsValidName(sender);
|
||||
|
|
@ -770,19 +768,19 @@ namespace MinecraftClient
|
|||
/// Write some text in the console. Nothing will be sent to the server.
|
||||
/// </summary>
|
||||
/// <param name="text">Log text to write</param>
|
||||
protected void LogToConsole(object text)
|
||||
protected void LogToConsole(object? text)
|
||||
{
|
||||
if (_handler == null || master == null)
|
||||
ConsoleIO.WriteLogLine(String.Format("[{0}] {1}", this.GetType().Name, text));
|
||||
ConsoleIO.WriteLogLine(String.Format("[{0}] {1}", GetType().Name, text));
|
||||
else
|
||||
Handler.Log.Info(String.Format("[{0}] {1}", this.GetType().Name, text));
|
||||
Handler.Log.Info(String.Format("[{0}] {1}", GetType().Name, text));
|
||||
string logfile = Settings.ExpandVars(Settings.chatbotLogFile);
|
||||
|
||||
if (!String.IsNullOrEmpty(logfile))
|
||||
{
|
||||
if (!File.Exists(logfile))
|
||||
{
|
||||
try { Directory.CreateDirectory(Path.GetDirectoryName(logfile)); }
|
||||
try { Directory.CreateDirectory(Path.GetDirectoryName(logfile)!); }
|
||||
catch { return; /* Invalid path or access denied */ }
|
||||
try { File.WriteAllText(logfile, ""); }
|
||||
catch { return; /* Invalid file name or access denied */ }
|
||||
|
|
@ -817,7 +815,7 @@ namespace MinecraftClient
|
|||
/// </summary>
|
||||
/// <param name="key">Translation key</param>
|
||||
/// <param name="args"></param>
|
||||
protected void LogDebugToConsoleTranslated(string key, params object[] args)
|
||||
protected void LogDebugToConsoleTranslated(string key, params object?[] args)
|
||||
{
|
||||
LogDebugToConsole(Translations.TryGet(key, args));
|
||||
}
|
||||
|
|
@ -831,7 +829,7 @@ namespace MinecraftClient
|
|||
protected void ReconnectToTheServer(int ExtraAttempts = 3, int delaySeconds = 0)
|
||||
{
|
||||
if (Settings.DebugMessages)
|
||||
ConsoleIO.WriteLogLine(Translations.Get("chatbot.reconnect", this.GetType().Name));
|
||||
ConsoleIO.WriteLogLine(Translations.Get("chatbot.reconnect", GetType().Name));
|
||||
McClient.ReconnectionAttemptsLeft = ExtraAttempts;
|
||||
Program.Restart(delaySeconds);
|
||||
}
|
||||
|
|
@ -872,7 +870,7 @@ namespace MinecraftClient
|
|||
/// <param name="filename">File name</param>
|
||||
/// <param name="playername">Player name to send error messages, if applicable</param>
|
||||
/// <param name="localVars">Local variables for use in the Script</param>
|
||||
protected void RunScript(string filename, string playername = null, Dictionary<string, object> localVars = null)
|
||||
protected void RunScript(string filename, string? playername = null, Dictionary<string, object>? localVars = null)
|
||||
{
|
||||
Handler.BotLoad(new ChatBots.Script(filename, playername, localVars));
|
||||
}
|
||||
|
|
@ -955,11 +953,9 @@ namespace MinecraftClient
|
|||
/// Get the current Minecraft World
|
||||
/// </summary>
|
||||
/// <returns>Minecraft world or null if associated setting is disabled</returns>
|
||||
protected Mapping.World GetWorld()
|
||||
protected World GetWorld()
|
||||
{
|
||||
if (GetTerrainEnabled())
|
||||
return Handler.GetWorld();
|
||||
return null;
|
||||
return Handler.GetWorld();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -1078,7 +1074,7 @@ namespace MinecraftClient
|
|||
else
|
||||
{
|
||||
LogToConsole("File not found: " + System.IO.Path.GetFullPath(file));
|
||||
return new string[0];
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1181,7 +1177,7 @@ namespace MinecraftClient
|
|||
/// <param name="channel">The name of the channel to register</param>
|
||||
protected void RegisterPluginChannel(string channel)
|
||||
{
|
||||
this.registeredPluginChannels.Add(channel);
|
||||
registeredPluginChannels.Add(channel);
|
||||
Handler.RegisterPluginChannel(channel, this);
|
||||
}
|
||||
|
||||
|
|
@ -1191,7 +1187,7 @@ namespace MinecraftClient
|
|||
/// <param name="channel">The name of the channel to unregister</param>
|
||||
protected void UnregisterPluginChannel(string channel)
|
||||
{
|
||||
this.registeredPluginChannels.RemoveAll(chan => chan == channel);
|
||||
registeredPluginChannels.RemoveAll(chan => chan == channel);
|
||||
Handler.UnregisterPluginChannel(channel, this);
|
||||
}
|
||||
|
||||
|
|
@ -1207,7 +1203,7 @@ namespace MinecraftClient
|
|||
{
|
||||
if (!sendEvenIfNotRegistered)
|
||||
{
|
||||
if (!this.registeredPluginChannels.Contains(channel))
|
||||
if (!registeredPluginChannels.Contains(channel))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1258,7 +1254,7 @@ namespace MinecraftClient
|
|||
/// <param name="itemType">Item type</param>
|
||||
/// <param name="count">Item count</param>
|
||||
/// <returns>TRUE if item given successfully</returns>
|
||||
protected bool CreativeGive(int slot, ItemType itemType, int count, Dictionary<string, object> nbt = null)
|
||||
protected bool CreativeGive(int slot, ItemType itemType, int count, Dictionary<string, object>? nbt = null)
|
||||
{
|
||||
return Handler.DoCreativeGive(slot, itemType, count, nbt);
|
||||
}
|
||||
|
|
@ -1331,7 +1327,7 @@ namespace MinecraftClient
|
|||
protected Container GetPlayerInventory()
|
||||
{
|
||||
Container container = Handler.GetPlayerInventory();
|
||||
return container == null ? null : new Container(container.ID, container.Type, container.Title, container.Items);
|
||||
return new Container(container.ID, container.Type, container.Title, container.Items);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -1591,9 +1587,9 @@ namespace MinecraftClient
|
|||
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)
|
||||
{
|
||||
return this.Runner(command, getArgs(command));
|
||||
return Runner(command, GetArgs(command));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -1605,10 +1601,10 @@ namespace MinecraftClient
|
|||
/// <param name="callback">Method for handling the command</param>
|
||||
public ChatBotCommand(string cmdName, string cmdDesc, string cmdUsage, CommandRunner callback)
|
||||
{
|
||||
this._cmdName = cmdName;
|
||||
this._cmdDesc = cmdDesc;
|
||||
this._cmdUsage = cmdUsage;
|
||||
this.Runner = callback;
|
||||
_cmdName = cmdName;
|
||||
_cmdDesc = cmdDesc;
|
||||
_cmdUsage = cmdUsage;
|
||||
Runner = callback;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ namespace DynamicRun.Builder
|
|||
{
|
||||
internal class CompileRunner
|
||||
{
|
||||
public object? Execute(byte[] compiledAssembly, string[] args, Dictionary<string, object> localVars, ChatBot apiHandler)
|
||||
public object? Execute(byte[] compiledAssembly, string[] args, Dictionary<string, object>? localVars, ChatBot apiHandler)
|
||||
{
|
||||
var assemblyLoadContextWeakRef = LoadAndExecute(compiledAssembly, args, localVars, apiHandler);
|
||||
|
||||
|
|
@ -29,20 +29,18 @@ namespace DynamicRun.Builder
|
|||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Tuple<WeakReference, object?> LoadAndExecute(byte[] compiledAssembly, string[] args, Dictionary<string, object> localVars, ChatBot apiHandler)
|
||||
private static Tuple<WeakReference, object?> LoadAndExecute(byte[] compiledAssembly, string[] args, Dictionary<string, object>? localVars, ChatBot apiHandler)
|
||||
{
|
||||
using (var asm = new MemoryStream(compiledAssembly))
|
||||
{
|
||||
var assemblyLoadContext = new SimpleUnloadableAssemblyLoadContext();
|
||||
using var asm = new MemoryStream(compiledAssembly);
|
||||
var assemblyLoadContext = new SimpleUnloadableAssemblyLoadContext();
|
||||
|
||||
var assembly = assemblyLoadContext.LoadFromStream(asm);
|
||||
var compiledScript = assembly.CreateInstance("ScriptLoader.Script");
|
||||
var execResult = compiledScript.GetType().GetMethod("__run").Invoke(compiledScript, new object[] { new CSharpAPI(apiHandler, localVars), args });
|
||||
|
||||
assemblyLoadContext.Unload();
|
||||
var assembly = assemblyLoadContext.LoadFromStream(asm);
|
||||
var compiledScript = assembly.CreateInstance("ScriptLoader.Script")!;
|
||||
var execResult = compiledScript.GetType().GetMethod("__run")!.Invoke(compiledScript, new object[] { new CSharpAPI(apiHandler, localVars), args });
|
||||
|
||||
return new (new WeakReference(assemblyLoadContext), execResult);
|
||||
}
|
||||
assemblyLoadContext.Unload();
|
||||
|
||||
return new(new WeakReference(assemblyLoadContext), execResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,39 +18,39 @@ using SingleFileExtractor.Core;
|
|||
|
||||
namespace DynamicRun.Builder
|
||||
{
|
||||
internal class Compiler
|
||||
internal class Compiler
|
||||
{
|
||||
public CompileResult Compile(string filepath, string fileName)
|
||||
{
|
||||
ConsoleIO.WriteLogLine($"Starting compilation of: '{fileName}'");
|
||||
|
||||
using (var peStream = new MemoryStream())
|
||||
using var peStream = new MemoryStream();
|
||||
var result = GenerateCode(filepath, fileName).Emit(peStream);
|
||||
|
||||
if (!result.Success)
|
||||
{
|
||||
var result = GenerateCode(filepath, fileName).Emit(peStream);
|
||||
ConsoleIO.WriteLogLine("Compilation done with error.");
|
||||
|
||||
if (!result.Success)
|
||||
var failures = result.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error);
|
||||
|
||||
return new CompileResult()
|
||||
{
|
||||
ConsoleIO.WriteLogLine("Compilation done with error.");
|
||||
|
||||
var failures = result.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error);
|
||||
|
||||
return new CompileResult() {
|
||||
Assembly = null,
|
||||
HasCompiledSucecssfully = false,
|
||||
Failures = failures.ToList()
|
||||
};
|
||||
}
|
||||
|
||||
ConsoleIO.WriteLogLine("Compilation done without any error.");
|
||||
|
||||
peStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
return new CompileResult() {
|
||||
Assembly = peStream.ToArray(),
|
||||
HasCompiledSucecssfully = true,
|
||||
Failures = null
|
||||
Assembly = null,
|
||||
HasCompiledSucecssfully = false,
|
||||
Failures = failures.ToList()
|
||||
};
|
||||
}
|
||||
|
||||
ConsoleIO.WriteLogLine("Compilation done without any error.");
|
||||
|
||||
peStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
return new CompileResult()
|
||||
{
|
||||
Assembly = peStream.ToArray(),
|
||||
HasCompiledSucecssfully = true,
|
||||
Failures = null
|
||||
};
|
||||
}
|
||||
|
||||
private static CSharpCompilation GenerateCode(string sourceCode, string fileName)
|
||||
|
|
@ -60,8 +60,8 @@ namespace DynamicRun.Builder
|
|||
|
||||
var parsedSyntaxTree = SyntaxFactory.ParseSyntaxTree(codeString, options);
|
||||
|
||||
var mods = Assembly.GetEntryAssembly().GetModules();
|
||||
|
||||
var mods = Assembly.GetEntryAssembly()!.GetModules();
|
||||
|
||||
#pragma warning disable IL3000
|
||||
// System.Private.CoreLib
|
||||
var A = typeof(object).Assembly.Location;
|
||||
|
|
@ -89,18 +89,19 @@ namespace DynamicRun.Builder
|
|||
ExecutableReader e = new();
|
||||
File.Delete(tempFileName);
|
||||
File.Copy(executablePath, tempFileName);
|
||||
|
||||
|
||||
// Access the contents of the executable.
|
||||
var viewAccessor = MemoryMappedFile.CreateFromFile(tempFileName, FileMode.Open).CreateViewAccessor();
|
||||
var manifest = e.ReadManifest(viewAccessor);
|
||||
var files = manifest.Files;
|
||||
|
||||
|
||||
Stream? assemblyStream;
|
||||
|
||||
var assemblyrefs = Assembly.GetEntryAssembly()?.GetReferencedAssemblies().ToList();
|
||||
assemblyrefs.Add(new ("MinecraftClient"));
|
||||
|
||||
foreach (var refs in assemblyrefs) {
|
||||
var assemblyrefs = Assembly.GetEntryAssembly()?.GetReferencedAssemblies().ToList()!;
|
||||
assemblyrefs.Add(new("MinecraftClient"));
|
||||
|
||||
foreach (var refs in assemblyrefs)
|
||||
{
|
||||
var loadedAssembly = Assembly.Load(refs);
|
||||
if (string.IsNullOrEmpty(loadedAssembly.Location))
|
||||
{
|
||||
|
|
@ -118,8 +119,8 @@ namespace DynamicRun.Builder
|
|||
throw new InvalidOperationException("The executable does not contain a referenced assembly. Assembly name: " + refs.Name);
|
||||
}
|
||||
|
||||
assemblyStream = GetStreamForFileEntry(viewAccessor, reference);
|
||||
references.Add(MetadataReference.CreateFromStream(assemblyStream));
|
||||
assemblyStream = GetStreamForFileEntry(viewAccessor, reference);
|
||||
references.Add(MetadataReference.CreateFromStream(assemblyStream!));
|
||||
continue;
|
||||
}
|
||||
references.Add(MetadataReference.CreateFromFile(loadedAssembly.Location));
|
||||
|
|
@ -138,29 +139,27 @@ namespace DynamicRun.Builder
|
|||
#pragma warning restore IL3000
|
||||
return CSharpCompilation.Create($"{fileName}.dll",
|
||||
new[] { parsedSyntaxTree },
|
||||
references: references,
|
||||
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary,
|
||||
references: references,
|
||||
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary,
|
||||
optimizationLevel: OptimizationLevel.Release,
|
||||
assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default));
|
||||
}
|
||||
|
||||
|
||||
private static Stream? GetStreamForFileEntry(MemoryMappedViewAccessor viewAccessor, FileEntry file)
|
||||
{
|
||||
var stream = typeof(BundleExtractor).GetMethod("GetStreamForFileEntry", BindingFlags.NonPublic | BindingFlags.Static)!.Invoke(null, new object[] { viewAccessor, file }) as Stream;
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
if (typeof(BundleExtractor).GetMethod("GetStreamForFileEntry", BindingFlags.NonPublic | BindingFlags.Static)!.Invoke(null, new object[] { viewAccessor, file }) is not Stream stream)
|
||||
throw new InvalidOperationException("The executable does not contain the assembly. Assembly name: " + file.RelativePath);
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
internal struct CompileResult {
|
||||
internal struct CompileResult
|
||||
{
|
||||
internal byte[]? Assembly;
|
||||
internal bool HasCompiledSucecssfully;
|
||||
internal List<Diagnostic>? Failures;
|
||||
public CompileResult(bool hasCompiledSucecssfully, List<Diagnostic>? failures, byte[]? assembly) {
|
||||
public CompileResult(bool hasCompiledSucecssfully, List<Diagnostic>? failures, byte[]? assembly)
|
||||
{
|
||||
HasCompiledSucecssfully = hasCompiledSucecssfully;
|
||||
Failures = failures;
|
||||
Assembly = assembly;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace DynamicRun.Builder
|
|||
{
|
||||
}
|
||||
|
||||
protected override Assembly Load(AssemblyName assemblyName)
|
||||
protected override Assembly? Load(AssemblyName assemblyName)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue