Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Dynamic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Timers;
- using Newtonsoft.Json;
- using Sharkbite.Irc;
- namespace Pokébot
- {
- //Controls all IRC behaviours
- //Implements the ThresherIRC library
- public class IRCBot
- {
- //Declare IRC connection
- private Connection connection;
- //Declares the requested channel
- private string channel;
- //A list of users and assosciated points
- private Dictionary<string, int> points = new Dictionary<string, int>();
- //A list of pokemon that each user has captured
- private Dictionary<string, int> captures = new Dictionary<string, int>();
- //A list of user levels
- private Dictionary<string, int> levels = new Dictionary<string, int>();
- //A list of trades initiated by a user
- private Dictionary<string, string> trades = new Dictionary<string, string>();
- //The timer which tracks points
- private Timer pointsTimer;
- //The list of usernames of the moderators
- private List<string> moderators = new List<string>();
- //The list of pokemon and their assosciated IDs
- private Dictionary<int, string> pokemon = new Dictionary<int, string>();
- /*
- * Method that handles all messages in the channel
- * user: An object containing information about the user that spoke
- * channel: The channel that the message was spoken to
- * message: The message that the user sent
- */
- void OnPublic(UserInfo user, string channel, string message)
- {
- Console.WriteLine("Received Message: " + user.User + ":" + message);
- //Check for pokéinfo command
- if (message.ToLower() == "!pokeinfo")
- {
- //Send pokéinfo to channel
- SendMessage("PokéPoints are gained automatically every 10 seconds just for being in the chat! For the full list of features type !commands");
- }
- //Check for !commands command
- if (message.ToLower() == "!commands")
- {
- //Send !commands to channel
- SendMessage("!timeron !timeroff !addpoints !removepoints !pokeinfo !lookup <user> !capture !release !trade !commands !levelup");
- }
- //Check for party command
- else if (message.ToLower() == "!party")
- {
- if (captures.ContainsKey(user.User.ToLower()) && captures[user.User.ToLower()] != 0)
- SendMessage(user.User + " owns a level " + levels[user.User.ToLower()] + " " + pokemon[captures[user.User.ToLower()]]);
- else
- SendMessage(user.User + " doesn't own a pokemon.");
- }
- //Checks for !levelup command
- else if (message.ToLower() == "!levelup")
- {
- if (points[user.User.ToLower()] < 1000)
- {
- SendMessage("You need 1000 points to level up.");
- return;
- }
- int newPoints = points[user.User.ToLower()] - 1000;
- points[user.User.ToLower()] = newPoints;
- int newLevel = levels[user.User.ToLower()] + 1;
- levels[user.User.ToLower()] = newLevel;
- SendMessage(user.User + " has levelled their " + pokemon[captures[user.User.ToLower()]] + " to level " + levels[user.User.ToLower()]);
- SaveSettings();
- }
- //Check for timer on command
- else if (message.ToLower() == "!timeron" && moderators.Contains(user.User.ToLower()))
- {
- pointsTimer.Start();
- SendMessage("The timer is now running.");
- SaveSettings();
- }
- //Check for timer off command
- else if (message.ToLower() == "!timeroff" && moderators.Contains(user.User.ToLower()))
- {
- pointsTimer.Stop();
- SendMessage("The timer is no longer running.");
- SaveSettings();
- }
- //Checks for play lookup commannd
- else if (message.ToLower().StartsWith("!lookup"))
- {
- //Split the message up into two strings by the space
- //0th string is !lookup
- //1st string is the username that they give
- string[] splitString = message.Split(' ');
- //If there aren't two strings, stop send back error
- if (splitString.Length < 2)
- {
- //Send error message
- SendMessage("Incorrect format. Must be in format: !lookup <user>");
- //Stop processing message
- return;
- }
- string target = splitString[1].ToLower();
- //Send back user points if they are being tracked
- if (points.ContainsKey(target))
- SendMessage(target + " points: " + points[target]);
- else
- SendMessage(target + " is not being tracked.");
- }
- //Checks for add point command
- else if (message.ToLower().StartsWith("!addpoints") && moderators.Contains(user.User.ToLower()))
- {
- //Split the message up into three strings by the space
- //0th string is !addpoints
- //1st string is the username that they give
- //2nd string is the number of points to send
- string[] splitString = message.Split(' ');
- //If there aren't two strings, stop send back error
- if (splitString.Length < 3)
- {
- //Send error message
- SendMessage("Incorrect format. Must be in format: !addpoints <username> <points>");
- //Stop processing message
- return;
- }
- //Put array elements into their own variables
- string target = splitString[1].ToLower();
- int pointAmount = (int)double.Parse(splitString[2]);
- //Check that target user exists
- if (points.ContainsKey(target))
- {
- points[target] = points[target] + pointAmount;
- SendMessage(user.User + " has given " + target + " " + pointAmount + " points.");
- }
- else
- SendMessage(target + " is not being tracked.");
- SaveSettings();
- }
- //Checks for remove point command
- else if (message.ToLower().StartsWith("!removepoints") && moderators.Contains(user.User.ToLower()))
- {
- //Split the message up into three strings by the space
- //0th string is !removepoints
- //1st string is the username that they give
- //2nd string is the number of points to take away
- string[] splitString = message.Split(' ');
- //If there aren't two strings, stop send back error
- if (splitString.Length < 3)
- {
- //Send error message
- SendMessage("Incorrect format. Must be in format: !removepoints <username> <points>");
- //Stop processing message
- return;
- }
- //Put array elements into their own variables
- string target = splitString[1].ToLower();
- int pointAmount = int.Parse(splitString[2]);
- //Check that target user exists
- if (points.ContainsKey(target))
- {
- points[target] = (points[target] < pointAmount ? 0 : points[target] - pointAmount);
- SendMessage(user.User + " has removed " + target + " " + pointAmount + " points.");
- }
- else
- SendMessage(target + " is not being tracked.");
- SaveSettings();
- }
- //Checks for the capture command
- else if (message.ToLower() == "!capture")
- {
- if (captures.ContainsKey(user.User.ToLower()) && captures[user.User.ToLower()] != 0)
- {
- SendMessage("You already have a pokemon in your party.");
- return;
- }
- //Choose a random number of one of the pokemon
- Random rand = new Random((int)(DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond));
- var newPoke = rand.Next(pokemon.Count);
- captures.Add(user.User.ToLower(), newPoke);
- levels.Add(user.User.ToLower(), 1);
- SendMessage(user.User + " has captured a " + pokemon[newPoke]);
- SaveSettings();
- }
- //Checks for the release command
- else if (message.ToLower() == "!release")
- {
- //Does the user have a pokemon already
- if (!captures.ContainsKey(user.User.ToLower()))
- {
- SendMessage("You don't have a pokemon in your party.");
- return;
- }
- //Does the user have enough points
- if (points[user.User.ToLower()] < 1000)
- {
- SendMessage("You need 1000 PokéPoints to release.");
- return;
- }
- var oldPoke = captures[user.User.ToLower()];
- captures.Remove(user.User.ToLower());
- SendMessage(user.User + " has released their " + pokemon[oldPoke]);
- SaveSettings();
- }
- //Checks for the trade command
- else if (message.ToLower().StartsWith("!trade"))
- {
- //Split the message up into three strings by the space
- //0th string is !trade
- //1st string is the username that they give
- string[] splitString = message.Split(' ');
- //If there aren't two strings, stop send back error
- if (splitString.Length < 2)
- {
- //Send error message
- SendMessage("Incorrect format. Must be in format: !trade <username>");
- //Stop processing message
- return;
- }
- //Put array elements into their own variables
- string target = splitString[1].ToLower();
- //They're already trading with this user
- if (trades.ContainsKey(user.User.ToLower()) && trades[user.User.ToLower()] == target)
- {
- SendMessage("You are already trading with " + target);
- return;
- }
- //Check if they're accepting a trade request
- if (trades.ContainsKey(target) && trades[target] == user.User.ToLower())
- {
- int targetPokemon = (captures.ContainsKey(target) ? captures[target] : 0);
- int userPokemon = (captures.ContainsKey(user.User.ToLower()) ? captures[user.User.ToLower()] : 0);
- if (targetPokemon == 0 || userPokemon == 0)
- {
- SendMessage("Both users must have pokemon in their party.");
- return;
- }
- //The actual swapping
- captures[target] = userPokemon;
- captures[user.User.ToLower()] = targetPokemon;
- int userLevel = levels[user.User.ToLower()];
- int targetLevel = levels[target];
- levels[user.User.ToLower()] = targetLevel;
- levels[target] = userLevel;
- SendMessage(target + " and " + user.User.ToLower() + " have traded pokemon.");
- //Delete the trade
- trades.Remove(target);
- //Continuing would start a new trade
- return;
- }
- if (!captures.ContainsKey(user.User.ToLower()) || !captures.ContainsKey(target))
- {
- SendMessage("Both users must have pokemon in their party.");
- return;
- }
- //Add the request
- if (trades.ContainsKey(user.User.ToLower()))
- trades.Remove(user.User.ToLower());
- trades.Add(user.User.ToLower(), target);
- Timer timeoutTimer = new Timer(1 * 90 * 1000);
- timeoutTimer.Elapsed += (o, i) => RequestTimeout(user.User.ToLower(), target, timeoutTimer);
- timeoutTimer.Start();
- //Notify users of trade
- SendMessage(user.User + " has requested a trade with " + target);
- SaveSettings();
- }
- }
- void RequestTimeout(string sender, string target, Timer timer)
- {
- //If the target trade exists
- if (trades.ContainsKey(sender) && trades[sender] == target)
- {
- //Destroy the current trade
- trades.Remove(sender);
- SendMessage("The request between " + sender + " and " + target + " has timed out.");
- }
- timer.Stop();
- }
- /*
- * Initialises the IRC bot - does not start connection
- * Requires IRC username and password
- */
- public IRCBot(string username, string password, string channel)
- {
- //Sets the channel for other methods to read
- this.channel = channel.ToLower();
- //Sets a default IRC server
- string server = "irc.twitch.tv";
- //Create the arguments for the connection
- ConnectionArgs args = new ConnectionArgs(username, server);
- args.UserName = username;
- args.ServerPassword = password;
- //Initialise connection with the new arguments
- connection = new Connection(args, false, false);
- connection.TextEncoding = new UTF8Encoding();
- //Connect all of the event handlers
- connection.Listener.OnRegistered += OnRegistered;
- connection.Listener.OnPublic += OnPublic;
- connection.Listener.OnJoin += OnJoin;
- connection.Listener.OnPart += OnPart;
- connection.Listener.OnNames += OnNames;
- connection.Listener.OnChannelModeChange += OnChannelModeChange;
- //Load all settings
- LoadAllSettings();
- }
- //Starts running the IRC bot and receiving messages
- public void Run()
- {
- try
- {
- Console.WriteLine("Bot connecting...");
- Identd.Start(connection.connectionArgs.UserName);
- //Starts the IRC connection
- connection.Connect();
- }
- catch (Exception ex)
- {
- Console.WriteLine("An exception has occurred. (Run)");
- Console.WriteLine(ex.Message);
- }
- }
- //Handles connection registering - connects to channel
- public void OnRegistered()
- {
- try
- {
- Console.WriteLine("Bot connected to chat!");
- Identd.Stop();
- //Join the IRC channel
- connection.Sender.Join(channel.ToLower());
- //Creates the new points timer
- pointsTimer = new Timer(10 * 1000);
- pointsTimer.Elapsed += PointsTimerElapsed;
- pointsTimer.Start();
- }
- catch (Exception ex)
- {
- Console.WriteLine("An exception has occurred. (OnRegistered)");
- Console.WriteLine(ex.Message);
- }
- }
- /*
- * Method that handles users joining the chat
- * user: An object containing information about the user that joined
- * channel: The channel that the new user joined
- */
- void OnJoin(UserInfo user, string channel)
- {
- //Checks that the user that connected was not the bot
- if (connection.connectionArgs.UserName.ToLower() != user.User.ToLower())
- SendMessage(user.User + " has joined the chat, and is now earning PokéPoints.");
- //Check if we are already tracking user points, otherwise add them as 0 points
- if (!points.ContainsKey(user.User.ToLower()))
- points.Add(user.User.ToLower(), 0);
- }
- /*
- * Method that handles users leaving the chat
- * user: An object containing information about the user that leaving
- * channel: The channel that the new user leaving
- */
- void OnPart(UserInfo user, string channel, string reason)
- {
- //Check if we are already tracking user points
- if (points.ContainsKey(user.User.ToLower()))
- points.Remove(user.User.ToLower());
- }
- /*
- * Handles an initial list of pre-connected users
- * channel: The channel which the users are connected
- * nicks: The users connected to the channel
- * last: The last set of names
- */
- void OnNames(string channel, string[] nicks, bool last)
- {
- //Add each name to the point list
- foreach (string name in nicks)
- if (!points.ContainsKey(name.ToLower()))
- points.Add(name.ToLower(), 0);
- }
- void OnChannelModeChange(UserInfo who, string channel, ChannelModeInfo[] modes)
- {
- foreach (ChannelModeInfo mode in modes)
- {
- string user = mode.Parameter;
- if (mode.Mode == ChannelMode.ChannelOperator)
- {
- if (mode.Action == ModeAction.Add)
- moderators.Add(user.ToLower());
- else if (mode.Action == ModeAction.Remove)
- {
- if (moderators.Contains(user.ToLower()))
- moderators.Remove(user.ToLower());
- }
- }
- }
- }
- /*
- * Every tick of the points timer, adds points to each user
- */
- void PointsTimerElapsed(object sender, ElapsedEventArgs e)
- {
- foreach (string user in points.Keys.ToList())
- points[user] += 1;
- SaveSettings();
- }
- //Loads all of the settings into the program
- void LoadAllSettings()
- {
- //Reads the configuration file into a string
- StreamReader reader = new StreamReader("points.config");
- string settingsFile = reader.ReadToEnd();
- reader.Close();
- //Deserialises the configuration into a variable
- dynamic settings = JsonConvert.DeserializeObject(settingsFile);
- foreach (dynamic user in settings.users)
- {
- points.Add((string)user.username, (int)user.points);
- if (user.pokemon != null && user.pokemon != 0)
- captures.Add((string)user.username, (int)user.pokemon);
- if (user.level != null && user.level != 0)
- levels.Add((string)user.username, (int)user.level);
- }
- //Reads the pokemon file into a string
- StreamReader pokemonReader = new StreamReader("pokemon.config");
- string pokemonFile = pokemonReader.ReadToEnd();
- pokemonReader.Close();
- //Deserialises the pokemon into a variable
- dynamic pokemonList = JsonConvert.DeserializeObject(pokemonFile);
- foreach (dynamic pokemon in pokemonList.pokemon)
- this.pokemon.Add((int)pokemon.id, (string)pokemon.name);
- }
- //Saves the settings into the points configuration file
- void SaveSettings()
- {
- //Creates the list of users
- dynamic users = new List<ExpandoObject>();
- foreach (string user in points.Keys.ToList())
- {
- dynamic userObject = new ExpandoObject();
- userObject.username = user;
- userObject.points = points[user];
- if (captures.ContainsKey(user.ToLower()))
- userObject.pokemon = captures[user.ToLower()];
- else userObject.pokemon = 0;
- if (levels.ContainsKey(user.ToLower()))
- userObject.level = levels[user.ToLower()];
- else userObject.level = 0;
- users.Add(userObject);
- }
- //Adds the users array to the settings
- dynamic settings = new ExpandoObject();
- settings.users = users;
- StreamWriter streamWriter = new StreamWriter("points.config");
- JsonWriter writer = new JsonTextWriter(streamWriter);
- writer.Formatting = Formatting.Indented;
- //Writes to the settings file
- JsonSerializer serialiser = new JsonSerializer();
- serialiser.Serialize(writer, settings);
- writer.Close();
- streamWriter.Close();
- }
- /*
- * Sends a message through to the IRC with /me appended
- * channel: The channel to send the message to
- * message: The message to be sent
- */
- void SendMessage(string message)
- {
- connection.Sender.PublicMessage(channel, "/me " + message);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement