mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-11-07 17:36:07 +00:00
App refactoring almost done
- Created specific namespaces and folders for each app brick - Added proxy support using Starksoft's Biko Library - App bricks: Main, ChatBots, Crypto, Protocol, Proxy - Each class is now in its own file (Aes streams, chatbots) - Used "Bridge" design pattern for Crypto, Protocol, Proxy - Added back support for Minecraft 1.4.6 to 1.6.4 (MCC 1.6.2) - Need to fully re-test everything and fix bugs - To Fix : Server pinging is slow on SpigotMC - To Do : Add Minecraft 1.2.5 (MCC 1.3) and maybe 1.3 to 1.4.5
This commit is contained in:
parent
9be1d99ca0
commit
d2ec2f48b7
43 changed files with 6039 additions and 2178 deletions
129
MinecraftClient/ChatBots/Alerts.cs
Normal file
129
MinecraftClient/ChatBots/Alerts.cs
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
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()
|
||||
{
|
||||
if (System.IO.File.Exists(Settings.Alerts_MatchesFile))
|
||||
{
|
||||
dictionary = System.IO.File.ReadAllLines(Settings.Alerts_MatchesFile);
|
||||
|
||||
for (int i = 0; i < dictionary.Length; i++)
|
||||
{
|
||||
dictionary[i] = dictionary[i].ToLower();
|
||||
}
|
||||
}
|
||||
else LogToConsole("File not found: " + Settings.Alerts_MatchesFile);
|
||||
|
||||
if (System.IO.File.Exists(Settings.Alerts_ExcludesFile))
|
||||
{
|
||||
excludelist = System.IO.File.ReadAllLines(Settings.Alerts_ExcludesFile);
|
||||
|
||||
for (int i = 0; i < excludelist.Length; i++)
|
||||
{
|
||||
excludelist[i] = excludelist[i].ToLower();
|
||||
}
|
||||
}
|
||||
else LogToConsole("File not found : " + Settings.Alerts_ExcludesFile);
|
||||
}
|
||||
|
||||
public override void GetText(string text)
|
||||
{
|
||||
text = getVerbatim(text);
|
||||
string comp = text.ToLower();
|
||||
foreach (string alert in dictionary)
|
||||
{
|
||||
if (comp.Contains(alert))
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
foreach (string exclusion in excludelist)
|
||||
{
|
||||
if (comp.Contains(exclusion))
|
||||
{
|
||||
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;
|
||||
|
||||
//Will be used for text displaying
|
||||
string[] temp = comp.Split(alert.Split(','), StringSplitOptions.RemoveEmptyEntries);
|
||||
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)
|
||||
{
|
||||
Console.BackgroundColor = ConsoleColor.Yellow;
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
for (int i = 0; i < alert.Length; i++)
|
||||
{
|
||||
ConsoleIO.Write(text[p]);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
//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) { }
|
||||
}
|
||||
Console.BackgroundColor = ConsoleColor.Black;
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
ConsoleIO.Write('\n');
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
39
MinecraftClient/ChatBots/AntiAFK.cs
Normal file
39
MinecraftClient/ChatBots/AntiAFK.cs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MinecraftClient.ChatBots
|
||||
{
|
||||
/// <summary>
|
||||
/// This bot sends a command every 60 seconds in order to stay non-afk.
|
||||
/// </summary>
|
||||
|
||||
public class AntiAFK : ChatBot
|
||||
{
|
||||
private int count;
|
||||
private int timeping;
|
||||
|
||||
/// <summary>
|
||||
/// This bot sends a /ping command every X seconds in order to stay non-afk.
|
||||
/// </summary>
|
||||
/// <param name="pingparam">Time amount between each ping (10 = 1s, 600 = 1 minute, etc.)</param>
|
||||
|
||||
public AntiAFK(int pingparam)
|
||||
{
|
||||
count = 0;
|
||||
timeping = pingparam;
|
||||
if (timeping < 10) { timeping = 10; } //To avoid flooding
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
count++;
|
||||
if (count == timeping)
|
||||
{
|
||||
SendText(Settings.AntiAFK_Command);
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
66
MinecraftClient/ChatBots/AutoRelog.cs
Normal file
66
MinecraftClient/ChatBots/AutoRelog.cs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MinecraftClient.ChatBots
|
||||
{
|
||||
/// <summary>
|
||||
/// This bot automatically re-join the server if kick message contains predefined string (Server is restarting ...)
|
||||
/// </summary>
|
||||
|
||||
public class AutoRelog : ChatBot
|
||||
{
|
||||
private string[] dictionary = new string[0];
|
||||
private int attempts;
|
||||
private int delay;
|
||||
|
||||
/// <summary>
|
||||
/// This bot automatically re-join the server if kick message contains predefined string
|
||||
/// </summary>
|
||||
/// <param name="DelayBeforeRelog">Delay before re-joining the server (in seconds)</param>
|
||||
/// <param name="retries">Number of retries if connection fails (-1 = infinite)</param>
|
||||
|
||||
public AutoRelog(int DelayBeforeRelog, int retries)
|
||||
{
|
||||
attempts = retries;
|
||||
if (attempts == -1) { attempts = int.MaxValue; }
|
||||
McTcpClient.AttemptsLeft = attempts;
|
||||
delay = DelayBeforeRelog;
|
||||
if (delay < 1) { delay = 1; }
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
McTcpClient.AttemptsLeft = attempts;
|
||||
if (System.IO.File.Exists(Settings.AutoRelog_KickMessagesFile))
|
||||
{
|
||||
dictionary = System.IO.File.ReadAllLines(Settings.AutoRelog_KickMessagesFile);
|
||||
|
||||
for (int i = 0; i < dictionary.Length; i++)
|
||||
{
|
||||
dictionary[i] = dictionary[i].ToLower();
|
||||
}
|
||||
}
|
||||
else LogToConsole("File not found: " + Settings.AutoRelog_KickMessagesFile);
|
||||
}
|
||||
|
||||
public override bool OnDisconnect(DisconnectReason reason, string message)
|
||||
{
|
||||
message = getVerbatim(message);
|
||||
string comp = message.ToLower();
|
||||
foreach (string msg in dictionary)
|
||||
{
|
||||
if (comp.Contains(msg))
|
||||
{
|
||||
LogToConsole("Waiting " + delay + " seconds before reconnecting...");
|
||||
System.Threading.Thread.Sleep(delay * 1000);
|
||||
McTcpClient.AttemptsLeft = attempts;
|
||||
ReconnectToTheServer();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
115
MinecraftClient/ChatBots/ChatLog.cs
Normal file
115
MinecraftClient/ChatBots/ChatLog.cs
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MinecraftClient.ChatBots
|
||||
{
|
||||
/// <summary>
|
||||
/// This bot saves the received messages in a text file.
|
||||
/// </summary>
|
||||
|
||||
public class ChatLog : ChatBot
|
||||
{
|
||||
public enum MessageFilter { AllText, AllMessages, OnlyChat, OnlyWhispers };
|
||||
private bool dateandtime;
|
||||
private bool saveOther = true;
|
||||
private bool saveChat = true;
|
||||
private bool savePrivate = true;
|
||||
private string logfile;
|
||||
|
||||
/// <summary>
|
||||
/// This bot saves the messages received in the specified file, with some filters and date/time tagging.
|
||||
/// </summary>
|
||||
/// <param name="file">The file to save the log in</param>
|
||||
/// <param name="filter">The kind of messages to save</param>
|
||||
/// <param name="AddDateAndTime">Add a date and time before each message</param>
|
||||
|
||||
public ChatLog(string file, MessageFilter filter, bool AddDateAndTime)
|
||||
{
|
||||
dateandtime = AddDateAndTime;
|
||||
logfile = file;
|
||||
switch (filter)
|
||||
{
|
||||
case MessageFilter.AllText:
|
||||
saveOther = true;
|
||||
savePrivate = true;
|
||||
saveChat = true;
|
||||
break;
|
||||
case MessageFilter.AllMessages:
|
||||
saveOther = false;
|
||||
savePrivate = true;
|
||||
saveChat = true;
|
||||
break;
|
||||
case MessageFilter.OnlyChat:
|
||||
saveOther = false;
|
||||
savePrivate = false;
|
||||
saveChat = true;
|
||||
break;
|
||||
case MessageFilter.OnlyWhispers:
|
||||
saveOther = false;
|
||||
savePrivate = true;
|
||||
saveChat = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static MessageFilter str2filter(string filtername)
|
||||
{
|
||||
switch (filtername.ToLower())
|
||||
{
|
||||
case "all": return MessageFilter.AllText;
|
||||
case "messages": return MessageFilter.AllMessages;
|
||||
case "chat": return MessageFilter.OnlyChat;
|
||||
case "private": return MessageFilter.OnlyWhispers;
|
||||
default: return MessageFilter.AllText;
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetText(string text)
|
||||
{
|
||||
text = getVerbatim(text);
|
||||
string sender = "";
|
||||
string message = "";
|
||||
|
||||
if (saveChat && isChatMessage(text, ref message, ref sender))
|
||||
{
|
||||
save("Chat " + sender + ": " + message);
|
||||
}
|
||||
else if (savePrivate && isPrivateMessage(text, ref message, ref sender))
|
||||
{
|
||||
save("Private " + sender + ": " + message);
|
||||
}
|
||||
else if (saveOther)
|
||||
{
|
||||
save("Other: " + text);
|
||||
}
|
||||
}
|
||||
|
||||
private void save(string tosave)
|
||||
{
|
||||
if (dateandtime)
|
||||
{
|
||||
int day = DateTime.Now.Day, month = DateTime.Now.Month;
|
||||
int hour = DateTime.Now.Hour, minute = DateTime.Now.Minute, second = DateTime.Now.Second;
|
||||
|
||||
string D = day < 10 ? "0" + day : "" + day;
|
||||
string M = month < 10 ? "0" + month : "" + day;
|
||||
string Y = "" + DateTime.Now.Year;
|
||||
|
||||
string h = hour < 10 ? "0" + hour : "" + hour;
|
||||
string m = minute < 10 ? "0" + minute : "" + minute;
|
||||
string s = second < 10 ? "0" + second : "" + second;
|
||||
|
||||
tosave = "" + D + '-' + M + '-' + Y + ' ' + h + ':' + m + ':' + s + ' ' + tosave;
|
||||
}
|
||||
|
||||
System.IO.FileStream stream = new System.IO.FileStream(logfile, System.IO.FileMode.OpenOrCreate);
|
||||
System.IO.StreamWriter writer = new System.IO.StreamWriter(stream);
|
||||
stream.Seek(0, System.IO.SeekOrigin.End);
|
||||
writer.WriteLine(tosave);
|
||||
writer.Dispose();
|
||||
stream.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
188
MinecraftClient/ChatBots/HangmanGame.cs
Normal file
188
MinecraftClient/ChatBots/HangmanGame.cs
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MinecraftClient.ChatBots
|
||||
{
|
||||
/// <summary>
|
||||
/// In-Chat Hangman game
|
||||
/// </summary>
|
||||
|
||||
public class HangmanGame : ChatBot
|
||||
{
|
||||
private int vie = 0;
|
||||
private int vie_param = 10;
|
||||
private int compteur = 0;
|
||||
private int compteur_param = 3000; //5 minutes
|
||||
private bool running = false;
|
||||
private bool[] discovered;
|
||||
private string word = "";
|
||||
private string letters = "";
|
||||
private bool English;
|
||||
|
||||
/// <summary>
|
||||
/// Le jeu du Pendu / Hangman Game
|
||||
/// </summary>
|
||||
/// <param name="english">if true, the game will be in english. If false, the game will be in french.</param>
|
||||
|
||||
public HangmanGame(bool english)
|
||||
{
|
||||
English = english;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (running)
|
||||
{
|
||||
if (compteur > 0)
|
||||
{
|
||||
compteur--;
|
||||
}
|
||||
else
|
||||
{
|
||||
SendText(English ? "You took too long to try a letter." : "Temps imparti écoulé !");
|
||||
SendText(English ? "Game canceled." : "Partie annulée.");
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetText(string text)
|
||||
{
|
||||
string message = "";
|
||||
string username = "";
|
||||
text = getVerbatim(text);
|
||||
|
||||
if (isPrivateMessage(text, ref message, ref username))
|
||||
{
|
||||
if (Settings.Bots_Owners.Contains(username.ToLower()))
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case "start":
|
||||
start();
|
||||
break;
|
||||
case "stop":
|
||||
running = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (running && isChatMessage(text, ref message, ref username))
|
||||
{
|
||||
if (message.Length == 1)
|
||||
{
|
||||
char letter = message.ToUpper()[0];
|
||||
if (letter >= 'A' && letter <= 'Z')
|
||||
{
|
||||
if (letters.Contains(letter))
|
||||
{
|
||||
SendText(English ? ("Letter " + letter + " has already been tried.") : ("Le " + letter + " a déjà été proposé."));
|
||||
}
|
||||
else
|
||||
{
|
||||
letters += letter;
|
||||
compteur = compteur_param;
|
||||
|
||||
if (word.Contains(letter))
|
||||
{
|
||||
for (int i = 0; i < word.Length; i++) { if (word[i] == letter) { discovered[i] = true; } }
|
||||
SendText(English ? ("Yes, the word contains a " + letter + '!') : ("Le " + letter + " figurait bien dans le mot :)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
vie--;
|
||||
if (vie == 0)
|
||||
{
|
||||
SendText(English ? "Game Over! :]" : "Perdu ! Partie terminée :]");
|
||||
SendText(English ? ("The word was: " + word) : ("Le mot était : " + word));
|
||||
running = false;
|
||||
}
|
||||
else SendText(English ? ("The " + letter + "? No.") : ("Le " + letter + " ? Non."));
|
||||
}
|
||||
|
||||
if (running)
|
||||
{
|
||||
SendText(English ? ("Mysterious word: " + word_cached + " (lives : " + vie + ")")
|
||||
: ("Mot mystère : " + word_cached + " (vie : " + vie + ")"));
|
||||
}
|
||||
|
||||
if (winner)
|
||||
{
|
||||
SendText(English ? ("Congrats, " + username + '!') : ("Félicitations, " + username + " !"));
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void start()
|
||||
{
|
||||
vie = vie_param;
|
||||
running = true;
|
||||
letters = "";
|
||||
word = chooseword();
|
||||
compteur = compteur_param;
|
||||
discovered = new bool[word.Length];
|
||||
|
||||
SendText(English ? "Hangman v1.0 - By ORelio" : "Pendu v1.0 - Par ORelio");
|
||||
SendText(English ? ("Mysterious word: " + word_cached + " (lives : " + vie + ")")
|
||||
: ("Mot mystère : " + word_cached + " (vie : " + vie + ")"));
|
||||
SendText(English ? ("Try some letters ... :)") : ("Proposez une lettre ... :)"));
|
||||
}
|
||||
|
||||
private string chooseword()
|
||||
{
|
||||
if (System.IO.File.Exists(English ? Settings.Hangman_FileWords_EN : Settings.Hangman_FileWords_FR))
|
||||
{
|
||||
string[] dico = System.IO.File.ReadAllLines(English ? Settings.Hangman_FileWords_EN : Settings.Hangman_FileWords_FR);
|
||||
return dico[new Random().Next(dico.Length)];
|
||||
}
|
||||
else
|
||||
{
|
||||
LogToConsole(English ? "File not found: " + Settings.Hangman_FileWords_EN : "Fichier introuvable : " + Settings.Hangman_FileWords_FR);
|
||||
return English ? "WORDSAREMISSING" : "DICOMANQUANT";
|
||||
}
|
||||
}
|
||||
|
||||
private string word_cached
|
||||
{
|
||||
get
|
||||
{
|
||||
string printed = "";
|
||||
for (int i = 0; i < word.Length; i++)
|
||||
{
|
||||
if (discovered[i])
|
||||
{
|
||||
printed += word[i];
|
||||
}
|
||||
else printed += '_';
|
||||
}
|
||||
return printed;
|
||||
}
|
||||
}
|
||||
|
||||
private bool winner
|
||||
{
|
||||
get
|
||||
{
|
||||
for (int i = 0; i < discovered.Length; i++)
|
||||
{
|
||||
if (!discovered[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
53
MinecraftClient/ChatBots/PlayerListLogger.cs
Normal file
53
MinecraftClient/ChatBots/PlayerListLogger.cs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MinecraftClient.ChatBots
|
||||
{
|
||||
/// <summary>
|
||||
/// This bot sends a /list command every X seconds and save the result.
|
||||
/// </summary>
|
||||
|
||||
public class PlayerListLogger : ChatBot
|
||||
{
|
||||
private int count;
|
||||
private int timeping;
|
||||
private string file;
|
||||
|
||||
/// <summary>
|
||||
/// This bot sends a /list command every X seconds and save the result.
|
||||
/// </summary>
|
||||
/// <param name="pingparam">Time amount between each list ping (10 = 1s, 600 = 1 minute, etc.)</param>
|
||||
|
||||
public PlayerListLogger(int pingparam, string filetosavein)
|
||||
{
|
||||
count = 0;
|
||||
file = filetosavein;
|
||||
timeping = pingparam;
|
||||
if (timeping < 10) { timeping = 10; } //To avoid flooding
|
||||
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
count++;
|
||||
if (count == timeping)
|
||||
{
|
||||
SendText("/list");
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetText(string text)
|
||||
{
|
||||
if (text.Contains("Joueurs en ligne") || text.Contains("Connected:") || text.Contains("online:"))
|
||||
{
|
||||
LogToConsole("Saving Player List");
|
||||
DateTime now = DateTime.Now;
|
||||
string TimeStamp = "[" + now.Year + '/' + now.Month + '/' + now.Day + ' ' + now.Hour + ':' + now.Minute + ']';
|
||||
System.IO.File.AppendAllText(file, TimeStamp + "\n" + getVerbatim(text) + "\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
68
MinecraftClient/ChatBots/RemoteControl.cs
Normal file
68
MinecraftClient/ChatBots/RemoteControl.cs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MinecraftClient.ChatBots
|
||||
{
|
||||
/// <summary>
|
||||
/// Allow to perform operations using whispers to the bot
|
||||
/// </summary>
|
||||
|
||||
public class RemoteControl : ChatBot
|
||||
{
|
||||
public override void GetText(string text)
|
||||
{
|
||||
text = getVerbatim(text);
|
||||
string command = "", sender = "";
|
||||
if (isPrivateMessage(text, ref command, ref sender) && Settings.Bots_Owners.Contains(sender.ToLower()))
|
||||
{
|
||||
string cmd_name = command.Split(' ')[0];
|
||||
switch (cmd_name.ToLower())
|
||||
{
|
||||
case "exit":
|
||||
DisconnectAndExit();
|
||||
break;
|
||||
case "reco":
|
||||
ReconnectToTheServer();
|
||||
break;
|
||||
case "script":
|
||||
if (command.Length >= 8)
|
||||
RunScript(command.Substring(7), sender);
|
||||
break;
|
||||
case "send":
|
||||
if (command.Length >= 6)
|
||||
SendText(command.Substring(5));
|
||||
break;
|
||||
case "connect":
|
||||
if (command.Length >= 9)
|
||||
{
|
||||
Settings.ServerIP = command.Substring(8);
|
||||
ReconnectToTheServer();
|
||||
}
|
||||
break;
|
||||
case "help":
|
||||
if (command.Length >= 6)
|
||||
{
|
||||
string help_cmd_name = command.Substring(5).ToLower();
|
||||
switch (help_cmd_name)
|
||||
{
|
||||
case "exit": SendPrivateMessage(sender, "exit: disconnect from the server."); break;
|
||||
case "reco": SendPrivateMessage(sender, "reco: restart and reconnct to the server."); break;
|
||||
case "script": SendPrivateMessage(sender, "script <scriptname>: run a script file."); break;
|
||||
case "send": SendPrivateMessage(sender, "send <text>: send a chat message or command."); break;
|
||||
case "connect": SendPrivateMessage(sender, "connect <serverip>: connect to the specified server."); break;
|
||||
case "help": SendPrivateMessage(sender, "help <cmdname>: show brief help about a command."); break;
|
||||
default: SendPrivateMessage(sender, "help: unknown command '" + help_cmd_name + "'."); break;
|
||||
}
|
||||
}
|
||||
else SendPrivateMessage(sender, "help <cmdname>. Available commands: exit, reco, script, send, connect.");
|
||||
break;
|
||||
default:
|
||||
SendPrivateMessage(sender, "Unknown command '" + cmd_name + "'. Use 'help' for help.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
134
MinecraftClient/ChatBots/Script.cs
Normal file
134
MinecraftClient/ChatBots/Script.cs
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MinecraftClient.ChatBots
|
||||
{
|
||||
/// <summary>
|
||||
/// Runs a list of commands
|
||||
/// </summary>
|
||||
|
||||
public class Script : ChatBot
|
||||
{
|
||||
private string file;
|
||||
private string[] lines = new string[0];
|
||||
private int sleepticks = 10;
|
||||
private int sleepticks_interval = 10;
|
||||
private int nextline = 0;
|
||||
private string owner;
|
||||
|
||||
public Script(string filename)
|
||||
{
|
||||
file = filename;
|
||||
}
|
||||
|
||||
public Script(string filename, string ownername)
|
||||
: this(filename)
|
||||
{
|
||||
if (ownername != "")
|
||||
owner = ownername;
|
||||
}
|
||||
|
||||
public static bool lookForScript(ref string filename)
|
||||
{
|
||||
//Automatically look in subfolders and try to add ".txt" file extension
|
||||
string[] files = new string[]
|
||||
{
|
||||
filename,
|
||||
filename + ".txt",
|
||||
"scripts\\" + filename,
|
||||
"scripts\\" + filename + ".txt",
|
||||
"config\\" + filename,
|
||||
"config\\" + filename + ".txt",
|
||||
};
|
||||
|
||||
foreach (string possible_file in files)
|
||||
{
|
||||
if (System.IO.File.Exists(possible_file))
|
||||
{
|
||||
filename = possible_file;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
//Load the given file from the startup parameters
|
||||
if (lookForScript(ref file))
|
||||
{
|
||||
lines = System.IO.File.ReadAllLines(file);
|
||||
if (owner != null) { SendPrivateMessage(owner, "Script '" + file + "' loaded."); }
|
||||
}
|
||||
else
|
||||
{
|
||||
LogToConsole("File not found: '" + file + "'");
|
||||
if (owner != null)
|
||||
SendPrivateMessage(owner, "File not found: '" + file + "'");
|
||||
UnloadBot(); //No need to keep the bot active
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (sleepticks > 0) { sleepticks--; }
|
||||
else
|
||||
{
|
||||
if (nextline < lines.Length) //Is there an instruction left to interpret?
|
||||
{
|
||||
string instruction_line = lines[nextline].Trim(); // Removes all whitespaces at start and end of current line
|
||||
nextline++; //Move the cursor so that the next time the following line will be interpreted
|
||||
sleepticks = sleepticks_interval; //Used to delay next command sending and prevent from beign kicked for spamming
|
||||
|
||||
if (instruction_line.Length > 1)
|
||||
{
|
||||
if (instruction_line[0] != '#' && instruction_line[0] != '/' && instruction_line[1] != '/')
|
||||
{
|
||||
string instruction_name = instruction_line.Split(' ')[0];
|
||||
switch (instruction_name.ToLower())
|
||||
{
|
||||
case "send":
|
||||
SendText(instruction_line.Substring(5, instruction_line.Length - 5));
|
||||
break;
|
||||
case "wait":
|
||||
int ticks = 10;
|
||||
try
|
||||
{
|
||||
ticks = Convert.ToInt32(instruction_line.Substring(5, instruction_line.Length - 5));
|
||||
}
|
||||
catch { }
|
||||
sleepticks = ticks;
|
||||
break;
|
||||
case "disconnect":
|
||||
DisconnectAndExit();
|
||||
break;
|
||||
case "exit": //Exit bot & stay connected to the server
|
||||
UnloadBot();
|
||||
break;
|
||||
case "connect":
|
||||
if (instruction_line.Length >= 9)
|
||||
{
|
||||
Settings.ServerIP = instruction_line.Substring(8);
|
||||
ReconnectToTheServer();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sleepticks = 0; Update(); //Unknown command : process next line immediately
|
||||
break;
|
||||
}
|
||||
}
|
||||
else { sleepticks = 0; Update(); } //Comment: process next line immediately
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//No more instructions to interpret
|
||||
UnloadBot();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
143
MinecraftClient/ChatBots/ScriptScheduler.cs
Normal file
143
MinecraftClient/ChatBots/ScriptScheduler.cs
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Globalization;
|
||||
|
||||
namespace MinecraftClient.ChatBots
|
||||
{
|
||||
/// <summary>
|
||||
/// Trigger scripts on specific events
|
||||
/// </summary>
|
||||
|
||||
public class ScriptScheduler : ChatBot
|
||||
{
|
||||
private class TaskDesc
|
||||
{
|
||||
public string script_file = null;
|
||||
public bool triggerOnFirstLogin = false;
|
||||
public bool triggerOnLogin = false;
|
||||
public bool triggerOnTime = false;
|
||||
public List<DateTime> triggerOnTime_Times = new List<DateTime>();
|
||||
public bool alreadyTriggered = false;
|
||||
}
|
||||
|
||||
private static bool firstlogin_done = false;
|
||||
|
||||
private string tasksfile;
|
||||
private bool serverlogin_done;
|
||||
private List<TaskDesc> tasks = new List<TaskDesc>();
|
||||
private int verifytasks_timeleft = 10;
|
||||
private int verifytasks_delay = 10;
|
||||
|
||||
public ScriptScheduler(string tasksfile)
|
||||
{
|
||||
this.tasksfile = tasksfile;
|
||||
serverlogin_done = false;
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
//Load the given file from the startup parameters
|
||||
if (System.IO.File.Exists(tasksfile))
|
||||
{
|
||||
TaskDesc current_task = null;
|
||||
String[] lines = System.IO.File.ReadAllLines(tasksfile);
|
||||
foreach (string lineRAW in lines)
|
||||
{
|
||||
string line = lineRAW.Split('#')[0].Trim();
|
||||
if (line.Length > 0)
|
||||
{
|
||||
if (line[0] == '[' && line[line.Length - 1] == ']')
|
||||
{
|
||||
switch (line.Substring(1, line.Length - 2).ToLower())
|
||||
{
|
||||
case "task":
|
||||
checkAddTask(current_task);
|
||||
current_task = new TaskDesc(); //Create a blank task
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (current_task != null)
|
||||
{
|
||||
string argName = line.Split('=')[0];
|
||||
if (line.Length > (argName.Length + 1))
|
||||
{
|
||||
string argValue = line.Substring(argName.Length + 1);
|
||||
switch (argName.ToLower())
|
||||
{
|
||||
case "triggeronfirstlogin": current_task.triggerOnFirstLogin = Settings.str2bool(argValue); break;
|
||||
case "triggeronlogin": current_task.triggerOnLogin = Settings.str2bool(argValue); break;
|
||||
case "triggerontime": current_task.triggerOnTime = Settings.str2bool(argValue); break;
|
||||
case "timevalue": try { current_task.triggerOnTime_Times.Add(DateTime.ParseExact(argValue, "HH:mm", CultureInfo.InvariantCulture)); }
|
||||
catch { } break;
|
||||
case "script": current_task.script_file = argValue; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
checkAddTask(current_task);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogToConsole("File not found: '" + tasksfile + "'");
|
||||
UnloadBot(); //No need to keep the bot active
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAddTask(TaskDesc current_task)
|
||||
{
|
||||
if (current_task != null)
|
||||
{
|
||||
//Check if we built a valid task before adding it
|
||||
if (current_task.script_file != null && Script.lookForScript(ref current_task.script_file) //Check if file exists
|
||||
&& (current_task.triggerOnLogin || (current_task.triggerOnTime && current_task.triggerOnTime_Times.Count > 0))) //Look for a valid trigger
|
||||
{
|
||||
tasks.Add(current_task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (verifytasks_timeleft <= 0)
|
||||
{
|
||||
verifytasks_timeleft = verifytasks_delay;
|
||||
if (serverlogin_done)
|
||||
{
|
||||
foreach (TaskDesc task in tasks)
|
||||
{
|
||||
if (task.triggerOnTime)
|
||||
{
|
||||
foreach (DateTime time in task.triggerOnTime_Times)
|
||||
{
|
||||
if (time.Hour == DateTime.Now.Hour && time.Minute == DateTime.Now.Minute)
|
||||
{
|
||||
if (!task.alreadyTriggered)
|
||||
{
|
||||
task.alreadyTriggered = true;
|
||||
RunScript(task.script_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else task.alreadyTriggered = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (TaskDesc task in tasks)
|
||||
{
|
||||
if (task.triggerOnLogin || (firstlogin_done == false && task.triggerOnFirstLogin))
|
||||
RunScript(task.script_file);
|
||||
}
|
||||
|
||||
firstlogin_done = true;
|
||||
serverlogin_done = true;
|
||||
}
|
||||
}
|
||||
else verifytasks_timeleft--;
|
||||
}
|
||||
}
|
||||
}
|
||||
30
MinecraftClient/ChatBots/TestBot.cs
Normal file
30
MinecraftClient/ChatBots/TestBot.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MinecraftClient.ChatBots
|
||||
{
|
||||
/// <summary>
|
||||
/// Example of message receiving.
|
||||
/// </summary>
|
||||
|
||||
public class TestBot : ChatBot
|
||||
{
|
||||
public override void GetText(string text)
|
||||
{
|
||||
string message = "";
|
||||
string username = "";
|
||||
text = getVerbatim(text);
|
||||
|
||||
if (isPrivateMessage(text, ref message, ref username))
|
||||
{
|
||||
ConsoleIO.WriteLine("Bot: " + username + " told me : " + message);
|
||||
}
|
||||
else if (isChatMessage(text, ref message, ref username))
|
||||
{
|
||||
ConsoleIO.WriteLine("Bot: " + username + " said : " + message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue