2 // Radegast Metaverse Client
3 // Copyright (c) 2009-2013, Radegast Development Team
4 // All rights reserved.
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
9 // * Redistributions of source code must retain the above copyright notice,
10 // this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 // * Neither the name of the application "Radegast", nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 using System.Collections.Generic;
33 using System.ComponentModel;
38 using System.Text.RegularExpressions;
39 using System.Windows.Forms;
40 using System.Threading;
43 using Meebey.SmartIrc4net;
45 namespace Radegast.Plugin.IRC
47 public partial class RelayConsole : RadegastTabControl
51 TabsConsole TC { get { return instance.TabConsole; } }
52 RichTextBoxPrinter textPrinter;
53 private List<string> chatHistory = new List<string>();
54 private int chatPointer;
55 bool connecting = false;
58 public RelayConsole(RadegastInstance instance)
61 InitializeComponent();
62 Disposed += new EventHandler(RelayConsole_Disposed);
63 textPrinter = new RichTextBoxPrinter(rtbChatText);
65 irc = new IrcClient();
67 irc.AutoReconnect = true;
68 irc.CtcpVersion = Properties.Resources.RadegastTitle;
69 irc.Encoding = Encoding.UTF8;
71 TC.OnTabAdded += new TabsConsole.TabCallback(TC_OnTabAdded);
72 TC.OnTabRemoved += new TabsConsole.TabCallback(TC_OnTabRemoved);
73 irc.OnError += new ErrorEventHandler(irc_OnError);
74 irc.OnRawMessage += new IrcEventHandler(irc_OnRawMessage);
75 irc.OnChannelMessage += new IrcEventHandler(irc_OnChannelMessage);
76 irc.OnConnected += new EventHandler(irc_OnConnected);
77 irc.OnDisconnected += new EventHandler(irc_OnDisconnected);
79 client.Self.IM += new EventHandler<InstantMessageEventArgs>(Self_IM);
84 void RelayConsole_Disposed(object sender, EventArgs e)
86 client.Self.IM -= new EventHandler<InstantMessageEventArgs>(Self_IM);
88 TC.OnTabAdded -= new TabsConsole.TabCallback(TC_OnTabAdded);
89 TC.OnTabRemoved -= new TabsConsole.TabCallback(TC_OnTabRemoved);
91 irc.OnError -= new ErrorEventHandler(irc_OnError);
92 irc.OnRawMessage -= new IrcEventHandler(irc_OnRawMessage);
93 irc.OnChannelMessage -= new IrcEventHandler(irc_OnChannelMessage);
94 irc.OnConnected -= new EventHandler(irc_OnConnected);
95 irc.OnDisconnected -= new EventHandler(irc_OnDisconnected);
99 irc.AutoReconnect = false;
104 void TC_OnTabRemoved(object sender, TabEventArgs e)
109 void TC_OnTabAdded(object sender, TabEventArgs e)
111 if (e.Tab.Control is GroupIMTabWindow)
120 BeginInvoke(new MethodInvoker(() => RefreshGroups()));
124 ddGroup.DropDownItems.Clear();
126 bool foundActive = false;
128 foreach (var tab in TC.Tabs)
130 if (!(tab.Value.Control is GroupIMTabWindow)) continue;
132 UUID session = new UUID(tab.Key);
133 if (session == relayGroup)
136 ToolStripButton item = new ToolStripButton(instance.Groups[session].Name, null, groupSelect, session.ToString());
137 ddGroup.DropDownItems.Add(item);
142 relayGroup = UUID.Zero;
143 ddGroup.Text = "Groups (none)";
148 void groupSelect(object sender, EventArgs e)
150 if (sender is ToolStripButton)
152 UUID session = new UUID(((ToolStripButton)sender).Name);
153 relayGroup = session;
154 ddGroup.Text = string.Format("Groups ({0})", instance.Groups[session].Name);
158 private void PrintMsg(string fromName, string message)
163 BeginInvoke(new MethodInvoker(() => PrintMsg(fromName, message)));
167 DateTime timestamp = DateTime.Now;
170 message = string.Empty;
174 textPrinter.ForeColor = Color.Gray;
175 textPrinter.PrintText(timestamp.ToString("[HH:mm] "));
178 textPrinter.ForeColor = Color.Black;
180 StringBuilder sb = new StringBuilder();
182 if (message.StartsWith("/me "))
185 sb.Append(message.Substring(3));
194 //instance.LogClientMessage(sessionName + ".txt", sb.ToString());
195 textPrinter.PrintTextLine(sb.ToString());
199 private void btnConnectPannel_Click(object sender, EventArgs e)
201 pnlConnectionSettings.Visible = true;
204 private void IrcThread(object param)
206 object[] args = (object[])param;
207 string server = (string)args[0];
208 int port = (int)args[1];
209 string nick = (string)args[2];
210 string chan = (string)args[3];
213 PrintMsg("System", "Connecting...");
217 irc.Connect(server, port);
218 PrintMsg("System", "Logging in...");
219 irc.Login(nick, "Radegast SL Relay", 0, nick);
225 PrintMsg("System", "An error has occured: " + ex.Message);
233 irc.AutoReconnect = false;
240 private void btnConnect_Click(object sender, EventArgs e)
244 PrintMsg("System", "Already connecting");
250 PrintMsg("System", "Already connected");
255 Thread IRCConnection = new Thread(new ParameterizedThreadStart(IrcThread));
256 IRCConnection.Name = "IRC Thread";
257 IRCConnection.IsBackground = true;
259 int.TryParse(txtPort.Text, out port);
260 IRCConnection.Start(new object[] { txtServer.Text, port, txtNick.Text, txtChan.Text });
263 void irc_OnRawMessage(object sender, IrcEventArgs e)
265 if (e.Data.Type == ReceiveType.Unknown || e.Data.Type == ReceiveType.ChannelMessage) return;
266 PrintMsg(e.Data.Nick, e.Data.Type + ": " + e.Data.Message);
269 void irc_OnError(object sender, ErrorEventArgs e)
271 PrintMsg("Error", e.ErrorMessage);
274 void irc_OnDisconnected(object sender, EventArgs e)
279 Invoke(new MethodInvoker(() => irc_OnDisconnected(sender, e)));
283 lblConnected.Text = "not connected";
284 btnSend.Enabled = false;
287 void irc_OnConnected(object sender, EventArgs e)
292 Invoke(new MethodInvoker(() => irc_OnConnected(sender, e)));
295 lblConnected.Text = "connected";
296 pnlConnectionSettings.Visible = false;
297 btnSend.Enabled = true;
300 void irc_OnChannelMessage(object sender, IrcEventArgs e)
302 ThreadPool.QueueUserWorkItem(sync =>
304 PrintMsg(e.Data.Nick, e.Data.Message);
305 if (relayGroup != UUID.Zero)
307 client.Self.InstantMessageGroup(relayGroup, string.Format("(irc:{2}) {0}: {1}", e.Data.Nick, e.Data.Message, e.Data.Channel));
313 void Self_IM(object sender, InstantMessageEventArgs e)
315 if (e.IM.IMSessionID == relayGroup && irc.IsConnected && e.IM.FromAgentID != client.Self.AgentID)
317 string[] lines = Regex.Split(e.IM.Message, "\n+");
319 for (int l = 0; l < lines.Length; l++)
322 string[] words = lines[l].Split(' ');
323 string outstr = string.Empty;
325 for (int i = 0; i < words.Length; i++)
327 outstr += words[i] + " ";
328 if (outstr.Length > 380)
330 PrintMsg(irc.Nickname, string.Format("{0}: {1}", e.IM.FromAgentName, outstr.Remove(outstr.Length - 1)));
331 irc.SendMessage(SendType.Message, txtChan.Text, string.Format("{0}: {1}", e.IM.FromAgentName, outstr.Remove(outstr.Length - 1)));
332 outstr = string.Empty;
335 PrintMsg(irc.Nickname, string.Format("{0}: {1}", e.IM.FromAgentName, outstr.Remove(outstr.Length - 1)));
336 irc.SendMessage(SendType.Message, txtChan.Text, string.Format("{0}: {1}", e.IM.FromAgentName, outstr.Remove(outstr.Length - 1)));
341 private void btnDisconnect_Click(object sender, EventArgs e)
345 irc.AutoReconnect = false;
352 string msg = cbxInput.Text;
353 if (msg == string.Empty) return;
355 chatHistory.Add(cbxInput.Text);
356 chatPointer = chatHistory.Count;
358 cbxInput.Text = string.Empty;
361 PrintMsg(irc.Nickname, msg);
362 irc.SendMessage(SendType.Message, txtChan.Text, msg);
366 void ChatHistoryPrev()
368 if (chatPointer == 0) return;
370 if (chatHistory.Count > chatPointer)
372 cbxInput.Text = chatHistory[chatPointer];
373 cbxInput.SelectionStart = cbxInput.Text.Length;
374 cbxInput.SelectionLength = 0;
378 void ChatHistoryNext()
380 if (chatPointer == chatHistory.Count) return;
382 if (chatPointer == chatHistory.Count)
384 cbxInput.Text = string.Empty;
387 cbxInput.Text = chatHistory[chatPointer];
388 cbxInput.SelectionStart = cbxInput.Text.Length;
389 cbxInput.SelectionLength = 0;
392 private void cbxInput_KeyDown(object sender, KeyEventArgs e)
394 if (e.KeyCode == Keys.Up && e.Modifiers == Keys.Control)
396 e.Handled = e.SuppressKeyPress = true;
401 if (e.KeyCode == Keys.Down && e.Modifiers == Keys.Control)
403 e.Handled = e.SuppressKeyPress = true;
408 if (e.KeyCode == Keys.Enter)
410 e.Handled = e.SuppressKeyPress = true;
415 private void btnSend_Click(object sender, EventArgs e)