The easy to use and full featured Irc Bot everyone is talking about!
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

MainViewModel.cs 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.ComponentModel;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Net;
  9. using System.Runtime.Remoting.Channels;
  10. using System.Threading;
  11. using System.Windows;
  12. using System.Windows.Documents;
  13. using Combot;
  14. using Combot.IRCServices.Messaging;
  15. using Combot.IRCServices.Commanding;
  16. namespace Interface.ViewModels
  17. {
  18. public class MainViewModel : ViewModelBase
  19. {
  20. public string ApplicationTitle { get; set; }
  21. private string _CurrentBuffer = string.Empty;
  22. public string CurrentBuffer
  23. {
  24. get { return _CurrentBuffer; }
  25. set
  26. {
  27. _CurrentBuffer = value;
  28. OnPropertyChanged("CurrentBuffer");
  29. }
  30. }
  31. private bool _Connected = false;
  32. public bool Connected
  33. {
  34. get { return _Connected; }
  35. set
  36. {
  37. _Connected = value;
  38. if (_Connected)
  39. {
  40. ToggleConnectionText = "Disconnect";
  41. }
  42. else
  43. {
  44. ToggleConnectionText = "Connect";
  45. }
  46. OnPropertyChanged("Connected");
  47. }
  48. }
  49. private string _ToggleConnectionText = "Connect";
  50. public string ToggleConnectionText
  51. {
  52. get { return _ToggleConnectionText; }
  53. set
  54. {
  55. _ToggleConnectionText = value;
  56. OnPropertyChanged("ToggleConnectionText");
  57. }
  58. }
  59. private string _InputBoxText;
  60. public string InputBoxText
  61. {
  62. get { return _InputBoxText; }
  63. set
  64. {
  65. _InputBoxText = value;
  66. OnPropertyChanged("InputBoxText");
  67. }
  68. }
  69. private string _SelectedServer;
  70. public string SelectedServer
  71. {
  72. get { return _SelectedServer; }
  73. set
  74. {
  75. _SelectedServer = value;
  76. OnPropertyChanged("SelectedServer");
  77. ChangeServer();
  78. ChangeBuffer();
  79. }
  80. }
  81. private string _SelectedLocation;
  82. public string SelectedLocation
  83. {
  84. get { return _SelectedLocation; }
  85. set
  86. {
  87. _SelectedLocation = value;
  88. OnPropertyChanged("SelectedLocation");
  89. ChangeBuffer();
  90. }
  91. }
  92. private ObservableCollection<string> _ServerList;
  93. public ObservableCollection<string> ServerList
  94. {
  95. get { return _ServerList; }
  96. set
  97. {
  98. if (_ServerList != value)
  99. {
  100. _ServerList = value;
  101. OnPropertyChanged("ServerList");
  102. }
  103. }
  104. }
  105. private ObservableCollection<string> _LocationList;
  106. public ObservableCollection<string> LocationList
  107. {
  108. get { return _LocationList; }
  109. set
  110. {
  111. if (_LocationList != value)
  112. {
  113. _LocationList = value;
  114. OnPropertyChanged("LocationList");
  115. }
  116. }
  117. }
  118. public DelegateCommand ToggleConnection { get; private set; }
  119. public DelegateCommand SubmitText { get; set; }
  120. public DelegateCommand RemoveLocation { get; set; }
  121. public DelegateCommand ClearLocation { get; set; }
  122. private List<BufferInfo> BufferList = new List<BufferInfo>();
  123. private ReaderWriterLockSlim BufferLock;
  124. public MainViewModel()
  125. {
  126. ApplicationTitle = "Combot";
  127. ServerList = new ObservableCollection<string>();
  128. LocationList = new ObservableCollection<string>();
  129. BufferLock = new ReaderWriterLockSlim();
  130. Controller.Instance.Load();
  131. foreach (Bot Combot in Controller.Instance.Bots)
  132. {
  133. ServerList.Add(Combot.ServerConfig.Name);
  134. Combot.ErrorEvent += e => BotErrorHandler(e, Combot.ServerConfig.Name);
  135. // Incoming Messages
  136. Combot.IRC.Message.ErrorMessageEvent += (sender, e) => ErrorMessageHandler(sender, e, Combot.ServerConfig.Name);
  137. Combot.IRC.Message.ServerReplyEvent += (sender, e) => ServerReplyHandler(sender, e, Combot.ServerConfig.Name);
  138. Combot.IRC.Message.ChannelMessageReceivedEvent += (sender, e) => ChannelMessageReceivedHandler(sender, e, Combot.ServerConfig.Name);
  139. Combot.IRC.Message.ChannelNoticeReceivedEvent += (sender, e) => ChannelNoticeReceivedHandler(sender, e, Combot.ServerConfig.Name);
  140. Combot.IRC.Message.PrivateMessageReceivedEvent += (sender, e) => PrivateMessageReceivedHandler(sender, e, Combot.ServerConfig.Name);
  141. Combot.IRC.Message.PrivateNoticeReceivedEvent += (sender, e) => PrivateNoticeReceivedHandler(sender, e, Combot.ServerConfig.Name);
  142. Combot.IRC.Message.JoinChannelEvent += (sender, e) => JoinEventHandler(sender, e, Combot.ServerConfig.Name);
  143. Combot.IRC.Message.PartChannelEvent += (sender, e) => PartEventHandler(sender, e, Combot.ServerConfig.Name);
  144. Combot.IRC.Message.QuitEvent += (sender, e) => QuitEventHandler(sender, e, Combot.ServerConfig.Name);
  145. // Outgoing Messages
  146. Combot.IRC.Command.PrivateMessageCommandEvent += (sender, e) => PrivateMessageCommandHandler(sender, e, Combot.ServerConfig.Name);
  147. Combot.IRC.Command.PrivateNoticeCommandEvent += (sender, e) => PrivateNoticeCommandHandler(sender, e, Combot.ServerConfig.Name);
  148. Combot.IRC.ConnectEvent += () => ConnectHandler(Combot.ServerConfig.Name);
  149. Combot.IRC.DisconnectEvent += () => DisconnectHandler(Combot.ServerConfig.Name);
  150. Combot.IRC.TCPErrorEvent += e => TCPErrorHandler(e, Combot.ServerConfig.Name);
  151. SelectedServer = Combot.ServerConfig.Name;
  152. }
  153. Controller.Instance.AutoConnect();
  154. ToggleConnection = new DelegateCommand(ExecuteToggleConnection, CanToggleConnection);
  155. SubmitText = new DelegateCommand(ExecuteSubmitText, CanSubmitText);
  156. RemoveLocation = new DelegateCommand(ExecuteRemoveLocation, CanRemoveLocation);
  157. ClearLocation = new DelegateCommand(ExecuteClearLocation, CanClearLocation);
  158. }
  159. private void BotErrorHandler(BotError error, string server)
  160. {
  161. AddToBuffer(server, null, string.Format("[{0}] \u0002{1} Error\u0002: {2}", DateTime.Now.ToString("HH:mm:ss"), error.Type, error.Message));
  162. }
  163. private void TCPErrorHandler(Combot.IRCServices.TCP.TCPError error, string server)
  164. {
  165. AddToBuffer(server, null, string.Format("[{0}] \u0002TCP Error {1}\u0002: {2}", DateTime.Now.ToString("HH:mm:ss"), error.Code, error.Message));
  166. }
  167. private void ServerReplyHandler(object sender, IReply reply, string server)
  168. {
  169. AddToBuffer(server, null, string.Format("[{0}] \u0002*\u0002: {1}", reply.TimeStamp.ToString("HH:mm:ss"), reply.Message));
  170. }
  171. private void ErrorMessageHandler(object sender, ErrorMessage message, string server)
  172. {
  173. AddToBuffer(server, null, string.Format("[{0}] \u0002*\u0002: {1}", message.TimeStamp.ToString("HH:mm:ss"), message.Message));
  174. }
  175. private void ChannelMessageReceivedHandler(object sender, ChannelMessage message, string server)
  176. {
  177. AddToBuffer(server, message.Channel, string.Format("[{0}] \u0002{1}\u0002: {2}", message.TimeStamp.ToString("HH:mm:ss"), message.Sender.Nickname, message.Message));
  178. }
  179. private void ChannelNoticeReceivedHandler(object sender, ChannelNotice message, string server)
  180. {
  181. string location = (SelectedServer == server) ? SelectedLocation : null;
  182. AddToBuffer(server, location, string.Format("[{0}] \u0002{1}\u0002 -NOTICE-: {2}", message.TimeStamp.ToString("HH:mm:ss"), message.Sender.Nickname, message.Message));
  183. }
  184. private void PrivateMessageReceivedHandler(object sender, PrivateMessage message, string server)
  185. {
  186. string location = message.Sender.Nickname;
  187. if (message.Sender.Nickname.ToLower() == "nickserv" || message.Sender.Nickname.ToLower() == "chanserv")
  188. {
  189. location = null;
  190. }
  191. AddToBuffer(server, location, string.Format("[{0}] \u0002{1}\u0002: {2}", message.TimeStamp.ToString("HH:mm:ss"), message.Sender.Nickname, message.Message));
  192. }
  193. private void PrivateNoticeReceivedHandler(object sender, PrivateNotice message, string server)
  194. {
  195. string location = (SelectedServer == server) ? SelectedLocation : null;
  196. if (message.Sender.Nickname.ToLower() == "nickserv" || message.Sender.Nickname.ToLower() == "chanserv")
  197. {
  198. location = null;
  199. }
  200. AddToBuffer(server, location, string.Format("[{0}] \u0002{1}\u0002 -NOTICE-: {2}", message.TimeStamp.ToString("HH:mm:ss"), message.Sender.Nickname, message.Message));
  201. }
  202. private void JoinEventHandler(object sender, JoinChannelInfo info, string server)
  203. {
  204. AddToBuffer(server, info.Channel, string.Format("[{0}] \u0002{1}\u0002 has joined \u0002{2}\u0002.", info.TimeStamp.ToString("HH:mm:ss"), info.Nick.Nickname, info.Channel));
  205. }
  206. private void PartEventHandler(object sender, PartChannelInfo info, string server)
  207. {
  208. AddToBuffer(server, info.Channel, string.Format("[{0}] \u0002{1}\u0002 has left \u0002{2}\u0002.", info.TimeStamp.ToString("HH:mm:ss"), info.Nick.Nickname, info.Channel));
  209. }
  210. private void QuitEventHandler(object sender, QuitInfo info, string server)
  211. {
  212. string message = (info.Message == string.Empty) ? info.Nick.Nickname : info.Message;
  213. AddToBuffer(server, null, string.Format("[{0}] \u0002{1}\u0002 has quit: ({2})", info.TimeStamp.ToString("HH:mm:ss"), info.Nick.Nickname, message));
  214. }
  215. private void PrivateMessageCommandHandler(object sender, PrivateMessageCommand message, string server)
  216. {
  217. string curNick = string.Empty;
  218. Bot session = Controller.Instance.GetBot(SelectedServer);
  219. if (session != null)
  220. {
  221. curNick = session.IRC.Nickname;
  222. }
  223. AddToBuffer(server, message.Recipient, string.Format("[{0}] \u0002{1}\u0002: {2}", message.TimeStamp.ToString("HH:mm:ss"), curNick, message.Message));
  224. }
  225. private void PrivateNoticeCommandHandler(object sender, PrivateNoticeCommand message, string server)
  226. {
  227. string curNick = string.Empty;
  228. Bot session = Controller.Instance.GetBot(SelectedServer);
  229. if (session != null)
  230. {
  231. curNick = session.IRC.Nickname;
  232. }
  233. string location = (SelectedServer == server) ? SelectedLocation : null;
  234. AddToBuffer(server, location, string.Format("[{0}] \u0002{1}\u0002 -NOTICE-: {2}", message.TimeStamp.ToString("HH:mm:ss"), curNick, message.Message));
  235. }
  236. private void ConnectHandler(string server)
  237. {
  238. if (server == SelectedServer)
  239. {
  240. Connected = true;
  241. }
  242. AddToBuffer(server, null, "-- Connected --");
  243. }
  244. private void DisconnectHandler(string server)
  245. {
  246. if (server == SelectedServer)
  247. {
  248. Connected = false;
  249. }
  250. AddToBuffer(server, null, "-- Disconnected --");
  251. }
  252. private void ExecuteToggleConnection()
  253. {
  254. if (_Connected)
  255. {
  256. Disconnect(SelectedServer);
  257. }
  258. else
  259. {
  260. Connect(SelectedServer);
  261. }
  262. }
  263. private bool CanToggleConnection()
  264. {
  265. return true;
  266. }
  267. private void ExecuteSubmitText()
  268. {
  269. Bot botInstance = Controller.Instance.GetBot(SelectedServer);
  270. if (botInstance != null && botInstance.Connected)
  271. {
  272. string message = InputBoxText;
  273. if (InputBoxText.StartsWith("/"))
  274. {
  275. MessageType type = MessageType.Query;
  276. if (SelectedLocation.StartsWith("#") || SelectedLocation.StartsWith("&"))
  277. {
  278. type = MessageType.Channel;
  279. }
  280. message = message.Remove(0, 1);
  281. message = string.Join("", botInstance.ServerConfig.CommandPrefix, message);
  282. botInstance.ExecuteCommand(message, SelectedLocation, type);
  283. }
  284. else
  285. {
  286. if (SelectedLocation != " --Server-- ")
  287. {
  288. if (SelectedLocation.StartsWith("#") || SelectedLocation.StartsWith("&"))
  289. {
  290. if (botInstance.IRC.Channels.Exists(chan => chan.Name == SelectedLocation))
  291. {
  292. botInstance.IRC.Command.SendPrivateMessage(SelectedLocation, message);
  293. }
  294. else
  295. {
  296. AddToBuffer(SelectedServer, SelectedLocation, "You are not in this channel.");
  297. }
  298. }
  299. else
  300. {
  301. botInstance.IRC.Command.SendPrivateMessage(SelectedLocation, message);
  302. }
  303. }
  304. }
  305. InputBoxText = string.Empty;
  306. }
  307. }
  308. private bool CanSubmitText()
  309. {
  310. if (Connected)
  311. {
  312. return true;
  313. }
  314. return false;
  315. }
  316. private void ExecuteRemoveLocation()
  317. {
  318. if (SelectedLocation != " --Server-- ")
  319. {
  320. string location = SelectedLocation;
  321. if (location.StartsWith("#") || location.StartsWith("&"))
  322. {
  323. Bot botInstance = Controller.Instance.GetBot(SelectedServer);
  324. if (botInstance.IRC.Channels.Exists(chan => chan.Name == location))
  325. {
  326. botInstance.IRC.Command.SendPart(location);
  327. }
  328. }
  329. if (LocationList.Contains(location))
  330. {
  331. Application.Current.Dispatcher.Invoke((Action)(() => LocationList.Remove(location)));
  332. }
  333. BufferLock.EnterWriteLock();
  334. if (BufferList.Exists(buf => buf.Server == SelectedServer && buf.Location == location))
  335. {
  336. BufferList.RemoveAll(buf => buf.Server == SelectedServer && buf.Location == location);
  337. }
  338. BufferLock.ExitWriteLock();
  339. }
  340. }
  341. private bool CanRemoveLocation()
  342. {
  343. return true;
  344. }
  345. private void ExecuteClearLocation()
  346. {
  347. string location = SelectedLocation;
  348. BufferLock.EnterWriteLock();
  349. if (BufferList.Exists(buf => buf.Server == SelectedServer && buf.Location == location))
  350. {
  351. BufferList.Find(buf => buf.Server == SelectedServer && buf.Location == location).Buffer.Clear();
  352. }
  353. BufferLock.ExitWriteLock();
  354. CurrentBuffer = string.Empty;
  355. }
  356. private bool CanClearLocation()
  357. {
  358. return true;
  359. }
  360. private void Connect(string server)
  361. {
  362. Controller.Instance.GetBot(server).Connect();
  363. }
  364. private void Disconnect(string server)
  365. {
  366. Controller.Instance.GetBot(server).Disconnect();
  367. }
  368. private void AddToBuffer(string server, string location, string message)
  369. {
  370. if (location == null)
  371. {
  372. location = " --Server-- ";
  373. }
  374. BufferLock.EnterWriteLock();
  375. if (!BufferList.Exists(buf => buf.Server == server && buf.Location == location))
  376. {
  377. BufferInfo newBuffer = new BufferInfo();
  378. newBuffer.Server = server;
  379. newBuffer.Location = location;
  380. BufferList.Add(newBuffer);
  381. }
  382. BufferLock.ExitWriteLock();
  383. if (SelectedServer == server && !LocationList.Contains(location))
  384. {
  385. Application.Current.Dispatcher.Invoke((Action) (() => LocationList.Add(location)));
  386. }
  387. BufferLock.EnterWriteLock();
  388. BufferInfo buffer = BufferList.Find(buf => buf.Server == server && buf.Location == location);
  389. if (buffer.Buffer.Count >= 500)
  390. {
  391. buffer.Buffer.RemoveAt(0);
  392. }
  393. buffer.Buffer.Add(message);
  394. BufferLock.ExitWriteLock();
  395. ChangeBuffer();
  396. }
  397. private void ChangeServer()
  398. {
  399. Application.Current.Dispatcher.Invoke((Action)(() => LocationList.Clear()));
  400. for (int i = 0; i < BufferList.Count; i++)
  401. {
  402. if (BufferList[i].Server == SelectedServer)
  403. {
  404. int index = i;
  405. Application.Current.Dispatcher.Invoke((Action)(() => LocationList.Add(BufferList[index].Location)));
  406. }
  407. }
  408. if (LocationList.Any())
  409. {
  410. SelectedLocation = " --Server-- ";
  411. }
  412. }
  413. private void ChangeBuffer()
  414. {
  415. if (SelectedServer != null && SelectedLocation != null)
  416. {
  417. BufferLock.EnterWriteLock();
  418. if (!BufferList.Exists(buf => buf.Server == SelectedServer && buf.Location == SelectedLocation))
  419. {
  420. BufferInfo newBuffer = new BufferInfo();
  421. newBuffer.Server = SelectedServer;
  422. newBuffer.Location = SelectedLocation;
  423. BufferList.Add(newBuffer);
  424. }
  425. CurrentBuffer = string.Join(Environment.NewLine, BufferList.Find(buf => buf.Server == SelectedServer && buf.Location == SelectedLocation).Buffer);
  426. BufferLock.ExitWriteLock();
  427. Bot session = Controller.Instance.GetBot(SelectedServer);
  428. if (session != null)
  429. {
  430. Connected = session.Connected;
  431. }
  432. }
  433. }
  434. }
  435. }