Advertisement
Guest User

Untitled

a guest
Nov 1st, 2014
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.89 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Dynamic;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Timers;
  8. using Newtonsoft.Json;
  9. using Sharkbite.Irc;
  10.  
  11. namespace Pokébot
  12. {
  13. //Controls all IRC behaviours
  14. //Implements the ThresherIRC library
  15. public class IRCBot
  16. {
  17. //Declare IRC connection
  18. private Connection connection;
  19.  
  20. //Declares the requested channel
  21. private string channel;
  22.  
  23. //A list of users and assosciated points
  24. private Dictionary<string, int> points = new Dictionary<string, int>();
  25.  
  26. //A list of pokemon that each user has captured
  27. private Dictionary<string, int> captures = new Dictionary<string, int>();
  28.  
  29. //A list of user levels
  30. private Dictionary<string, int> levels = new Dictionary<string, int>();
  31.  
  32. //A list of trades initiated by a user
  33. private Dictionary<string, string> trades = new Dictionary<string, string>();
  34.  
  35. //The timer which tracks points
  36. private Timer pointsTimer;
  37.  
  38. //The list of usernames of the moderators
  39. private List<string> moderators = new List<string>();
  40.  
  41. //The list of pokemon and their assosciated IDs
  42. private Dictionary<int, string> pokemon = new Dictionary<int, string>();
  43.  
  44. /*
  45. * Method that handles all messages in the channel
  46. * user: An object containing information about the user that spoke
  47. * channel: The channel that the message was spoken to
  48. * message: The message that the user sent
  49. */
  50. void OnPublic(UserInfo user, string channel, string message)
  51. {
  52. Console.WriteLine("Received Message: " + user.User + ":" + message);
  53. //Check for pokéinfo command
  54. if (message.ToLower() == "!pokeinfo")
  55. {
  56. //Send pokéinfo to channel
  57. SendMessage("PokéPoints are gained automatically every 10 seconds just for being in the chat! For the full list of features type !commands");
  58. }
  59. //Check for !commands command
  60. if (message.ToLower() == "!commands")
  61. {
  62. //Send !commands to channel
  63. SendMessage("!timeron !timeroff !addpoints !removepoints !pokeinfo !lookup &lt;user&gt; !capture !release !trade !commands !levelup");
  64. }
  65. //Check for party command
  66. else if (message.ToLower() == "!party")
  67. {
  68. if (captures.ContainsKey(user.User.ToLower()) && captures[user.User.ToLower()] != 0)
  69. SendMessage(user.User + " owns a level " + levels[user.User.ToLower()] + " " + pokemon[captures[user.User.ToLower()]]);
  70. else
  71. SendMessage(user.User + " doesn't own a pokemon.");
  72. }
  73. //Checks for !levelup command
  74. else if (message.ToLower() == "!levelup")
  75. {
  76. if (points[user.User.ToLower()] < 1000)
  77. {
  78. SendMessage("You need 1000 points to level up.");
  79. return;
  80. }
  81. int newPoints = points[user.User.ToLower()] - 1000;
  82. points[user.User.ToLower()] = newPoints;
  83. int newLevel = levels[user.User.ToLower()] + 1;
  84. levels[user.User.ToLower()] = newLevel;
  85. SendMessage(user.User + " has levelled their " + pokemon[captures[user.User.ToLower()]] + " to level " + levels[user.User.ToLower()]);
  86. SaveSettings();
  87. }
  88. //Check for timer on command
  89. else if (message.ToLower() == "!timeron" && moderators.Contains(user.User.ToLower()))
  90. {
  91. pointsTimer.Start();
  92. SendMessage("The timer is now running.");
  93. SaveSettings();
  94. }
  95. //Check for timer off command
  96. else if (message.ToLower() == "!timeroff" && moderators.Contains(user.User.ToLower()))
  97. {
  98. pointsTimer.Stop();
  99. SendMessage("The timer is no longer running.");
  100. SaveSettings();
  101. }
  102. //Checks for play lookup commannd
  103. else if (message.ToLower().StartsWith("!lookup"))
  104. {
  105. //Split the message up into two strings by the space
  106. //0th string is !lookup
  107. //1st string is the username that they give
  108. string[] splitString = message.Split(' ');
  109.  
  110. //If there aren't two strings, stop send back error
  111. if (splitString.Length < 2)
  112. {
  113. //Send error message
  114. SendMessage("Incorrect format. Must be in format: !lookup &lt;user&gt;");
  115. //Stop processing message
  116. return;
  117. }
  118.  
  119. string target = splitString[1].ToLower();
  120.  
  121. //Send back user points if they are being tracked
  122. if (points.ContainsKey(target))
  123. SendMessage(target + " points: " + points[target]);
  124. else
  125. SendMessage(target + " is not being tracked.");
  126. }
  127. //Checks for add point command
  128. else if (message.ToLower().StartsWith("!addpoints") && moderators.Contains(user.User.ToLower()))
  129. {
  130. //Split the message up into three strings by the space
  131. //0th string is !addpoints
  132. //1st string is the username that they give
  133. //2nd string is the number of points to send
  134. string[] splitString = message.Split(' ');
  135.  
  136.  
  137. //If there aren't two strings, stop send back error
  138. if (splitString.Length < 3)
  139. {
  140. //Send error message
  141. SendMessage("Incorrect format. Must be in format: !addpoints &lt;username&gt; &lt;points&gt;");
  142. //Stop processing message
  143. return;
  144. }
  145.  
  146. //Put array elements into their own variables
  147. string target = splitString[1].ToLower();
  148. int pointAmount = (int)double.Parse(splitString[2]);
  149.  
  150. //Check that target user exists
  151. if (points.ContainsKey(target))
  152. {
  153. points[target] = points[target] + pointAmount;
  154. SendMessage(user.User + " has given " + target + " " + pointAmount + " points.");
  155. }
  156. else
  157. SendMessage(target + " is not being tracked.");
  158. SaveSettings();
  159. }
  160. //Checks for remove point command
  161. else if (message.ToLower().StartsWith("!removepoints") && moderators.Contains(user.User.ToLower()))
  162. {
  163. //Split the message up into three strings by the space
  164. //0th string is !removepoints
  165. //1st string is the username that they give
  166. //2nd string is the number of points to take away
  167. string[] splitString = message.Split(' ');
  168.  
  169. //If there aren't two strings, stop send back error
  170. if (splitString.Length < 3)
  171. {
  172. //Send error message
  173. SendMessage("Incorrect format. Must be in format: !removepoints &lt;username&gt; &lt;points&gt;");
  174. //Stop processing message
  175. return;
  176. }
  177.  
  178. //Put array elements into their own variables
  179. string target = splitString[1].ToLower();
  180. int pointAmount = int.Parse(splitString[2]);
  181.  
  182. //Check that target user exists
  183. if (points.ContainsKey(target))
  184. {
  185. points[target] = (points[target] < pointAmount ? 0 : points[target] - pointAmount);
  186. SendMessage(user.User + " has removed " + target + " " + pointAmount + " points.");
  187. }
  188. else
  189. SendMessage(target + " is not being tracked.");
  190. SaveSettings();
  191. }
  192. //Checks for the capture command
  193. else if (message.ToLower() == "!capture")
  194. {
  195. if (captures.ContainsKey(user.User.ToLower()) && captures[user.User.ToLower()] != 0)
  196. {
  197. SendMessage("You already have a pokemon in your party.");
  198. return;
  199. }
  200.  
  201. //Choose a random number of one of the pokemon
  202. Random rand = new Random((int)(DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond));
  203. var newPoke = rand.Next(pokemon.Count);
  204.  
  205. captures.Add(user.User.ToLower(), newPoke);
  206. levels.Add(user.User.ToLower(), 1);
  207. SendMessage(user.User + " has captured a " + pokemon[newPoke]);
  208. SaveSettings();
  209. }
  210. //Checks for the release command
  211. else if (message.ToLower() == "!release")
  212. {
  213. //Does the user have a pokemon already
  214. if (!captures.ContainsKey(user.User.ToLower()))
  215. {
  216. SendMessage("You don't have a pokemon in your party.");
  217. return;
  218. }
  219.  
  220. //Does the user have enough points
  221. if (points[user.User.ToLower()] < 1000)
  222. {
  223. SendMessage("You need 1000 PokéPoints to release.");
  224. return;
  225. }
  226.  
  227. var oldPoke = captures[user.User.ToLower()];
  228. captures.Remove(user.User.ToLower());
  229. SendMessage(user.User + " has released their " + pokemon[oldPoke]);
  230. SaveSettings();
  231. }
  232. //Checks for the trade command
  233. else if (message.ToLower().StartsWith("!trade"))
  234. {
  235. //Split the message up into three strings by the space
  236. //0th string is !trade
  237. //1st string is the username that they give
  238. string[] splitString = message.Split(' ');
  239.  
  240. //If there aren't two strings, stop send back error
  241. if (splitString.Length < 2)
  242. {
  243. //Send error message
  244. SendMessage("Incorrect format. Must be in format: !trade &lt;username&gt;");
  245. //Stop processing message
  246. return;
  247. }
  248.  
  249. //Put array elements into their own variables
  250. string target = splitString[1].ToLower();
  251.  
  252. //They're already trading with this user
  253. if (trades.ContainsKey(user.User.ToLower()) && trades[user.User.ToLower()] == target)
  254. {
  255. SendMessage("You are already trading with " + target);
  256. return;
  257. }
  258.  
  259. //Check if they're accepting a trade request
  260. if (trades.ContainsKey(target) && trades[target] == user.User.ToLower())
  261. {
  262. int targetPokemon = (captures.ContainsKey(target) ? captures[target] : 0);
  263. int userPokemon = (captures.ContainsKey(user.User.ToLower()) ? captures[user.User.ToLower()] : 0);
  264.  
  265. if (targetPokemon == 0 || userPokemon == 0)
  266. {
  267. SendMessage("Both users must have pokemon in their party.");
  268. return;
  269. }
  270.  
  271. //The actual swapping
  272. captures[target] = userPokemon;
  273. captures[user.User.ToLower()] = targetPokemon;
  274.  
  275. int userLevel = levels[user.User.ToLower()];
  276. int targetLevel = levels[target];
  277.  
  278. levels[user.User.ToLower()] = targetLevel;
  279. levels[target] = userLevel;
  280.  
  281. SendMessage(target + " and " + user.User.ToLower() + " have traded pokemon.");
  282.  
  283. //Delete the trade
  284. trades.Remove(target);
  285.  
  286. //Continuing would start a new trade
  287. return;
  288. }
  289.  
  290. if (!captures.ContainsKey(user.User.ToLower()) || !captures.ContainsKey(target))
  291. {
  292. SendMessage("Both users must have pokemon in their party.");
  293. return;
  294. }
  295.  
  296. //Add the request
  297. if (trades.ContainsKey(user.User.ToLower()))
  298. trades.Remove(user.User.ToLower());
  299. trades.Add(user.User.ToLower(), target);
  300.  
  301. Timer timeoutTimer = new Timer(1 * 90 * 1000);
  302. timeoutTimer.Elapsed += (o, i) => RequestTimeout(user.User.ToLower(), target, timeoutTimer);
  303. timeoutTimer.Start();
  304.  
  305. //Notify users of trade
  306. SendMessage(user.User + " has requested a trade with " + target);
  307.  
  308. SaveSettings();
  309. }
  310. }
  311.  
  312. void RequestTimeout(string sender, string target, Timer timer)
  313. {
  314. //If the target trade exists
  315. if (trades.ContainsKey(sender) && trades[sender] == target)
  316. {
  317. //Destroy the current trade
  318. trades.Remove(sender);
  319. SendMessage("The request between " + sender + " and " + target + " has timed out.");
  320. }
  321. timer.Stop();
  322. }
  323.  
  324.  
  325. /*
  326. * Initialises the IRC bot - does not start connection
  327. * Requires IRC username and password
  328. */
  329. public IRCBot(string username, string password, string channel)
  330. {
  331. //Sets the channel for other methods to read
  332. this.channel = channel.ToLower();
  333. //Sets a default IRC server
  334. string server = "irc.twitch.tv";
  335.  
  336. //Create the arguments for the connection
  337. ConnectionArgs args = new ConnectionArgs(username, server);
  338. args.UserName = username;
  339. args.ServerPassword = password;
  340.  
  341. //Initialise connection with the new arguments
  342. connection = new Connection(args, false, false);
  343. connection.TextEncoding = new UTF8Encoding();
  344.  
  345. //Connect all of the event handlers
  346. connection.Listener.OnRegistered += OnRegistered;
  347. connection.Listener.OnPublic += OnPublic;
  348. connection.Listener.OnJoin += OnJoin;
  349. connection.Listener.OnPart += OnPart;
  350. connection.Listener.OnNames += OnNames;
  351. connection.Listener.OnChannelModeChange += OnChannelModeChange;
  352.  
  353. //Load all settings
  354. LoadAllSettings();
  355. }
  356.  
  357. //Starts running the IRC bot and receiving messages
  358. public void Run()
  359. {
  360. try
  361. {
  362. Console.WriteLine("Bot connecting...");
  363.  
  364. Identd.Start(connection.connectionArgs.UserName);
  365.  
  366. //Starts the IRC connection
  367. connection.Connect();
  368. }
  369. catch (Exception ex)
  370. {
  371. Console.WriteLine("An exception has occurred. (Run)");
  372. Console.WriteLine(ex.Message);
  373. }
  374. }
  375.  
  376. //Handles connection registering - connects to channel
  377. public void OnRegistered()
  378. {
  379. try
  380. {
  381. Console.WriteLine("Bot connected to chat!");
  382.  
  383. Identd.Stop();
  384.  
  385. //Join the IRC channel
  386. connection.Sender.Join(channel.ToLower());
  387.  
  388. //Creates the new points timer
  389. pointsTimer = new Timer(10 * 1000);
  390. pointsTimer.Elapsed += PointsTimerElapsed;
  391. pointsTimer.Start();
  392.  
  393. }
  394. catch (Exception ex)
  395. {
  396. Console.WriteLine("An exception has occurred. (OnRegistered)");
  397. Console.WriteLine(ex.Message);
  398. }
  399. }
  400.  
  401. /*
  402. * Method that handles users joining the chat
  403. * user: An object containing information about the user that joined
  404. * channel: The channel that the new user joined
  405. */
  406. void OnJoin(UserInfo user, string channel)
  407. {
  408. //Checks that the user that connected was not the bot
  409. if (connection.connectionArgs.UserName.ToLower() != user.User.ToLower())
  410. SendMessage(user.User + " has joined the chat, and is now earning PokéPoints.");
  411.  
  412. //Check if we are already tracking user points, otherwise add them as 0 points
  413. if (!points.ContainsKey(user.User.ToLower()))
  414. points.Add(user.User.ToLower(), 0);
  415. }
  416.  
  417. /*
  418. * Method that handles users leaving the chat
  419. * user: An object containing information about the user that leaving
  420. * channel: The channel that the new user leaving
  421. */
  422. void OnPart(UserInfo user, string channel, string reason)
  423. {
  424. //Check if we are already tracking user points
  425. if (points.ContainsKey(user.User.ToLower()))
  426. points.Remove(user.User.ToLower());
  427. }
  428.  
  429. /*
  430. * Handles an initial list of pre-connected users
  431. * channel: The channel which the users are connected
  432. * nicks: The users connected to the channel
  433. * last: The last set of names
  434. */
  435. void OnNames(string channel, string[] nicks, bool last)
  436. {
  437. //Add each name to the point list
  438. foreach (string name in nicks)
  439. if (!points.ContainsKey(name.ToLower()))
  440. points.Add(name.ToLower(), 0);
  441. }
  442.  
  443. void OnChannelModeChange(UserInfo who, string channel, ChannelModeInfo[] modes)
  444. {
  445. foreach (ChannelModeInfo mode in modes)
  446. {
  447. string user = mode.Parameter;
  448. if (mode.Mode == ChannelMode.ChannelOperator)
  449. {
  450. if (mode.Action == ModeAction.Add)
  451. moderators.Add(user.ToLower());
  452. else if (mode.Action == ModeAction.Remove)
  453. {
  454. if (moderators.Contains(user.ToLower()))
  455. moderators.Remove(user.ToLower());
  456. }
  457. }
  458. }
  459. }
  460.  
  461. /*
  462. * Every tick of the points timer, adds points to each user
  463. */
  464. void PointsTimerElapsed(object sender, ElapsedEventArgs e)
  465. {
  466. foreach (string user in points.Keys.ToList())
  467. points[user] += 1;
  468. SaveSettings();
  469. }
  470.  
  471. //Loads all of the settings into the program
  472. void LoadAllSettings()
  473. {
  474. //Reads the configuration file into a string
  475. StreamReader reader = new StreamReader("points.config");
  476. string settingsFile = reader.ReadToEnd();
  477. reader.Close();
  478.  
  479. //Deserialises the configuration into a variable
  480. dynamic settings = JsonConvert.DeserializeObject(settingsFile);
  481.  
  482. foreach (dynamic user in settings.users)
  483. {
  484. points.Add((string)user.username, (int)user.points);
  485. if (user.pokemon != null && user.pokemon != 0)
  486. captures.Add((string)user.username, (int)user.pokemon);
  487. if (user.level != null && user.level != 0)
  488. levels.Add((string)user.username, (int)user.level);
  489. }
  490.  
  491. //Reads the pokemon file into a string
  492. StreamReader pokemonReader = new StreamReader("pokemon.config");
  493. string pokemonFile = pokemonReader.ReadToEnd();
  494. pokemonReader.Close();
  495.  
  496. //Deserialises the pokemon into a variable
  497. dynamic pokemonList = JsonConvert.DeserializeObject(pokemonFile);
  498.  
  499. foreach (dynamic pokemon in pokemonList.pokemon)
  500. this.pokemon.Add((int)pokemon.id, (string)pokemon.name);
  501. }
  502.  
  503. //Saves the settings into the points configuration file
  504. void SaveSettings()
  505. {
  506. //Creates the list of users
  507. dynamic users = new List<ExpandoObject>();
  508.  
  509. foreach (string user in points.Keys.ToList())
  510. {
  511. dynamic userObject = new ExpandoObject();
  512. userObject.username = user;
  513. userObject.points = points[user];
  514. if (captures.ContainsKey(user.ToLower()))
  515. userObject.pokemon = captures[user.ToLower()];
  516. else userObject.pokemon = 0;
  517. if (levels.ContainsKey(user.ToLower()))
  518. userObject.level = levels[user.ToLower()];
  519. else userObject.level = 0;
  520. users.Add(userObject);
  521. }
  522.  
  523. //Adds the users array to the settings
  524. dynamic settings = new ExpandoObject();
  525. settings.users = users;
  526.  
  527. StreamWriter streamWriter = new StreamWriter("points.config");
  528. JsonWriter writer = new JsonTextWriter(streamWriter);
  529. writer.Formatting = Formatting.Indented;
  530.  
  531. //Writes to the settings file
  532. JsonSerializer serialiser = new JsonSerializer();
  533. serialiser.Serialize(writer, settings);
  534.  
  535. writer.Close();
  536. streamWriter.Close();
  537. }
  538.  
  539. /*
  540. * Sends a message through to the IRC with /me appended
  541. * channel: The channel to send the message to
  542. * message: The message to be sent
  543. */
  544. void SendMessage(string message)
  545. {
  546. connection.Sender.PublicMessage(channel, "/me " + message);
  547. }
  548. }
  549. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement