mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Merge branch 'master' into rename-items
This commit is contained in:
commit
f77d58402a
9 changed files with 1573 additions and 27 deletions
1341
MinecraftClient/ChatBots/WebSocketBot.cs
Normal file
1341
MinecraftClient/ChatBots/WebSocketBot.cs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -25,12 +25,24 @@ namespace MinecraftClient
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class JSONData
|
public class JSONData
|
||||||
{
|
{
|
||||||
public enum DataType { Object, Array, String };
|
public enum DataType
|
||||||
|
{
|
||||||
|
Object,
|
||||||
|
Array,
|
||||||
|
String
|
||||||
|
};
|
||||||
|
|
||||||
private readonly DataType type;
|
private readonly DataType type;
|
||||||
public DataType Type { get { return type; } }
|
|
||||||
|
public DataType Type
|
||||||
|
{
|
||||||
|
get { return type; }
|
||||||
|
}
|
||||||
|
|
||||||
public Dictionary<string, JSONData> Properties;
|
public Dictionary<string, JSONData> Properties;
|
||||||
public List<JSONData> DataArray;
|
public List<JSONData> DataArray;
|
||||||
public string StringValue;
|
public string StringValue;
|
||||||
|
|
||||||
public JSONData(DataType datatype)
|
public JSONData(DataType datatype)
|
||||||
{
|
{
|
||||||
type = datatype;
|
type = datatype;
|
||||||
|
|
@ -63,12 +75,21 @@ namespace MinecraftClient
|
||||||
if (toparse[cursorpos] == '"')
|
if (toparse[cursorpos] == '"')
|
||||||
{
|
{
|
||||||
JSONData propertyname = String2Data(toparse, ref cursorpos);
|
JSONData propertyname = String2Data(toparse, ref cursorpos);
|
||||||
if (toparse[cursorpos] == ':') { cursorpos++; } else { /* parse error ? */ }
|
if (toparse[cursorpos] == ':')
|
||||||
|
{
|
||||||
|
cursorpos++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* parse error ? */
|
||||||
|
}
|
||||||
|
|
||||||
JSONData propertyData = String2Data(toparse, ref cursorpos);
|
JSONData propertyData = String2Data(toparse, ref cursorpos);
|
||||||
data.Properties[propertyname.StringValue] = propertyData;
|
data.Properties[propertyname.StringValue] = propertyData;
|
||||||
}
|
}
|
||||||
else cursorpos++;
|
else cursorpos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
cursorpos++;
|
cursorpos++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -79,10 +100,15 @@ namespace MinecraftClient
|
||||||
SkipSpaces(toparse, ref cursorpos);
|
SkipSpaces(toparse, ref cursorpos);
|
||||||
while (toparse[cursorpos] != ']')
|
while (toparse[cursorpos] != ']')
|
||||||
{
|
{
|
||||||
if (toparse[cursorpos] == ',') { cursorpos++; }
|
if (toparse[cursorpos] == ',')
|
||||||
|
{
|
||||||
|
cursorpos++;
|
||||||
|
}
|
||||||
|
|
||||||
JSONData arrayItem = String2Data(toparse, ref cursorpos);
|
JSONData arrayItem = String2Data(toparse, ref cursorpos);
|
||||||
data.DataArray.Add(arrayItem);
|
data.DataArray.Add(arrayItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
cursorpos++;
|
cursorpos++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -103,9 +129,11 @@ namespace MinecraftClient
|
||||||
&& IsHex(toparse[cursorpos + 5]))
|
&& IsHex(toparse[cursorpos + 5]))
|
||||||
{
|
{
|
||||||
//"abc\u0123abc" => "0123" => 0123 => Unicode char n°0123 => Add char to string
|
//"abc\u0123abc" => "0123" => 0123 => Unicode char n°0123 => Add char to string
|
||||||
data.StringValue += char.ConvertFromUtf32(int.Parse(toparse.Substring(cursorpos + 2, 4),
|
data.StringValue += char.ConvertFromUtf32(int.Parse(
|
||||||
|
toparse.Substring(cursorpos + 2, 4),
|
||||||
System.Globalization.NumberStyles.HexNumber));
|
System.Globalization.NumberStyles.HexNumber));
|
||||||
cursorpos += 6; continue;
|
cursorpos += 6;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else if (toparse[cursorpos + 1] == 'n')
|
else if (toparse[cursorpos + 1] == 'n')
|
||||||
{
|
{
|
||||||
|
|
@ -127,12 +155,20 @@ namespace MinecraftClient
|
||||||
}
|
}
|
||||||
else cursorpos++; //Normal character escapement \"
|
else cursorpos++; //Normal character escapement \"
|
||||||
}
|
}
|
||||||
catch (IndexOutOfRangeException) { cursorpos++; } // \u01<end of string>
|
catch (IndexOutOfRangeException)
|
||||||
catch (ArgumentOutOfRangeException) { cursorpos++; } // Unicode index 0123 was invalid
|
{
|
||||||
|
cursorpos++;
|
||||||
|
} // \u01<end of string>
|
||||||
|
catch (ArgumentOutOfRangeException)
|
||||||
|
{
|
||||||
|
cursorpos++;
|
||||||
|
} // Unicode index 0123 was invalid
|
||||||
}
|
}
|
||||||
|
|
||||||
data.StringValue += toparse[cursorpos];
|
data.StringValue += toparse[cursorpos];
|
||||||
cursorpos++;
|
cursorpos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
cursorpos++;
|
cursorpos++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -151,11 +187,13 @@ namespace MinecraftClient
|
||||||
case '-':
|
case '-':
|
||||||
data = new JSONData(JSONData.DataType.String);
|
data = new JSONData(JSONData.DataType.String);
|
||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
while ((toparse[cursorpos] >= '0' && toparse[cursorpos] <= '9') || toparse[cursorpos] == '.' || toparse[cursorpos] == '-')
|
while ((toparse[cursorpos] >= '0' && toparse[cursorpos] <= '9') || toparse[cursorpos] == '.' ||
|
||||||
|
toparse[cursorpos] == '-')
|
||||||
{
|
{
|
||||||
sb.Append(toparse[cursorpos]);
|
sb.Append(toparse[cursorpos]);
|
||||||
cursorpos++;
|
cursorpos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.StringValue = sb.ToString();
|
data.StringValue = sb.ToString();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -163,28 +201,71 @@ namespace MinecraftClient
|
||||||
case 't':
|
case 't':
|
||||||
data = new JSONData(JSONData.DataType.String);
|
data = new JSONData(JSONData.DataType.String);
|
||||||
cursorpos++;
|
cursorpos++;
|
||||||
if (toparse[cursorpos] == 'r') { cursorpos++; }
|
if (toparse[cursorpos] == 'r')
|
||||||
if (toparse[cursorpos] == 'u') { cursorpos++; }
|
{
|
||||||
if (toparse[cursorpos] == 'e') { cursorpos++; data.StringValue = "true"; }
|
cursorpos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toparse[cursorpos] == 'u')
|
||||||
|
{
|
||||||
|
cursorpos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toparse[cursorpos] == 'e')
|
||||||
|
{
|
||||||
|
cursorpos++;
|
||||||
|
data.StringValue = "true";
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Boolean : false
|
//Boolean : false
|
||||||
case 'f':
|
case 'f':
|
||||||
data = new JSONData(JSONData.DataType.String);
|
data = new JSONData(JSONData.DataType.String);
|
||||||
cursorpos++;
|
cursorpos++;
|
||||||
if (toparse[cursorpos] == 'a') { cursorpos++; }
|
if (toparse[cursorpos] == 'a')
|
||||||
if (toparse[cursorpos] == 'l') { cursorpos++; }
|
{
|
||||||
if (toparse[cursorpos] == 's') { cursorpos++; }
|
cursorpos++;
|
||||||
if (toparse[cursorpos] == 'e') { cursorpos++; data.StringValue = "false"; }
|
}
|
||||||
|
|
||||||
|
if (toparse[cursorpos] == 'l')
|
||||||
|
{
|
||||||
|
cursorpos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toparse[cursorpos] == 's')
|
||||||
|
{
|
||||||
|
cursorpos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toparse[cursorpos] == 'e')
|
||||||
|
{
|
||||||
|
cursorpos++;
|
||||||
|
data.StringValue = "false";
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Null field
|
//Null field
|
||||||
case 'n':
|
case 'n':
|
||||||
data = new JSONData(JSONData.DataType.String);
|
data = new JSONData(JSONData.DataType.String);
|
||||||
cursorpos++;
|
cursorpos++;
|
||||||
if (toparse[cursorpos] == 'u') { cursorpos++; }
|
if (toparse[cursorpos] == 'u')
|
||||||
if (toparse[cursorpos] == 'l') { cursorpos++; }
|
{
|
||||||
if (toparse[cursorpos] == 'l') { cursorpos++; data.StringValue = "null"; }
|
cursorpos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toparse[cursorpos] == 'l')
|
||||||
|
{
|
||||||
|
cursorpos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toparse[cursorpos] == 'l')
|
||||||
|
{
|
||||||
|
cursorpos++;
|
||||||
|
data.StringValue = "null";
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Unknown data
|
//Unknown data
|
||||||
|
|
@ -192,6 +273,7 @@ namespace MinecraftClient
|
||||||
cursorpos++;
|
cursorpos++;
|
||||||
return String2Data(toparse, ref cursorpos);
|
return String2Data(toparse, ref cursorpos);
|
||||||
}
|
}
|
||||||
|
|
||||||
SkipSpaces(toparse, ref cursorpos);
|
SkipSpaces(toparse, ref cursorpos);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
@ -206,7 +288,10 @@ namespace MinecraftClient
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="c">Char to test</param>
|
/// <param name="c">Char to test</param>
|
||||||
/// <returns>True if hexadecimal</returns>
|
/// <returns>True if hexadecimal</returns>
|
||||||
private static bool IsHex(char c) { return ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')); }
|
private static bool IsHex(char c)
|
||||||
|
{
|
||||||
|
return ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Advance the cursor to skip white spaces and line breaks
|
/// Advance the cursor to skip white spaces and line breaks
|
||||||
|
|
@ -216,10 +301,77 @@ namespace MinecraftClient
|
||||||
private static void SkipSpaces(string toparse, ref int cursorpos)
|
private static void SkipSpaces(string toparse, ref int cursorpos)
|
||||||
{
|
{
|
||||||
while (cursorpos < toparse.Length
|
while (cursorpos < toparse.Length
|
||||||
&& (char.IsWhiteSpace(toparse[cursorpos])
|
&& (char.IsWhiteSpace(toparse[cursorpos])
|
||||||
|| toparse[cursorpos] == '\r'
|
|| toparse[cursorpos] == '\r'
|
||||||
|| toparse[cursorpos] == '\n'))
|
|| toparse[cursorpos] == '\n'))
|
||||||
cursorpos++;
|
cursorpos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Original: https://github.com/mono/mono/blob/master/mcs/class/System.Json/System.Json/JsonValue.cs
|
||||||
|
private static bool NeedEscape(string src, int i)
|
||||||
|
{
|
||||||
|
var c = src[i];
|
||||||
|
return c < 32 || c == '"' || c == '\\'
|
||||||
|
// Broken lead surrogate
|
||||||
|
|| (c is >= '\uD800' and <= '\uDBFF' &&
|
||||||
|
(i == src.Length - 1 || src[i + 1] < '\uDC00' || src[i + 1] > '\uDFFF'))
|
||||||
|
// Broken tail surrogate
|
||||||
|
|| (c is >= '\uDC00' and <= '\uDFFF' &&
|
||||||
|
(i == 0 || src[i - 1] < '\uD800' || src[i - 1] > '\uDBFF'))
|
||||||
|
// To produce valid JavaScript
|
||||||
|
|| c == '\u2028' || c == '\u2029'
|
||||||
|
// Escape "</" for <script> tags
|
||||||
|
|| (c == '/' && i > 0 && src[i - 1] == '<');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string EscapeString(string src)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
var start = 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < src.Length; i++)
|
||||||
|
{
|
||||||
|
if (!NeedEscape(src, i)) continue;
|
||||||
|
sb.Append(src, start, i - start);
|
||||||
|
|
||||||
|
switch (src[i])
|
||||||
|
{
|
||||||
|
case '\b':
|
||||||
|
sb.Append("\\b");
|
||||||
|
break;
|
||||||
|
case '\f':
|
||||||
|
sb.Append("\\f");
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
sb.Append("\\n");
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
sb.Append("\\r");
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
sb.Append("\\t");
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
sb.Append("\\\"");
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
sb.Append("\\\\");
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
sb.Append("\\/");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
sb.Append("\\u");
|
||||||
|
sb.Append(((int)src[i]).ToString("x04"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.Append(src, start, src.Length - start);
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -297,6 +297,7 @@ namespace MinecraftClient
|
||||||
if (Config.ChatBot.ScriptScheduler.Enabled) { BotLoad(new ScriptScheduler()); }
|
if (Config.ChatBot.ScriptScheduler.Enabled) { BotLoad(new ScriptScheduler()); }
|
||||||
if (Config.ChatBot.TelegramBridge.Enabled) { BotLoad(new TelegramBridge()); }
|
if (Config.ChatBot.TelegramBridge.Enabled) { BotLoad(new TelegramBridge()); }
|
||||||
if (Config.ChatBot.ItemsCollector.Enabled) { BotLoad(new ItemsCollector()); }
|
if (Config.ChatBot.ItemsCollector.Enabled) { BotLoad(new ItemsCollector()); }
|
||||||
|
if (Config.ChatBot.WebSocketBot.Enabled) { BotLoad(new WebSocketBot()); }
|
||||||
//Add your ChatBot here by uncommenting and adapting
|
//Add your ChatBot here by uncommenting and adapting
|
||||||
//BotLoad(new ChatBots.YourBot());
|
//BotLoad(new ChatBots.YourBot());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1238,5 +1238,35 @@ namespace MinecraftClient {
|
||||||
return ResourceManager.GetString("ChatBot.ItemsCollector", resourceCulture);
|
return ResourceManager.GetString("ChatBot.ItemsCollector", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static string ChatBot_WebSocketBot {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ChatBot.WebSocketBot", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string ChatBot_WebSocketBot_Ip {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ChatBot.WebSocketBot.Ip", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string ChatBot_WebSocketBot_Port {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ChatBot.WebSocketBot.Port", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string ChatBot_WebSocketBot_Password {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ChatBot.WebSocketBot.Password", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string ChatBot_WebSocketBot_DebugMode {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ChatBot.WebSocketBot.DebugMode", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -828,4 +828,19 @@ If the connection to the Minecraft game server is blocked by the firewall, set E
|
||||||
<data name="ChatBot.ItemsCollector" xml:space="preserve">
|
<data name="ChatBot.ItemsCollector" xml:space="preserve">
|
||||||
<value>A Chat Bot that collects items on the ground</value>
|
<value>A Chat Bot that collects items on the ground</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ChatBot.WebSocketBot" xml:space="preserve">
|
||||||
|
<value>Remotely control the client using Web Sockets.\n# This is useful if you want to implement an application that can remotely and asynchronously execute procedures in MCC.\n# Example implementation written in JavaScript: https://github.com/milutinke/MCC.js.git\n# The protocol specification will be available in the documentation soon.</value>
|
||||||
|
</data>
|
||||||
|
<data name="ChatBot.WebSocketBot.Ip" xml:space="preserve">
|
||||||
|
<value>The IP address that Websocket server will be bound to.</value>
|
||||||
|
</data>
|
||||||
|
<data name="ChatBot.WebSocketBot.Port" xml:space="preserve">
|
||||||
|
<value>The Port that Websocket server will be bounded to.</value>
|
||||||
|
</data>
|
||||||
|
<data name="ChatBot.WebSocketBot.Password" xml:space="preserve">
|
||||||
|
<value>A password that will be used to authenticate on thw Websocket server (It is recommended to change the default password and to set a strong one).</value>
|
||||||
|
</data>
|
||||||
|
<data name="ChatBot.WebSocketBot.DebugMode" xml:space="preserve">
|
||||||
|
<value>This setting is for developers who are developing a library that uses this chat bot to remotely execute procedures/commands/functions.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// <auto-generated>
|
// <auto-generated>
|
||||||
// This code was generated by a tool.
|
// This code was generated by a tool.
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<root>
|
<root>
|
||||||
<!--
|
<!--
|
||||||
Microsoft ResX Schema
|
Microsoft ResX Schema
|
||||||
|
|
|
||||||
|
|
@ -1050,7 +1050,7 @@ namespace MinecraftClient.Scripting
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Send Entity Action
|
/// Send Entity Action
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool SendEntityAction(Protocol.EntityActionType entityAction)
|
protected bool SendEntityAction(Protocol.EntityActionType entityAction)
|
||||||
{
|
{
|
||||||
return Handler.SendEntityAction(entityAction);
|
return Handler.SendEntityAction(entityAction);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1404,6 +1404,13 @@ namespace MinecraftClient
|
||||||
get { return ChatBots.ItemsCollector.Config; }
|
get { return ChatBots.ItemsCollector.Config; }
|
||||||
set { ChatBots.ItemsCollector.Config = value; ChatBots.ItemsCollector.Config.OnSettingUpdate(); }
|
set { ChatBots.ItemsCollector.Config = value; ChatBots.ItemsCollector.Config.OnSettingUpdate(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TomlPrecedingComment("$ChatBot.WebSocketBot$")]
|
||||||
|
public ChatBots.WebSocketBot.Configs WebSocketBot
|
||||||
|
{
|
||||||
|
get { return ChatBots.WebSocketBot.Config!; }
|
||||||
|
set { ChatBots.WebSocketBot.Config = value; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue