PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/ZeroKLobby_NET4.0/MicroLobby/ChatTab.cs

https://github.com/db81/Zero-K-Infrastructure
C# | 379 lines | 321 code | 54 blank | 4 comment | 99 complexity | 3057d8340b74b018190f22499f34c9f5 MD5 | raw file
Possible License(s): GPL-3.0, MIT
  1. using System;
  2. using System.Diagnostics;
  3. using System.Globalization;
  4. using System.Linq;
  5. using System.Text.RegularExpressions;
  6. using System.Windows.Forms;
  7. using LobbyClient;
  8. using ZeroKLobby;
  9. using ZeroKLobby.Lines;
  10. using ZeroKLobby.Notifications;
  11. using ZkData;
  12. namespace ZeroKLobby.MicroLobby
  13. {
  14. public partial class ChatTab : UserControl, INavigatable
  15. {
  16. BattleChatControl battleChatControl;
  17. readonly ToolTabs toolTabs = new ToolTabs { Dock = DockStyle.Fill };
  18. string focusWhenJoin;
  19. public ChatTab()
  20. {
  21. SuspendLayout();
  22. InitializeComponent();
  23. if (Process.GetCurrentProcess().ProcessName == "devenv") return; // detect design mode, workaround for non-working this.DesignMode
  24. Controls.Add(toolTabs);
  25. AddBattleControl();
  26. Program.TasClient.ChannelJoined += client_ChannelJoined;
  27. Program.TasClient.Said += client_Said;
  28. Program.TasClient.ConnectionLost += TasClient_ConnectionLost;
  29. Program.TasClient.ChannelLeft += TasClient_ChannelLeft;
  30. Program.TasClient.LoginAccepted += TasClient_LoginAccepted;
  31. Program.TasClient.UserRemoved += TasClient_UserRemoved;
  32. Program.TasClient.UserAdded += TasClient_UserAdded;
  33. Program.FriendManager.FriendAdded += FriendManager_FriendAdded;
  34. Program.FriendManager.FriendRemoved += FriendManager_FriendRemoved;
  35. Program.TasClient.ChannelJoinFailed += TasClient_ChannelJoinFailed;
  36. foreach (var channel in Program.TasClient.JoinedChannels.Values.Where(c => !IsIgnoredChannel(c.Name))) CreateChannelControl(channel.Name);
  37. toolTabs.SelectChannelTab("Battle");
  38. ResumeLayout();
  39. }
  40. public void CloseChannelTab(string key)
  41. {
  42. toolTabs.RemoveChannelTab(key);
  43. }
  44. public void ClosePrivateTab(string key)
  45. {
  46. toolTabs.RemovePrivateTab(key);
  47. }
  48. public PrivateMessageControl CreatePrivateMessageControl(string userName)
  49. {
  50. var pmControl = new PrivateMessageControl(userName) { Dock = DockStyle.Fill };
  51. var isFriend = Program.FriendManager.Friends.Contains(userName);
  52. User user;
  53. var isOffline = !Program.TasClient.ExistingUsers.TryGetValue(userName, out user);
  54. var icon = isOffline ? ZklResources.grayuser : TextImage.GetUserImage(userName);
  55. var contextMenu = new ContextMenu();
  56. if (!isFriend)
  57. {
  58. var closeButton = new MenuItem();
  59. closeButton.Click += (s, e) => toolTabs.RemovePrivateTab(userName);
  60. contextMenu.MenuItems.Add(closeButton);
  61. }
  62. toolTabs.AddTab(userName, userName, pmControl, icon, ToolTipHandler.GetUserToolTipString(userName), 0);
  63. pmControl.ChatLine +=
  64. (s, e) =>
  65. {
  66. if (Program.TasClient.IsLoggedIn)
  67. {
  68. if (Program.TasClient.ExistingUsers.ContainsKey(userName)) Program.TasClient.Say(SayPlace.User, userName, e.Data, false);
  69. else Program.TasClient.Say(SayPlace.User, GlobalConst.NightwatchName, e.Data, false, string.Format("!pm {0} ", userName)); // send using PM
  70. }
  71. };
  72. return pmControl;
  73. }
  74. public static bool IsIgnoredChannel(string channelName)
  75. {
  76. return false;
  77. }
  78. public void OpenChannel(string channelName)
  79. {
  80. if (GetChannelControl(channelName) != null) toolTabs.SelectChannelTab(channelName);
  81. else
  82. {
  83. focusWhenJoin = channelName;
  84. Program.TasClient.JoinChannel(channelName);
  85. }
  86. }
  87. public void OpenPrivateMessageChannel(string userName)
  88. {
  89. if (GetPrivateMessageControl(userName) == null) CreatePrivateMessageControl(userName);
  90. toolTabs.SelectPrivateTab(userName);
  91. }
  92. public string GetNextTabPath()
  93. {
  94. return toolTabs.GetNextTabPath();
  95. }
  96. public string GetPrevTabPath()
  97. {
  98. return toolTabs.GetPrevTabPath();
  99. }
  100. void AddBattleControl()
  101. {
  102. if (battleChatControl == null || battleChatControl.IsDisposed) battleChatControl = new BattleChatControl { Dock = DockStyle.Fill };
  103. if (toolTabs.GetChannelTab("Battle") == null) toolTabs.AddTab("Battle", "Battle", battleChatControl, ZklResources.battle, "Current battle room", 3);
  104. }
  105. ChatControl CreateChannelControl(string channelName)
  106. {
  107. if (IsIgnoredChannel(channelName)) return null;
  108. var existing = GetChannelControl(channelName);
  109. if (existing != null) return existing;
  110. var chatControl = new ChatControl(channelName) { Dock = DockStyle.Fill };
  111. var gameInfo = KnownGames.List.FirstOrDefault(x => x.Channel == channelName);
  112. if (gameInfo != null) toolTabs.AddTab(channelName, gameInfo.FullName, chatControl, ZklResources.game, null, 2);
  113. else toolTabs.AddTab(channelName, channelName, chatControl, ZklResources.chat, null, 1);
  114. chatControl.ChatLine += (s, e) => Program.TasClient.Say(SayPlace.Channel, channelName, e.Data, false);
  115. return chatControl;
  116. }
  117. public ChatControl GetChannelControl(string channelName)
  118. {
  119. return toolTabs.GetChannelTab(channelName);
  120. }
  121. PrivateMessageControl GetPrivateMessageControl(string userName)
  122. {
  123. return toolTabs.GetPrivateTab(userName);
  124. }
  125. void client_ChannelJoined(object sender, EventArgs<Channel> channel)
  126. {
  127. var channelName = channel.Data.Name;
  128. CreateChannelControl(channelName);
  129. if (focusWhenJoin == channelName)
  130. {
  131. toolTabs.SelectChannelTab(channelName);
  132. focusWhenJoin = null;
  133. }
  134. }
  135. void client_Said(object sender, TasSayEventArgs e)
  136. {
  137. var tas = (TasClient)sender;
  138. if (Program.Conf.IgnoredUsers.Contains(e.UserName))
  139. {
  140. return;
  141. }
  142. if (e.Place == SayPlace.Battle && !e.IsEmote && !Program.TasClient.MyUser.IsInGame) Program.MainWindow.NotifyUser("chat/battle", null);
  143. if (e.Place == SayPlace.Channel && !IsIgnoredChannel(e.Channel)) Program.MainWindow.NotifyUser("chat/channel/" + e.Channel, null);
  144. else if (e.Place == SayPlace.User)
  145. {
  146. var otherUserName = e.UserName == tas.UserName ? e.Channel : e.UserName;
  147. // support for offline pm and persistent channels
  148. if (otherUserName == GlobalConst.NightwatchName && e.Text.StartsWith("!pm"))
  149. {
  150. // message received
  151. if (e.UserName == GlobalConst.NightwatchName)
  152. {
  153. var regex = Regex.Match(e.Text, "!pm\\|([^\\|]*)\\|([^\\|]+)\\|([^\\|]+)\\|([^\\|]+)");
  154. if (regex.Success)
  155. {
  156. var chan = regex.Groups[1].Value;
  157. var name = regex.Groups[2].Value;
  158. var time = DateTime.Parse(regex.Groups[3].Value, CultureInfo.InvariantCulture).ToLocalTime();
  159. var text = regex.Groups[4].Value;
  160. if (string.IsNullOrEmpty(chan))
  161. {
  162. var pmControl = GetPrivateMessageControl(name) ?? CreatePrivateMessageControl(name);
  163. pmControl.AddLine(new SaidLine(name, text, time));
  164. MainWindow.Instance.NotifyUser("chat/user/" + name, string.Format("{0}: {1}", name, text), false, true);
  165. }
  166. else
  167. {
  168. var chatControl = GetChannelControl(chan) ?? CreateChannelControl(chan);
  169. chatControl.AddLine(new SaidLine(name, text, time));
  170. Program.MainWindow.NotifyUser("chat/channel/" + chan, null);
  171. }
  172. }
  173. else
  174. {
  175. Trace.TraceWarning("Incomprehensible Nightwatch message: {0}", e.Text);
  176. }
  177. }
  178. else // message sent to nightwatch
  179. {
  180. var regex = Regex.Match(e.Text, "!pm ([^ ]+) (.*)");
  181. if (regex.Success)
  182. {
  183. var name = regex.Groups[1].Value;
  184. var text = regex.Groups[2].Value;
  185. var pmControl = GetPrivateMessageControl(name) ?? CreatePrivateMessageControl(name);
  186. pmControl.AddLine(new SaidLine(Program.Conf.LobbyPlayerName, text));
  187. }
  188. }
  189. }
  190. else
  191. {
  192. var pmControl = GetPrivateMessageControl(otherUserName);
  193. // block non friend messages
  194. if (pmControl == null && Program.Conf.BlockNonFriendPm && !Program.FriendManager.Friends.Contains(otherUserName) && !Program.TasClient.ExistingUsers[e.UserName].IsBot)
  195. {
  196. if (e.UserName != Program.TasClient.UserName)
  197. Program.TasClient.Say(SayPlace.User,
  198. otherUserName,
  199. "Sorry, I'm busy and do not receive messages. If you want to ask something, use #zk channel. If you have issue to report use http://code.google.com/p/zero-k/issues/list",
  200. false);
  201. }
  202. else
  203. {
  204. pmControl = pmControl ?? CreatePrivateMessageControl(otherUserName);
  205. if (!e.IsEmote) pmControl.AddLine(new SaidLine(e.UserName, e.Text));
  206. else pmControl.AddLine(new SaidExLine(e.UserName, e.Text));
  207. if (e.UserName != Program.TasClient.MyUser.Name)
  208. {
  209. MainWindow.Instance.NotifyUser("chat/user/" + otherUserName,
  210. string.Format("{0}: {1}", otherUserName, e.Text),
  211. false,
  212. true);
  213. }
  214. }
  215. }
  216. }
  217. else if (e.Place == SayPlace.MessageBox) Trace.TraceInformation("TASC: {0}", e.Text);
  218. if (e.Place == SayPlace.MessageBox) WarningBar.DisplayWarning(e.Text, "Message from server");
  219. }
  220. void FriendManager_FriendAdded(object sender, EventArgs<string> e)
  221. {
  222. var userName = e.Data;
  223. toolTabs.RemovePrivateTab(userName);
  224. var pm = CreatePrivateMessageControl(userName);
  225. toolTabs.SelectPrivateTab(userName);
  226. }
  227. void FriendManager_FriendRemoved(object sender, EventArgs<string> e)
  228. {
  229. toolTabs.RemovePrivateTab(e.Data);
  230. }
  231. void TasClient_ChannelJoinFailed(object sender, EventArgs<JoinChannelResponse> joinChannelResponse)
  232. {
  233. WarningBar.DisplayWarning("Channel Joining Error - " + joinChannelResponse.Data.Reason, "Cannot join channel");
  234. }
  235. void TasClient_ChannelLeft(object sender, EventArgs<Channel> channel)
  236. {
  237. var channelName = channel.Data.Name;
  238. var chatControl = GetChannelControl(channelName);
  239. toolTabs.RemoveChannelTab(channelName);
  240. if (chatControl != null)
  241. {
  242. chatControl.Reset();
  243. chatControl.Dispose();
  244. }
  245. }
  246. void TasClient_ConnectionLost(object sender, TasEventArgs e)
  247. {
  248. toolTabs.DisposeAllTabs();
  249. AddBattleControl();
  250. }
  251. void TasClient_LoginAccepted(object sender, TasEventArgs e)
  252. {
  253. AddBattleControl();
  254. foreach (var friendName in Program.FriendManager.Friends) CreatePrivateMessageControl(friendName);
  255. foreach (var channel in Program.AutoJoinManager.Channels) Program.TasClient.JoinChannel(channel, Program.AutoJoinManager.GetPassword(channel));
  256. var lang = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
  257. if (!string.IsNullOrEmpty(lang)) Program.TasClient.JoinChannel(lang);
  258. }
  259. void TasClient_UserAdded(object sender, EventArgs<User> user)
  260. {
  261. var userName = user.Data.Name;
  262. var pmControl = GetPrivateMessageControl(userName);
  263. if (pmControl != null)
  264. toolTabs.SetIcon(userName, Program.FriendManager.Friends.Contains(userName) ? ZklResources.friend : TextImage.GetUserImage(userName),
  265. true);
  266. }
  267. void TasClient_UserRemoved(object sender, EventArgs<UserDisconnected> e)
  268. {
  269. var userName = e.Data.Name;
  270. var pmControl = GetPrivateMessageControl(userName);
  271. if (pmControl != null) toolTabs.SetIcon(userName, ZklResources.grayuser, true);
  272. }
  273. public string PathHead { get { return "chat"; } }
  274. public bool TryNavigate(params string[] path) //called by NavigationControl.cs when user press Navigation button or the URL button
  275. {
  276. if (path.Length == 0) return false;
  277. if (path[0] != PathHead) return false;
  278. if (path.Length == 2 && !String.IsNullOrEmpty(path[1]))
  279. {
  280. if (path[1] == "battle")
  281. {
  282. toolTabs.SelectChannelTab("Battle");
  283. }
  284. }
  285. if (path.Length == 3 && !String.IsNullOrEmpty(path[1]) && !String.IsNullOrEmpty(path[2]))
  286. {
  287. var type = path[1];
  288. if (type == "user")
  289. {
  290. var userName = path[2];
  291. OpenPrivateMessageChannel(userName);
  292. }
  293. else if (type == "channel")
  294. {
  295. var channelName = path[2];
  296. OpenChannel(channelName);
  297. }
  298. }
  299. return true;
  300. //note: the path is set from ToolTabs.cs (to NavigationControl.cs) which happens when user pressed the channel's name.
  301. }
  302. public bool Hilite(HiliteLevel level, string pathString)
  303. {
  304. var path = pathString.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
  305. if (path.Length == 0) return false;
  306. if (path[0] != PathHead) return false;
  307. if (path.Length >= 2 && path[1] == "battle") return toolTabs.SetHilite("Battle", level, false);
  308. else if (path.Length >= 3)
  309. {
  310. if (path[1] == "channel") return toolTabs.SetHilite(path[2], level, false);
  311. if (path[1] == "user") return toolTabs.SetHilite(path[2], level, true);
  312. }
  313. return false;
  314. }
  315. public string GetTooltip(params string[] path)
  316. {
  317. return null;
  318. }
  319. public void Reload()
  320. {
  321. }
  322. public bool CanReload { get { return false; } }
  323. public bool IsBusy { get { return false; } }
  324. }
  325. }