mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-11-07 17:36:07 +00:00
Merge pull request #69 from ORelio/Indev
Merging changes from Indev for 1.8.2 release
This commit is contained in:
commit
5b430562ca
17 changed files with 364 additions and 214 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -2,3 +2,4 @@
|
|||
/MinecraftClient.suo
|
||||
/MinecraftClientGUI.v11.suo
|
||||
/MinecraftClientGUI.suo
|
||||
/MinecraftClient.userprefs
|
||||
|
|
|
|||
41
MinecraftClient/AutoTimeout.cs
Normal file
41
MinecraftClient/AutoTimeout.cs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace MinecraftClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Allow easy timeout on pieces of code
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By ORelio - (c) 2014 - CDDL 1.0
|
||||
/// </remarks>
|
||||
public class AutoTimeout
|
||||
{
|
||||
/// <summary>
|
||||
/// Perform the specified action with specified timeout
|
||||
/// </summary>
|
||||
/// <param name="action">Action to run</param>
|
||||
/// <param name="timeout">Maximum timeout in milliseconds</param>
|
||||
/// <returns>True if the action finished whithout timing out</returns>
|
||||
public static bool Perform(Action action, int timeout)
|
||||
{
|
||||
return Perform(action, TimeSpan.FromMilliseconds(timeout));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform the specified action with specified timeout
|
||||
/// </summary>
|
||||
/// <param name="action">Action to run</param>
|
||||
/// <param name="timeout">Maximum timeout</param>
|
||||
/// <returns>True if the action finished whithout timing out</returns>
|
||||
public static bool Perform(Action action, TimeSpan timeout)
|
||||
{
|
||||
Thread thread = new Thread(new ThreadStart(action));
|
||||
thread.Start();
|
||||
bool success = thread.Join(timeout);
|
||||
if (!success)
|
||||
thread.Abort();
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -204,6 +204,26 @@ namespace MinecraftClient
|
|||
return isValidName(sender);
|
||||
}
|
||||
|
||||
//Detect HeroChat PMsend
|
||||
//From Someone: message
|
||||
else if (text.StartsWith("From "))
|
||||
{
|
||||
sender = text.Substring(5).Split(':')[0];
|
||||
message = text.Substring(text.IndexOf(':') + 2);
|
||||
return isValidName(sender);
|
||||
}
|
||||
|
||||
//Detect HeroChat Messages
|
||||
//[Channel] [Rank] User: Message
|
||||
else if (text.StartsWith("[") && text.Contains(':') && tmp.Length > 2)
|
||||
{
|
||||
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);
|
||||
return isValidName(sender);
|
||||
}
|
||||
|
||||
else return false;
|
||||
}
|
||||
catch (IndexOutOfRangeException) { return false; }
|
||||
|
|
|
|||
|
|
@ -2,125 +2,96 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace MinecraftClient.ChatBots
|
||||
{
|
||||
/// <summary>
|
||||
/// This bot make the console beep on some specified words. Useful to detect when someone is talking to you, for example.
|
||||
/// </summary>
|
||||
|
||||
public class Alerts : ChatBot
|
||||
{
|
||||
private string[] dictionary = new string[0];
|
||||
private string[] excludelist = new string[0];
|
||||
|
||||
public override void Initialize()
|
||||
/// <summary>
|
||||
/// Import alerts from the specified file
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
private static string[] FromFile(string file)
|
||||
{
|
||||
if (System.IO.File.Exists(Settings.Alerts_MatchesFile))
|
||||
if (File.Exists(file))
|
||||
{
|
||||
List<string> tmp_dictionary = new List<string>();
|
||||
string[] file_lines = System.IO.File.ReadAllLines(Settings.Alerts_MatchesFile);
|
||||
foreach (string line in file_lines)
|
||||
if (line.Trim().Length > 0 && !tmp_dictionary.Contains(line.ToLower()))
|
||||
tmp_dictionary.Add(line.ToLower());
|
||||
dictionary = tmp_dictionary.ToArray();
|
||||
//Read all lines from file, remove lines with no text, convert to lowercase,
|
||||
//remove duplicate entries, convert to a string array, and return the result.
|
||||
return File.ReadAllLines(file)
|
||||
.Where(line => !String.IsNullOrWhiteSpace(line))
|
||||
.Select(line => line.ToLower())
|
||||
.Distinct().ToArray();
|
||||
}
|
||||
else LogToConsole("File not found: " + Settings.Alerts_MatchesFile);
|
||||
|
||||
if (System.IO.File.Exists(Settings.Alerts_ExcludesFile))
|
||||
else
|
||||
{
|
||||
List<string> tmp_excludelist = new List<string>();
|
||||
string[] file_lines = System.IO.File.ReadAllLines(Settings.Alerts_ExcludesFile);
|
||||
foreach (string line in file_lines)
|
||||
if (line.Trim().Length > 0 && !tmp_excludelist.Contains(line.Trim().ToLower()))
|
||||
tmp_excludelist.Add(line.ToLower());
|
||||
excludelist = tmp_excludelist.ToArray();
|
||||
LogToConsole("File not found: " + Settings.Alerts_MatchesFile);
|
||||
return new string[0];
|
||||
}
|
||||
else LogToConsole("File not found : " + Settings.Alerts_ExcludesFile);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Intitialize the Alerts bot
|
||||
/// </summary>
|
||||
public override void Initialize()
|
||||
{
|
||||
dictionary = FromFile(Settings.Alerts_MatchesFile);
|
||||
excludelist = FromFile(Settings.Alerts_ExcludesFile);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process text received from the server to display alerts
|
||||
/// </summary>
|
||||
/// <param name="text">Received text</param>
|
||||
public override void GetText(string text)
|
||||
{
|
||||
text = getVerbatim(text);
|
||||
string comp = text.ToLower();
|
||||
foreach (string alert in dictionary)
|
||||
//Remove color codes and convert to lowercase
|
||||
text = getVerbatim(text).ToLower();
|
||||
|
||||
//Proceed only if no exclusions are found in text
|
||||
if (!excludelist.Any(exclusion => text.Contains(exclusion)))
|
||||
{
|
||||
if (comp.Contains(alert))
|
||||
//Show an alert for each alert item found in text, if any
|
||||
foreach (string alert in dictionary.Where(alert => text.Contains(alert)))
|
||||
{
|
||||
bool ok = true;
|
||||
if (Settings.Alerts_Beep_Enabled)
|
||||
Console.Beep(); //Text found !
|
||||
|
||||
foreach (string exclusion in excludelist)
|
||||
if (ConsoleIO.basicIO) //Using a GUI? Pass text as is.
|
||||
ConsoleIO.WriteLine(text.Replace(alert, "§c" + alert + "§r"));
|
||||
|
||||
else //Using Consome Prompt : Print text with alert highlighted
|
||||
{
|
||||
if (comp.Contains(exclusion))
|
||||
string[] splitted = text.Split(new string[] { alert }, StringSplitOptions.None);
|
||||
|
||||
if (splitted.Length > 0)
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
if (Settings.Alerts_Beep_Enabled) { Console.Beep(); } //Text found !
|
||||
|
||||
if (ConsoleIO.basicIO) { ConsoleIO.WriteLine(comp.Replace(alert, "§c" + alert + "§r")); }
|
||||
else
|
||||
{
|
||||
|
||||
#region Displaying the text with the interesting part highlighted
|
||||
|
||||
Console.BackgroundColor = ConsoleColor.DarkGray;
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
ConsoleIO.Write(splitted[0]);
|
||||
|
||||
//Will be used for text displaying
|
||||
string[] temp = comp.Split(alert.Split(','), StringSplitOptions.None);
|
||||
int p = 0;
|
||||
|
||||
//Special case : alert in the beginning of the text
|
||||
string test = "";
|
||||
for (int i = 0; i < alert.Length; i++)
|
||||
{
|
||||
test += comp[i];
|
||||
}
|
||||
if (test == alert)
|
||||
for (int i = 1; i < splitted.Length; i++)
|
||||
{
|
||||
Console.BackgroundColor = ConsoleColor.Yellow;
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
for (int i = 0; i < alert.Length; i++)
|
||||
{
|
||||
ConsoleIO.Write(text[p]);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
ConsoleIO.Write(alert);
|
||||
|
||||
//Displaying the rest of the text
|
||||
for (int i = 0; i < temp.Length; i++)
|
||||
{
|
||||
Console.BackgroundColor = ConsoleColor.DarkGray;
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
for (int j = 0; j < temp[i].Length; j++)
|
||||
{
|
||||
ConsoleIO.Write(text[p]);
|
||||
p++;
|
||||
}
|
||||
Console.BackgroundColor = ConsoleColor.Yellow;
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
try
|
||||
{
|
||||
for (int j = 0; j < alert.Length; j++)
|
||||
{
|
||||
ConsoleIO.Write(text[p]);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfRangeException) { }
|
||||
ConsoleIO.Write(splitted[i]);
|
||||
}
|
||||
Console.BackgroundColor = ConsoleColor.Black;
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
ConsoleIO.Write('\n');
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
Console.BackgroundColor = ConsoleColor.Black;
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
ConsoleIO.Write('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,9 @@ namespace MinecraftClient.ChatBots
|
|||
if (dateandtime)
|
||||
tosave = getTimestamp() + ' ' + tosave;
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(logfile));
|
||||
string directory = Path.GetDirectoryName(logfile);
|
||||
if (!String.IsNullOrEmpty(directory) && !Directory.Exists(directory))
|
||||
Directory.CreateDirectory(directory);
|
||||
FileStream stream = new FileStream(logfile, FileMode.OpenOrCreate);
|
||||
StreamWriter writer = new StreamWriter(stream);
|
||||
stream.Seek(0, SeekOrigin.End);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace MinecraftClient.ChatBots
|
|||
{
|
||||
text = getVerbatim(text);
|
||||
string command = "", sender = "";
|
||||
if (isPrivateMessage(text, ref command, ref sender) && Settings.Bots_Owners.Contains(sender.ToLower()))
|
||||
if (isPrivateMessage(text, ref command, ref sender) && Settings.Bots_Owners.Contains(sender.ToLower().Trim()))
|
||||
{
|
||||
string response = "";
|
||||
performInternalCommand(command, ref response);
|
||||
|
|
@ -24,7 +24,9 @@ namespace MinecraftClient.ChatBots
|
|||
SendPrivateMessage(sender, response);
|
||||
}
|
||||
}
|
||||
else if (Settings.RemoteCtrl_AutoTpaccept && isTeleportRequest(text, ref sender) && Settings.Bots_Owners.Contains(sender.ToLower()))
|
||||
else if (Settings.RemoteCtrl_AutoTpaccept
|
||||
&& isTeleportRequest(text, ref sender)
|
||||
&& (Settings.RemoteCtrl_AutoTpaccept_Everyone || Settings.Bots_Owners.Contains(sender.ToLower().Trim())))
|
||||
{
|
||||
SendText("/tpaccept");
|
||||
}
|
||||
|
|
|
|||
19
MinecraftClient/Commands/List.cs
Normal file
19
MinecraftClient/Commands/List.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MinecraftClient.Commands
|
||||
{
|
||||
public class List : Command
|
||||
{
|
||||
public override string CMDName { get { return "list"; } }
|
||||
public override string CMDDesc { get { return "list: get the player list."; } }
|
||||
|
||||
public override string Run(McTcpClient handler, string command)
|
||||
{
|
||||
return "PlayerList: " + String.Join(", ", handler.getOnlinePlayers());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -20,6 +20,7 @@ namespace MinecraftClient
|
|||
private static List<string> cmd_names = new List<string>();
|
||||
private static Dictionary<string, Command> cmds = new Dictionary<string, Command>();
|
||||
private List<ChatBot> bots = new List<ChatBot>();
|
||||
private Dictionary<Guid, string> onlinePlayers = new Dictionary<Guid,string>();
|
||||
private static List<ChatBots.Script> scripts_on_hold = new List<ChatBots.Script>();
|
||||
public void BotLoad(ChatBot b) { b.SetHandler(this); bots.Add(b); b.Initialize(); Settings.SingleCommand = ""; }
|
||||
public void BotUnLoad(ChatBot b) { bots.RemoveAll(item => object.ReferenceEquals(item, b)); }
|
||||
|
|
@ -53,7 +54,7 @@ namespace MinecraftClient
|
|||
/// <param name="port">The server port to use</param>
|
||||
/// <param name="protocolversion">Minecraft protocol version to use</param>
|
||||
|
||||
public McTcpClient(string username, string uuid, string sessionID, int protocolversion, string server_ip, short port)
|
||||
public McTcpClient(string username, string uuid, string sessionID, int protocolversion, string server_ip, ushort port)
|
||||
{
|
||||
StartClient(username, uuid, sessionID, server_ip, port, protocolversion, false, "");
|
||||
}
|
||||
|
|
@ -69,7 +70,7 @@ namespace MinecraftClient
|
|||
/// <param name="protocolversion">Minecraft protocol version to use</param>
|
||||
/// <param name="command">The text or command to send.</param>
|
||||
|
||||
public McTcpClient(string username, string uuid, string sessionID, string server_ip, short port, int protocolversion, string command)
|
||||
public McTcpClient(string username, string uuid, string sessionID, string server_ip, ushort port, int protocolversion, string command)
|
||||
{
|
||||
StartClient(username, uuid, sessionID, server_ip, port, protocolversion, true, command);
|
||||
}
|
||||
|
|
@ -86,7 +87,7 @@ namespace MinecraftClient
|
|||
/// <param name="singlecommand">If set to true, the client will send a single command and then disconnect from the server</param>
|
||||
/// <param name="command">The text or command to send. Will only be sent if singlecommand is set to true.</param>
|
||||
|
||||
private void StartClient(string user, string uuid, string sessionID, string server_ip, short port, int protocolversion, bool singlecommand, string command)
|
||||
private void StartClient(string user, string uuid, string sessionID, string server_ip, ushort port, int protocolversion, bool singlecommand, string command)
|
||||
{
|
||||
this.sessionid = sessionID;
|
||||
this.uuid = uuid;
|
||||
|
|
@ -125,7 +126,9 @@ namespace MinecraftClient
|
|||
}
|
||||
else
|
||||
{
|
||||
foreach (ChatBot bot in scripts_on_hold) { bots.Add(bot); }
|
||||
foreach (ChatBot bot in scripts_on_hold)
|
||||
bot.SetHandler(this);
|
||||
bots.AddRange(scripts_on_hold);
|
||||
scripts_on_hold.Clear();
|
||||
|
||||
Console.WriteLine("Server was successfully joined.\nType '"
|
||||
|
|
@ -280,8 +283,11 @@ namespace MinecraftClient
|
|||
if (bot is ChatBots.Script)
|
||||
scripts_on_hold.Add((ChatBots.Script)bot);
|
||||
|
||||
handler.Disconnect();
|
||||
handler.Dispose();
|
||||
if (handler != null)
|
||||
{
|
||||
handler.Disconnect();
|
||||
handler.Dispose();
|
||||
}
|
||||
|
||||
if (cmdprompt != null)
|
||||
cmdprompt.Abort();
|
||||
|
|
@ -397,5 +403,36 @@ namespace MinecraftClient
|
|||
{
|
||||
return handler.SendRespawnPacket();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when a new player joins the game
|
||||
/// </summary>
|
||||
/// <param name="uuid">UUID of the player</param>
|
||||
/// <param name="name">Name of the player</param>
|
||||
|
||||
public void OnPlayerJoin(Guid uuid, string name)
|
||||
{
|
||||
onlinePlayers[uuid] = name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when a player has left the game
|
||||
/// </summary>
|
||||
/// <param name="uuid">UUID of the player</param>
|
||||
|
||||
public void OnPlayerLeave(Guid uuid)
|
||||
{
|
||||
onlinePlayers.Remove(uuid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a set of online player names
|
||||
/// </summary>
|
||||
/// <returns>Online player names</returns>
|
||||
|
||||
public string[] getOnlinePlayers()
|
||||
{
|
||||
return onlinePlayers.Values.Distinct().ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@
|
|||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AutoTimeout.cs" />
|
||||
<Compile Include="ChatBots\Alerts.cs" />
|
||||
<Compile Include="ChatBots\AntiAFK.cs" />
|
||||
<Compile Include="ChatBots\AutoRelog.cs" />
|
||||
|
|
@ -131,6 +132,7 @@
|
|||
<Compile Include="Proxy\Handlers\Socks5ProxyClient.cs" />
|
||||
<Compile Include="Proxy\Handlers\Utils.cs" />
|
||||
<Compile Include="Settings.cs" />
|
||||
<Compile Include="Commands\List.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client">
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.Net.Sockets;
|
|||
using System.Threading;
|
||||
using MinecraftClient.Crypto;
|
||||
using MinecraftClient.Proxy;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers
|
||||
{
|
||||
|
|
@ -157,7 +158,11 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
if (readNextInt() == 2022) { handler.OnTextReceived("You are dead. Type /reco to respawn & reconnect."); }
|
||||
if (protocolversion >= 72) { readData(4); } else readData(1);
|
||||
break;
|
||||
case 0xC9: readNextString(); readData(3); break;
|
||||
case 0xC9:
|
||||
string name = readNextString(); bool online = readNextByte() != 0x00; readData(2);
|
||||
Guid FakeUUID = new Guid(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(name)).Take(16).ToArray());
|
||||
if (online) { handler.OnPlayerJoin(FakeUUID, name); } else { handler.OnPlayerLeave(FakeUUID); }
|
||||
break;
|
||||
case 0xCA: if (protocolversion >= 72) { readData(9); } else readData(3); break;
|
||||
case 0xCB: autocomplete_result = readNextString(); autocomplete_received = true; break;
|
||||
case 0xCC: readNextString(); readData(4); break;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.Net.Sockets;
|
|||
using System.Threading;
|
||||
using MinecraftClient.Crypto;
|
||||
using MinecraftClient.Proxy;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers
|
||||
{
|
||||
|
|
@ -96,6 +97,17 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case 0x02:
|
||||
handler.OnTextReceived(ChatParser.ParseText(readNextString()));
|
||||
break;
|
||||
case 0x38:
|
||||
string name = readNextString();
|
||||
bool online = readNextBool();
|
||||
short ping = readNextShort();
|
||||
Guid FakeUUID = new Guid(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(name)).Take(16).ToArray());
|
||||
if (online)
|
||||
{
|
||||
handler.OnPlayerJoin(FakeUUID, name);
|
||||
}
|
||||
else handler.OnPlayerLeave(FakeUUID);
|
||||
break;
|
||||
case 0x3A:
|
||||
int autocomplete_count = readNextVarInt();
|
||||
string tab_list = "";
|
||||
|
|
@ -186,6 +198,44 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
else return "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a uuid from the network
|
||||
/// </summary>
|
||||
/// <param name="cache">Cache of bytes to read from</param>
|
||||
/// <returns>The uuid</returns>
|
||||
|
||||
private Guid readNextUUID()
|
||||
{
|
||||
byte[] cache = new byte[16];
|
||||
Receive(cache, 0, 16, SocketFlags.None);
|
||||
return new Guid(cache);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a short from the network
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
|
||||
private short readNextShort()
|
||||
{
|
||||
byte[] tmp = new byte[2];
|
||||
Receive(tmp, 0, 2, SocketFlags.None);
|
||||
Array.Reverse(tmp);
|
||||
return BitConverter.ToInt16(tmp, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a boolean from the network
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
|
||||
private bool readNextBool()
|
||||
{
|
||||
byte[] tmp = new byte[1];
|
||||
Receive(tmp, 0, 1, SocketFlags.None);
|
||||
return tmp[0] != 0x00;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a byte array from the network
|
||||
/// </summary>
|
||||
|
|
@ -545,14 +595,13 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
{
|
||||
protocolversion = atoi(tmp_ver[1]);
|
||||
|
||||
// Handle if "name" exists twice, like when connecting to a server with another user logged in.
|
||||
//Handle if "name" exists twice, eg when connecting to a server with another user logged in.
|
||||
version = (tmp_name.Length == 2) ? tmp_name[1].Split('"')[0] : tmp_name[2].Split('"')[0];
|
||||
if (result.Contains("modinfo\":"))
|
||||
{
|
||||
//Server is running Forge (which is not supported)
|
||||
version = "Forge " + version;
|
||||
protocolversion = 0;
|
||||
}
|
||||
|
||||
//Automatic fix for BungeeCord 1.8 not properly reporting protocol version
|
||||
if (protocolversion < 47 && version.Split(' ').Contains("1.8"))
|
||||
protocolversion = ProtocolHandler.MCVer2ProtocolVersion("1.8.0");
|
||||
|
||||
ConsoleIO.WriteLineFormatted("§8Server version : " + version + " (protocol v" + protocolversion + ").");
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,13 +137,31 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
{
|
||||
switch (packetID)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x00: //Keep-Alive
|
||||
SendPacket(0x00, getVarInt(readNextVarInt(ref packetData)));
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x02: //Chat message
|
||||
handler.OnTextReceived(ChatParser.ParseText(readNextString(ref packetData)));
|
||||
break;
|
||||
case 0x3A:
|
||||
case 0x38: //Player List update
|
||||
int action = readNextVarInt(ref packetData);
|
||||
int numActions = readNextVarInt(ref packetData);
|
||||
Guid uuid = readNextUUID(ref packetData);
|
||||
switch (action)
|
||||
{
|
||||
case 0x00: //Player Join
|
||||
string name = readNextString(ref packetData);
|
||||
handler.OnPlayerJoin(uuid, name);
|
||||
break;
|
||||
case 0x04: //Player Leave
|
||||
handler.OnPlayerLeave(uuid);
|
||||
break;
|
||||
default:
|
||||
//Unknown player list item type
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x3A: //Tab-Complete Result
|
||||
int autocomplete_count = readNextVarInt(ref packetData);
|
||||
string tab_list = "";
|
||||
for (int i = 0; i < autocomplete_count; i++)
|
||||
|
|
@ -157,10 +175,10 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
if (tab_list.Length > 0)
|
||||
ConsoleIO.WriteLineFormatted("§8" + tab_list, false);
|
||||
break;
|
||||
case 0x40:
|
||||
case 0x40: //Kick Packet
|
||||
handler.OnConnectionLost(ChatBot.DisconnectReason.InGameKick, ChatParser.ParseText(readNextString(ref packetData)));
|
||||
return false;
|
||||
case 0x46:
|
||||
case 0x46: //Network Compression Treshold Info
|
||||
compression_treshold = readNextVarInt(ref packetData);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -256,6 +274,17 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
else return "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a uuid from a cache of bytes and remove it from the cache
|
||||
/// </summary>
|
||||
/// <param name="cache">Cache of bytes to read from</param>
|
||||
/// <returns>The uuid</returns>
|
||||
|
||||
private Guid readNextUUID(ref byte[] cache)
|
||||
{
|
||||
return new Guid(readData(16, ref cache));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a byte array from a cache of bytes and remove it from the cache
|
||||
/// </summary>
|
||||
|
|
@ -624,65 +653,5 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
while (wait_left > 0 && !autocomplete_received) { System.Threading.Thread.Sleep(100); wait_left--; }
|
||||
return autocomplete_result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ping a Minecraft server to get information about the server
|
||||
/// </summary>
|
||||
/// <returns>True if ping was successful</returns>
|
||||
|
||||
public static bool doPing(string host, int port, ref int protocolversion)
|
||||
{
|
||||
string version = "";
|
||||
TcpClient tcp = ProxyHandler.newTcpClient(host, port);
|
||||
tcp.ReceiveBufferSize = 1024 * 1024;
|
||||
|
||||
byte[] packet_id = getVarInt(0);
|
||||
byte[] protocol_version = getVarInt(4);
|
||||
byte[] server_adress_val = Encoding.UTF8.GetBytes(host);
|
||||
byte[] server_adress_len = getVarInt(server_adress_val.Length);
|
||||
byte[] server_port = BitConverter.GetBytes((ushort)port); Array.Reverse(server_port);
|
||||
byte[] next_state = getVarInt(1);
|
||||
byte[] packet = concatBytes(packet_id, protocol_version, server_adress_len, server_adress_val, server_port, next_state);
|
||||
byte[] tosend = concatBytes(getVarInt(packet.Length), packet);
|
||||
|
||||
tcp.Client.Send(tosend, SocketFlags.None);
|
||||
|
||||
byte[] status_request = getVarInt(0);
|
||||
byte[] request_packet = concatBytes(getVarInt(status_request.Length), status_request);
|
||||
|
||||
tcp.Client.Send(request_packet, SocketFlags.None);
|
||||
|
||||
int packetID = -1;
|
||||
byte[] packetData = new byte[] { };
|
||||
Protocol18Handler ComTmp = new Protocol18Handler(tcp);
|
||||
ComTmp.readNextPacket(ref packetID, ref packetData);
|
||||
if (packetData.Length > 0) //Verify Response length
|
||||
{
|
||||
if (packetID == 0x00) //Read Packet ID
|
||||
{
|
||||
string result = ComTmp.readNextString(ref packetData); //Get the Json data
|
||||
if (result[0] == '{' && result.Contains("protocol\":") && result.Contains("name\":\""))
|
||||
{
|
||||
string[] tmp_ver = result.Split(new string[] { "protocol\":" }, StringSplitOptions.None);
|
||||
string[] tmp_name = result.Split(new string[] { "name\":\"" }, StringSplitOptions.None);
|
||||
|
||||
if (tmp_ver.Length >= 2 && tmp_name.Length >= 2)
|
||||
{
|
||||
protocolversion = atoi(tmp_ver[1]);
|
||||
version = tmp_name[1].Split('"')[0];
|
||||
if (result.Contains("modinfo\":"))
|
||||
{
|
||||
//Server is running Forge (which is not supported)
|
||||
version = "Forge " + version;
|
||||
protocolversion = 0;
|
||||
}
|
||||
ConsoleIO.WriteLineFormatted("§8Server version : " + version + " (protocol v" + protocolversion + ").");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ namespace MinecraftClient.Protocol
|
|||
string getUsername();
|
||||
string getUserUUID();
|
||||
string getSessionID();
|
||||
string[] getOnlinePlayers();
|
||||
|
||||
/// <summary>
|
||||
/// This method is called when the protocol handler receives a chat message
|
||||
|
|
@ -28,6 +29,21 @@ namespace MinecraftClient.Protocol
|
|||
|
||||
void OnTextReceived(string text);
|
||||
|
||||
/// <summary>
|
||||
/// This method is called when a new player joins the game
|
||||
/// </summary>
|
||||
/// <param name="uuid">UUID of the player</param>
|
||||
/// <param name="name">Name of the player</param>
|
||||
|
||||
void OnPlayerJoin(Guid uuid, string name);
|
||||
|
||||
/// <summary>
|
||||
/// This method is called when a player has left the game
|
||||
/// </summary>
|
||||
/// <param name="uuid">UUID of the player</param>
|
||||
|
||||
void OnPlayerLeave(Guid uuid);
|
||||
|
||||
/// <summary>
|
||||
/// This method is called when the connection has been lost
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace MinecraftClient.Protocol
|
|||
/// <param name="protocolversion">Will contain protocol version, if ping successful</param>
|
||||
/// <returns>TRUE if ping was successful</returns>
|
||||
|
||||
public static bool GetServerInfo(string serverIP, short serverPort, ref int protocolversion)
|
||||
public static bool GetServerInfo(string serverIP, ushort serverPort, ref int protocolversion)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -108,6 +108,7 @@ namespace MinecraftClient.Protocol
|
|||
case "1.7.10":
|
||||
return 5;
|
||||
case "1.8.0":
|
||||
case "1.8.1":
|
||||
return 47;
|
||||
default:
|
||||
return 0;
|
||||
|
|
@ -229,30 +230,37 @@ namespace MinecraftClient.Protocol
|
|||
|
||||
private static int doHTTPSPost(string host, string endpoint, string request, ref string result)
|
||||
{
|
||||
TcpClient client = ProxyHandler.newTcpClient(host, 443);
|
||||
SslStream stream = new SslStream(client.GetStream());
|
||||
stream.AuthenticateAsClient(host);
|
||||
|
||||
List<String> http_request = new List<string>();
|
||||
http_request.Add("POST " + endpoint + " HTTP/1.1");
|
||||
http_request.Add("Host: " + host);
|
||||
http_request.Add("User-Agent: MCC/" + Program.Version);
|
||||
http_request.Add("Content-Type: application/json");
|
||||
http_request.Add("Content-Length: " + Encoding.ASCII.GetBytes(request).Length);
|
||||
http_request.Add("Connection: close");
|
||||
http_request.Add("");
|
||||
http_request.Add(request);
|
||||
|
||||
stream.Write(Encoding.ASCII.GetBytes(String.Join("\r\n", http_request.ToArray())));
|
||||
System.IO.StreamReader sr = new System.IO.StreamReader(stream);
|
||||
string raw_result = sr.ReadToEnd();
|
||||
|
||||
if (raw_result.StartsWith("HTTP/1.1"))
|
||||
string postResult = null;
|
||||
int statusCode = 520;
|
||||
AutoTimeout.Perform(() =>
|
||||
{
|
||||
result = raw_result.Substring(raw_result.IndexOf("\r\n\r\n") + 4);
|
||||
return Settings.str2int(raw_result.Split(' ')[1]);
|
||||
}
|
||||
else return 520; //Web server is returning an unknown error
|
||||
TcpClient client = ProxyHandler.newTcpClient(host, 443);
|
||||
SslStream stream = new SslStream(client.GetStream());
|
||||
stream.AuthenticateAsClient(host);
|
||||
|
||||
List<String> http_request = new List<string>();
|
||||
http_request.Add("POST " + endpoint + " HTTP/1.1");
|
||||
http_request.Add("Host: " + host);
|
||||
http_request.Add("User-Agent: MCC/" + Program.Version);
|
||||
http_request.Add("Content-Type: application/json");
|
||||
http_request.Add("Content-Length: " + Encoding.ASCII.GetBytes(request).Length);
|
||||
http_request.Add("Connection: close");
|
||||
http_request.Add("");
|
||||
http_request.Add(request);
|
||||
|
||||
stream.Write(Encoding.ASCII.GetBytes(String.Join("\r\n", http_request.ToArray())));
|
||||
System.IO.StreamReader sr = new System.IO.StreamReader(stream);
|
||||
string raw_result = sr.ReadToEnd();
|
||||
|
||||
if (raw_result.StartsWith("HTTP/1.1"))
|
||||
{
|
||||
postResult = raw_result.Substring(raw_result.IndexOf("\r\n\r\n") + 4);
|
||||
statusCode = Settings.str2int(raw_result.Split(' ')[1]);
|
||||
}
|
||||
else statusCode = 520; //Web server is returning an unknown error
|
||||
}, 15000);
|
||||
result = postResult;
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace MinecraftClient
|
|||
public static string Username = "";
|
||||
public static string Password = "";
|
||||
public static string ServerIP = "";
|
||||
public static short ServerPort = 25565;
|
||||
public static ushort ServerPort = 25565;
|
||||
public static string ServerVersion = "";
|
||||
public static string SingleCommand = "";
|
||||
public static string ConsoleTitle = "";
|
||||
|
|
@ -86,11 +86,12 @@ namespace MinecraftClient
|
|||
//Remote Control
|
||||
public static bool RemoteCtrl_Enabled = false;
|
||||
public static bool RemoteCtrl_AutoTpaccept = true;
|
||||
public static bool RemoteCtrl_AutoTpaccept_Everyone = false;
|
||||
|
||||
//Custom app variables and Minecraft accounts
|
||||
private static Dictionary<string, string> AppVars = new Dictionary<string, string>();
|
||||
private static Dictionary<string, KeyValuePair<string, string>> Accounts = new Dictionary<string, KeyValuePair<string, string>>();
|
||||
private static Dictionary<string, KeyValuePair<string, short>> Servers = new Dictionary<string, KeyValuePair<string, short>>();
|
||||
private static 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 };
|
||||
|
||||
|
|
@ -154,8 +155,8 @@ namespace MinecraftClient
|
|||
|
||||
case "botowners":
|
||||
Bots_Owners.Clear();
|
||||
foreach (string name in argValue.ToLower().Replace(" ", "").Split(','))
|
||||
Bots_Owners.Add(name);
|
||||
foreach (string name in argValue.ToLower().Split(','))
|
||||
Bots_Owners.Add(name.Trim());
|
||||
break;
|
||||
|
||||
case "internalcmdchar":
|
||||
|
|
@ -186,7 +187,7 @@ namespace MinecraftClient
|
|||
{
|
||||
//Backup current server info
|
||||
string server_host_temp = ServerIP;
|
||||
short server_port_temp = ServerPort;
|
||||
ushort server_port_temp = ServerPort;
|
||||
|
||||
foreach (string server_line in File.ReadAllLines(argValue))
|
||||
{
|
||||
|
|
@ -198,7 +199,7 @@ namespace MinecraftClient
|
|||
&& !server_data[0].Contains('.')
|
||||
&& setServerIP(server_data[1]))
|
||||
Servers[server_data[0]]
|
||||
= new KeyValuePair<string, short>(ServerIP, ServerPort);
|
||||
= new KeyValuePair<string, ushort>(ServerIP, ServerPort);
|
||||
}
|
||||
|
||||
//Restore current server info
|
||||
|
|
@ -271,6 +272,7 @@ namespace MinecraftClient
|
|||
{
|
||||
case "enabled": RemoteCtrl_Enabled = str2bool(argValue); break;
|
||||
case "autotpaccept": RemoteCtrl_AutoTpaccept = str2bool(argValue); break;
|
||||
case "tpaccepteveryone": RemoteCtrl_AutoTpaccept_Everyone = str2bool(argValue); break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -399,7 +401,8 @@ namespace MinecraftClient
|
|||
+ "\r\n"
|
||||
+ "[RemoteControl]\r\n"
|
||||
+ "enabled=false\r\n"
|
||||
+ "autotpaccept=true\r\n", Encoding.UTF8);
|
||||
+ "autotpaccept=true\r\n"
|
||||
+ "tpaccepteveryone=false\r\n", Encoding.UTF8);
|
||||
}
|
||||
|
||||
public static int str2int(string str) { try { return Convert.ToInt32(str); } catch { return 0; } }
|
||||
|
|
@ -432,13 +435,13 @@ namespace MinecraftClient
|
|||
server = server.ToLower();
|
||||
string[] sip = server.Split(':');
|
||||
string host = sip[0];
|
||||
short port = 25565;
|
||||
ushort port = 25565;
|
||||
|
||||
if (sip.Length > 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
port = Convert.ToInt16(sip[1]);
|
||||
port = Convert.ToUInt16(sip[1]);
|
||||
}
|
||||
catch (FormatException) { return false; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ In scripts and remote control, no slash is needed to perform the command.
|
|||
- respawn : Use this to respawn if you are dead (like clicking "respawn" ingame)
|
||||
- log <text> : display some text in the console (useful for scripts)
|
||||
- set varname=value : set a value which can be used as %varname% in further commands
|
||||
- wait <time> : wait <time> : wait X ticks (10 ticks = ~1 second. Only for scripts)
|
||||
- wait <time> : wait X ticks (10 ticks = ~1 second. Only for scripts)
|
||||
- help : show command help. Tip: Use "/send /help" for server help
|
||||
|
||||
[account] is an account alias defined in accounts file, read more below.
|
||||
|
|
@ -161,14 +161,16 @@ When the remote control bot is enabled, you can send commands to your bot using
|
|||
Don't forget to add your username in botowners INI setting if you want it to obey.
|
||||
To perform a command simply do the following: /tell <yourbot> <thecommand>
|
||||
Where <thecommand> is an internal command as described in "Internal commands" section.
|
||||
If enabled, remote control will auto-accept /tpa and /tpahere requests from the bot owners.
|
||||
You can remotely send chat messages or commands using /tell <yourbot> send <thetext>
|
||||
Remote control system can auto-accept /tpa and /tpahere requests from the bot owners.
|
||||
Auto-accept can be disabled or extended to requests from anyone in remote control configuration.
|
||||
|
||||
=========================
|
||||
Disclaimer & Last words
|
||||
=========================
|
||||
|
||||
Even if everything should work, I am not responsible of any damage this app could cause to your computer or your server.
|
||||
This app does not steal your password. If you don't trust it, don't use it or check & compile the source code.
|
||||
This app does not steal your password. If you don't trust it, don't use it or check & compile the source code.
|
||||
|
||||
Also, remember that when you connect to a server with this program, you will appear where you left the last time.
|
||||
This means that you can die if you log in in an unsafe place on a survival server!
|
||||
|
|
@ -178,5 +180,5 @@ You can find more info at:
|
|||
http://www.minecraftforum.net/topic/1314800-/
|
||||
|
||||
+--------------------+
|
||||
| © 2012-2014 ORelio |
|
||||
+--------------------+
|
||||
| © 2012-2015 ORelio |
|
||||
+--------------------+
|
||||
|
|
|
|||
|
|
@ -86,21 +86,24 @@ namespace MinecraftClientGUI
|
|||
while (line.Trim() == "")
|
||||
{
|
||||
line = Client.StandardOutput.ReadLine() + Client.MainWindowTitle;
|
||||
if (line == "Server was successfuly joined.") { disconnected = false; }
|
||||
if (line == "You have left the server.") { disconnected = true; }
|
||||
if (line[0] == (char)0x00)
|
||||
if (line.Length > 0)
|
||||
{
|
||||
//App message from the console
|
||||
string[] command = line.Substring(1).Split((char)0x00);
|
||||
switch (command[0].ToLower())
|
||||
if (line == "Server was successfuly joined.") { disconnected = false; }
|
||||
if (line == "You have left the server.") { disconnected = true; }
|
||||
if (line[0] == (char)0x00)
|
||||
{
|
||||
case "autocomplete":
|
||||
if (command.Length > 1) { tabAutoCompleteBuffer.AddLast(command[1]); }
|
||||
else tabAutoCompleteBuffer.AddLast("");
|
||||
break;
|
||||
//App message from the console
|
||||
string[] command = line.Substring(1).Split((char)0x00);
|
||||
switch (command[0].ToLower())
|
||||
{
|
||||
case "autocomplete":
|
||||
if (command.Length > 1) { tabAutoCompleteBuffer.AddLast(command[1]); }
|
||||
else tabAutoCompleteBuffer.AddLast("");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else OutputBuffer.AddLast(line);
|
||||
}
|
||||
else OutputBuffer.AddLast(line);
|
||||
}
|
||||
}
|
||||
catch (NullReferenceException) { break; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue