aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs')
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs1734
1 files changed, 867 insertions, 867 deletions
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs
index 966f5f3..15720fc 100644
--- a/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs
@@ -1,868 +1,868 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Net.Sockets; 31using System.Net.Sockets;
32using System.Reflection; 32using System.Reflection;
33using System.Text.RegularExpressions; 33using System.Text.RegularExpressions;
34using System.Threading; 34using System.Threading;
35using libsecondlife; 35using libsecondlife;
36using log4net; 36using log4net;
37using Nini.Config; 37using Nini.Config;
38using OpenSim.Framework; 38using OpenSim.Framework;
39using OpenSim.Region.Environment.Interfaces; 39using OpenSim.Region.Environment.Interfaces;
40using OpenSim.Region.Environment.Scenes; 40using OpenSim.Region.Environment.Scenes;
41 41
42namespace OpenSim.Region.Environment.Modules.Avatar.Chat 42namespace OpenSim.Region.Environment.Modules.Avatar.Chat
43{ 43{
44 public class ChatModule : IRegionModule, ISimChat 44 public class ChatModule : IRegionModule, ISimChat
45 { 45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 private string m_defaultzone = null; 47 private string m_defaultzone = null;
48 48
49 private IRCChatModule m_irc = null; 49 private IRCChatModule m_irc = null;
50 private Thread m_irc_connector = null; 50 private Thread m_irc_connector = null;
51 51
52 private string m_last_leaving_user = null; 52 private string m_last_leaving_user = null;
53 private string m_last_new_user = null; 53 private string m_last_new_user = null;
54 private int m_saydistance = 30; 54 private int m_saydistance = 30;
55 private List<Scene> m_scenes = new List<Scene>(); 55 private List<Scene> m_scenes = new List<Scene>();
56 private int m_shoutdistance = 100; 56 private int m_shoutdistance = 100;
57 internal object m_syncInit = new object(); 57 internal object m_syncInit = new object();
58 internal object m_syncLogout = new object(); 58 internal object m_syncLogout = new object();
59 private int m_whisperdistance = 10; 59 private int m_whisperdistance = 10;
60 60
61 #region IRegionModule Members 61 #region IRegionModule Members
62 62
63 public void Initialise(Scene scene, IConfigSource config) 63 public void Initialise(Scene scene, IConfigSource config)
64 { 64 {
65 lock (m_syncInit) 65 lock (m_syncInit)
66 { 66 {
67 if (!m_scenes.Contains(scene)) 67 if (!m_scenes.Contains(scene))
68 { 68 {
69 m_scenes.Add(scene); 69 m_scenes.Add(scene);
70 scene.EventManager.OnNewClient += NewClient; 70 scene.EventManager.OnNewClient += NewClient;
71 scene.RegisterModuleInterface<ISimChat>(this); 71 scene.RegisterModuleInterface<ISimChat>(this);
72 } 72 }
73 73
74 // wrap this in a try block so that defaults will work if 74 // wrap this in a try block so that defaults will work if
75 // the config file doesn't specify otherwise. 75 // the config file doesn't specify otherwise.
76 try 76 try
77 { 77 {
78 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); 78 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance);
79 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); 79 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance);
80 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); 80 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance);
81 } 81 }
82 catch (Exception) 82 catch (Exception)
83 { 83 {
84 } 84 }
85 85
86 try 86 try
87 { 87 {
88 m_defaultzone = config.Configs["IRC"].GetString("nick", "Sim"); 88 m_defaultzone = config.Configs["IRC"].GetString("nick", "Sim");
89 } 89 }
90 catch (Exception) 90 catch (Exception)
91 { 91 {
92 } 92 }
93 93
94 // setup IRC Relay 94 // setup IRC Relay
95 if (m_irc == null) 95 if (m_irc == null)
96 { 96 {
97 m_irc = new IRCChatModule(config); 97 m_irc = new IRCChatModule(config);
98 } 98 }
99 if (m_irc_connector == null) 99 if (m_irc_connector == null)
100 { 100 {
101 m_irc_connector = new Thread(IRCConnectRun); 101 m_irc_connector = new Thread(IRCConnectRun);
102 m_irc_connector.Name = "IRCConnectorThread"; 102 m_irc_connector.Name = "IRCConnectorThread";
103 m_irc_connector.IsBackground = true; 103 m_irc_connector.IsBackground = true;
104 } 104 }
105 } 105 }
106 } 106 }
107 107
108 public void PostInitialise() 108 public void PostInitialise()
109 { 109 {
110 if (m_irc.Enabled) 110 if (m_irc.Enabled)
111 { 111 {
112 try 112 try
113 { 113 {
114 //m_irc.Connect(m_scenes); 114 //m_irc.Connect(m_scenes);
115 if (m_irc_connector == null) 115 if (m_irc_connector == null)
116 { 116 {
117 m_irc_connector = new Thread(IRCConnectRun); 117 m_irc_connector = new Thread(IRCConnectRun);
118 m_irc_connector.Name = "IRCConnectorThread"; 118 m_irc_connector.Name = "IRCConnectorThread";
119 m_irc_connector.IsBackground = true; 119 m_irc_connector.IsBackground = true;
120 } 120 }
121 if (!m_irc_connector.IsAlive) 121 if (!m_irc_connector.IsAlive)
122 { 122 {
123 m_irc_connector.Start(); 123 m_irc_connector.Start();
124 ThreadTracker.Add(m_irc_connector); 124 ThreadTracker.Add(m_irc_connector);
125 } 125 }
126 } 126 }
127 catch (Exception) 127 catch (Exception)
128 { 128 {
129 } 129 }
130 } 130 }
131 } 131 }
132 132
133 public void Close() 133 public void Close()
134 { 134 {
135 m_irc.Close(); 135 m_irc.Close();
136 } 136 }
137 137
138 public string Name 138 public string Name
139 { 139 {
140 get { return "ChatModule"; } 140 get { return "ChatModule"; }
141 } 141 }
142 142
143 public bool IsSharedModule 143 public bool IsSharedModule
144 { 144 {
145 get { return true; } 145 get { return true; }
146 } 146 }
147 147
148 #endregion 148 #endregion
149 149
150 #region ISimChat Members 150 #region ISimChat Members
151 151
152 public void SimChat(Object sender, ChatFromViewerArgs e) 152 public void SimChat(Object sender, ChatFromViewerArgs e)
153 { 153 {
154 // FROM: Sim TO: IRC 154 // FROM: Sim TO: IRC
155 155
156 ScenePresence avatar = null; 156 ScenePresence avatar = null;
157 157
158 //TODO: Move ForEachScenePresence and others into IScene. 158 //TODO: Move ForEachScenePresence and others into IScene.
159 Scene scene = (Scene) e.Scene; 159 Scene scene = (Scene) e.Scene;
160 160
161 //TODO: Remove the need for this check 161 //TODO: Remove the need for this check
162 if (scene == null) 162 if (scene == null)
163 scene = m_scenes[0]; 163 scene = m_scenes[0];
164 164
165 // Filled in since it's easier than rewriting right now. 165 // Filled in since it's easier than rewriting right now.
166 LLVector3 fromPos = e.Position; 166 LLVector3 fromPos = e.Position;
167 LLVector3 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 167 LLVector3 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
168 168
169 string fromName = e.From; 169 string fromName = e.From;
170 string message = e.Message; 170 string message = e.Message;
171 LLUUID fromAgentID = LLUUID.Zero; 171 LLUUID fromAgentID = LLUUID.Zero;
172 172
173 if (e.Sender != null) 173 if (e.Sender != null)
174 { 174 {
175 avatar = scene.GetScenePresence(e.Sender.AgentId); 175 avatar = scene.GetScenePresence(e.Sender.AgentId);
176 } 176 }
177 177
178 if (avatar != null) 178 if (avatar != null)
179 { 179 {
180 fromPos = avatar.AbsolutePosition; 180 fromPos = avatar.AbsolutePosition;
181 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 181 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
182 fromName = avatar.Firstname + " " + avatar.Lastname; 182 fromName = avatar.Firstname + " " + avatar.Lastname;
183 fromAgentID = e.Sender.AgentId; 183 fromAgentID = e.Sender.AgentId;
184 } 184 }
185 185
186 // Try to reconnect to server if not connected 186 // Try to reconnect to server if not connected
187 if (m_irc.Enabled && !m_irc.Connected) 187 if (m_irc.Enabled && !m_irc.Connected)
188 { 188 {
189 // In a non-blocking way. Eventually the connector will get it started 189 // In a non-blocking way. Eventually the connector will get it started
190 try 190 try
191 { 191 {
192 if (m_irc_connector == null) 192 if (m_irc_connector == null)
193 { 193 {
194 m_irc_connector = new Thread(IRCConnectRun); 194 m_irc_connector = new Thread(IRCConnectRun);
195 m_irc_connector.Name = "IRCConnectorThread"; 195 m_irc_connector.Name = "IRCConnectorThread";
196 m_irc_connector.IsBackground = true; 196 m_irc_connector.IsBackground = true;
197 } 197 }
198 if (!m_irc_connector.IsAlive) 198 if (!m_irc_connector.IsAlive)
199 { 199 {
200 m_irc_connector.Start(); 200 m_irc_connector.Start();
201 ThreadTracker.Add(m_irc_connector); 201 ThreadTracker.Add(m_irc_connector);
202 } 202 }
203 } 203 }
204 catch (Exception) 204 catch (Exception)
205 { 205 {
206 } 206 }
207 } 207 }
208 208
209 209
210 // We only want to relay stuff on channel 0 210 // We only want to relay stuff on channel 0
211 if (e.Channel == 0) 211 if (e.Channel == 0)
212 { 212 {
213 // IRC stuff 213 // IRC stuff
214 if (e.Message.Length > 0) 214 if (e.Message.Length > 0)
215 { 215 {
216 if (m_irc.Connected && (avatar != null)) // this is to keep objects from talking to IRC 216 if (m_irc.Connected && (avatar != null)) // this is to keep objects from talking to IRC
217 { 217 {
218 m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, e.Message); 218 m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, e.Message);
219 } 219 }
220 } 220 }
221 221
222 foreach (Scene s in m_scenes) 222 foreach (Scene s in m_scenes)
223 { 223 {
224 s.ForEachScenePresence(delegate(ScenePresence presence) 224 s.ForEachScenePresence(delegate(ScenePresence presence)
225 { 225 {
226 TrySendChatMessage(presence, fromPos, regionPos, 226 TrySendChatMessage(presence, fromPos, regionPos,
227 fromAgentID, fromName, e.Type, message); 227 fromAgentID, fromName, e.Type, message);
228 }); 228 });
229 } 229 }
230 } 230 }
231 } 231 }
232 232
233 #endregion 233 #endregion
234 234
235 public void NewClient(IClientAPI client) 235 public void NewClient(IClientAPI client)
236 { 236 {
237 try 237 try
238 { 238 {
239 client.OnChatFromViewer += SimChat; 239 client.OnChatFromViewer += SimChat;
240 240
241 if ((m_irc.Enabled) && (m_irc.Connected)) 241 if ((m_irc.Enabled) && (m_irc.Connected))
242 { 242 {
243 string clientName = client.FirstName + " " + client.LastName; 243 string clientName = client.FirstName + " " + client.LastName;
244 // handles simple case. May not work for hundred connecting in per second. 244 // handles simple case. May not work for hundred connecting in per second.
245 // and the NewClients calles getting interleved 245 // and the NewClients calles getting interleved
246 // but filters out multiple reports 246 // but filters out multiple reports
247 if (clientName != m_last_new_user) 247 if (clientName != m_last_new_user)
248 { 248 {
249 m_last_new_user = clientName; 249 m_last_new_user = clientName;
250 string clientRegion = FindClientRegion(client.FirstName, client.LastName); 250 string clientRegion = FindClientRegion(client.FirstName, client.LastName);
251 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " in " + clientRegion); 251 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " in " + clientRegion);
252 } 252 }
253 } 253 }
254 client.OnLogout += ClientLoggedOut; 254 client.OnLogout += ClientLoggedOut;
255 client.OnConnectionClosed += ClientLoggedOut; 255 client.OnConnectionClosed += ClientLoggedOut;
256 client.OnLogout += ClientLoggedOut; 256 client.OnLogout += ClientLoggedOut;
257 } 257 }
258 catch (Exception ex) 258 catch (Exception ex)
259 { 259 {
260 m_log.Error("[IRC]: NewClient exception trap:" + ex.ToString()); 260 m_log.Error("[IRC]: NewClient exception trap:" + ex.ToString());
261 } 261 }
262 } 262 }
263 263
264 public void ClientLoggedOut(IClientAPI client) 264 public void ClientLoggedOut(IClientAPI client)
265 { 265 {
266 lock (m_syncLogout) 266 lock (m_syncLogout)
267 { 267 {
268 try 268 try
269 { 269 {
270 if ((m_irc.Enabled) && (m_irc.Connected)) 270 if ((m_irc.Enabled) && (m_irc.Connected))
271 { 271 {
272 string clientName = client.FirstName + " " + client.LastName; 272 string clientName = client.FirstName + " " + client.LastName;
273 string clientRegion = FindClientRegion(client.FirstName, client.LastName); 273 string clientRegion = FindClientRegion(client.FirstName, client.LastName);
274 // handles simple case. May not work for hundred connecting in per second. 274 // handles simple case. May not work for hundred connecting in per second.
275 // and the NewClients calles getting interleved 275 // and the NewClients calles getting interleved
276 // but filters out multiple reports 276 // but filters out multiple reports
277 if (clientName != m_last_leaving_user) 277 if (clientName != m_last_leaving_user)
278 { 278 {
279 m_last_leaving_user = clientName; 279 m_last_leaving_user = clientName;
280 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " left " + clientRegion); 280 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " left " + clientRegion);
281 m_log.Info("[IRC]: IRC watcher notices " + clientName + " left " + clientRegion); 281 m_log.Info("[IRC]: IRC watcher notices " + clientName + " left " + clientRegion);
282 } 282 }
283 } 283 }
284 } 284 }
285 catch (Exception ex) 285 catch (Exception ex)
286 { 286 {
287 m_log.Error("[IRC]: ClientLoggedOut exception trap:" + ex.ToString()); 287 m_log.Error("[IRC]: ClientLoggedOut exception trap:" + ex.ToString());
288 } 288 }
289 } 289 }
290 } 290 }
291 291
292 private void TrySendChatMessage(ScenePresence presence, LLVector3 fromPos, LLVector3 regionPos, 292 private void TrySendChatMessage(ScenePresence presence, LLVector3 fromPos, LLVector3 regionPos,
293 LLUUID fromAgentID, string fromName, ChatTypeEnum type, string message) 293 LLUUID fromAgentID, string fromName, ChatTypeEnum type, string message)
294 { 294 {
295 if (!presence.IsChildAgent) 295 if (!presence.IsChildAgent)
296 { 296 {
297 LLVector3 fromRegionPos = fromPos + regionPos; 297 LLVector3 fromRegionPos = fromPos + regionPos;
298 LLVector3 toRegionPos = presence.AbsolutePosition + regionPos; 298 LLVector3 toRegionPos = presence.AbsolutePosition + regionPos;
299 int dis = Math.Abs((int) Util.GetDistanceTo(toRegionPos, fromRegionPos)); 299 int dis = Math.Abs((int) Util.GetDistanceTo(toRegionPos, fromRegionPos));
300 300
301 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || 301 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance ||
302 type == ChatTypeEnum.Say && dis > m_saydistance || 302 type == ChatTypeEnum.Say && dis > m_saydistance ||
303 type == ChatTypeEnum.Shout && dis > m_shoutdistance) 303 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
304 { 304 {
305 return; 305 return;
306 } 306 }
307 307
308 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView 308 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView
309 presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName, fromAgentID); 309 presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName, fromAgentID);
310 } 310 }
311 } 311 }
312 312
313 // if IRC is enabled then just keep trying using a monitor thread 313 // if IRC is enabled then just keep trying using a monitor thread
314 public void IRCConnectRun() 314 public void IRCConnectRun()
315 { 315 {
316 while (true) 316 while (true)
317 { 317 {
318 if ((m_irc.Enabled) && (!m_irc.Connected)) 318 if ((m_irc.Enabled) && (!m_irc.Connected))
319 { 319 {
320 m_irc.Connect(m_scenes); 320 m_irc.Connect(m_scenes);
321 } 321 }
322 Thread.Sleep(15000); 322 Thread.Sleep(15000);
323 } 323 }
324 } 324 }
325 325
326 public string FindClientRegion(string client_FirstName, string client_LastName) 326 public string FindClientRegion(string client_FirstName, string client_LastName)
327 { 327 {
328 string sourceRegion = null; 328 string sourceRegion = null;
329 foreach (Scene s in m_scenes) 329 foreach (Scene s in m_scenes)
330 { 330 {
331 s.ForEachScenePresence(delegate(ScenePresence presence) 331 s.ForEachScenePresence(delegate(ScenePresence presence)
332 { 332 {
333 if ((presence.IsChildAgent == false) 333 if ((presence.IsChildAgent == false)
334 && (presence.Firstname == client_FirstName) 334 && (presence.Firstname == client_FirstName)
335 && (presence.Lastname == client_LastName)) 335 && (presence.Lastname == client_LastName))
336 { 336 {
337 sourceRegion = presence.Scene.RegionInfo.RegionName; 337 sourceRegion = presence.Scene.RegionInfo.RegionName;
338 //sourceRegion= s.RegionInfo.RegionName; 338 //sourceRegion= s.RegionInfo.RegionName;
339 } 339 }
340 }); 340 });
341 if (sourceRegion != null) return sourceRegion; 341 if (sourceRegion != null) return sourceRegion;
342 } 342 }
343 if (m_defaultzone == null) 343 if (m_defaultzone == null)
344 { 344 {
345 m_defaultzone = "Sim"; 345 m_defaultzone = "Sim";
346 } 346 }
347 return m_defaultzone; 347 return m_defaultzone;
348 } 348 }
349 } 349 }
350 350
351 internal class IRCChatModule 351 internal class IRCChatModule
352 { 352 {
353 #region ErrorReplies enum 353 #region ErrorReplies enum
354 354
355 public enum ErrorReplies 355 public enum ErrorReplies
356 { 356 {
357 NotRegistered = 451, // ":You have not registered" 357 NotRegistered = 451, // ":You have not registered"
358 NicknameInUse = 433 // "<nick> :Nickname is already in use" 358 NicknameInUse = 433 // "<nick> :Nickname is already in use"
359 } 359 }
360 360
361 #endregion 361 #endregion
362 362
363 #region Replies enum 363 #region Replies enum
364 364
365 public enum Replies 365 public enum Replies
366 { 366 {
367 MotdStart = 375, // ":- <server> Message of the day - " 367 MotdStart = 375, // ":- <server> Message of the day - "
368 Motd = 372, // ":- <text>" 368 Motd = 372, // ":- <text>"
369 EndOfMotd = 376 // ":End of /MOTD command" 369 EndOfMotd = 376 // ":End of /MOTD command"
370 } 370 }
371 371
372 #endregion 372 #endregion
373 373
374 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 374 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
375 private Thread listener; 375 private Thread listener;
376 376
377 private string m_basenick = null; 377 private string m_basenick = null;
378 private string m_channel = null; 378 private string m_channel = null;
379 private bool m_connected = false; 379 private bool m_connected = false;
380 private bool m_enabled = false; 380 private bool m_enabled = false;
381 private List<Scene> m_last_scenes = null; 381 private List<Scene> m_last_scenes = null;
382 private string m_nick = null; 382 private string m_nick = null;
383 private uint m_port = 6668; 383 private uint m_port = 6668;
384 private string m_privmsgformat = "PRIVMSG {0} :<{1} in {2}>: {3}"; 384 private string m_privmsgformat = "PRIVMSG {0} :<{1} in {2}>: {3}";
385 private StreamReader m_reader; 385 private StreamReader m_reader;
386 private List<Scene> m_scenes = null; 386 private List<Scene> m_scenes = null;
387 private string m_server = null; 387 private string m_server = null;
388 388
389 private NetworkStream m_stream; 389 private NetworkStream m_stream;
390 internal object m_syncConnect = new object(); 390 internal object m_syncConnect = new object();
391 private TcpClient m_tcp; 391 private TcpClient m_tcp;
392 private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot"; 392 private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot";
393 private StreamWriter m_writer; 393 private StreamWriter m_writer;
394 394
395 private Thread pingSender; 395 private Thread pingSender;
396 396
397 public IRCChatModule(IConfigSource config) 397 public IRCChatModule(IConfigSource config)
398 { 398 {
399 m_nick = "OSimBot" + Util.RandomClass.Next(1, 99); 399 m_nick = "OSimBot" + Util.RandomClass.Next(1, 99);
400 m_tcp = null; 400 m_tcp = null;
401 m_writer = null; 401 m_writer = null;
402 m_reader = null; 402 m_reader = null;
403 403
404 // configuration in OpenSim.ini 404 // configuration in OpenSim.ini
405 // [IRC] 405 // [IRC]
406 // server = chat.freenode.net 406 // server = chat.freenode.net
407 // nick = OSimBot_mysim 407 // nick = OSimBot_mysim
408 // ;username = USER OpenSimBot 8 * :I'm a OpenSim to irc bot 408 // ;username = USER OpenSimBot 8 * :I'm a OpenSim to irc bot
409 // ; username is the IRC command line sent 409 // ; username is the IRC command line sent
410 // ; USER <irc_user> <visible=8,invisible=0> * : <IRC_realname> 410 // ; USER <irc_user> <visible=8,invisible=0> * : <IRC_realname>
411 // channel = #opensim-regions 411 // channel = #opensim-regions
412 // port = 6667 412 // port = 6667
413 // ;MSGformat fields : 0=botnick, 1=user, 2=region, 3=message 413 // ;MSGformat fields : 0=botnick, 1=user, 2=region, 3=message
414 // ;for <bot>:<user in region> :<message> 414 // ;for <bot>:<user in region> :<message>
415 // ;msgformat = "PRIVMSG {0} :<{1} in {2}>: {3}" 415 // ;msgformat = "PRIVMSG {0} :<{1} in {2}>: {3}"
416 // ;for <bot>:<message> - <user of region> : 416 // ;for <bot>:<message> - <user of region> :
417 // ;msgformat = "PRIVMSG {0} : {3} - {1} of {2}" 417 // ;msgformat = "PRIVMSG {0} : {3} - {1} of {2}"
418 // ;for <bot>:<message> - from <user> : 418 // ;for <bot>:<message> - from <user> :
419 // ;msgformat = "PRIVMSG {0} : {3} - from {1}" 419 // ;msgformat = "PRIVMSG {0} : {3} - from {1}"
420 // Traps I/O disconnects so it does not crash the sim 420 // Traps I/O disconnects so it does not crash the sim
421 // Trys to reconnect if disconnected and someone says something 421 // Trys to reconnect if disconnected and someone says something
422 // Tells IRC server "QUIT" when doing a close (just to be nice) 422 // Tells IRC server "QUIT" when doing a close (just to be nice)
423 // Default port back to 6667 423 // Default port back to 6667
424 424
425 try 425 try
426 { 426 {
427 m_server = config.Configs["IRC"].GetString("server"); 427 m_server = config.Configs["IRC"].GetString("server");
428 m_nick = config.Configs["IRC"].GetString("nick"); 428 m_nick = config.Configs["IRC"].GetString("nick");
429 m_basenick = m_nick; 429 m_basenick = m_nick;
430 m_channel = config.Configs["IRC"].GetString("channel"); 430 m_channel = config.Configs["IRC"].GetString("channel");
431 m_port = (uint) config.Configs["IRC"].GetInt("port", (int) m_port); 431 m_port = (uint) config.Configs["IRC"].GetInt("port", (int) m_port);
432 m_user = config.Configs["IRC"].GetString("username", m_user); 432 m_user = config.Configs["IRC"].GetString("username", m_user);
433 m_privmsgformat = config.Configs["IRC"].GetString("msgformat", m_privmsgformat); 433 m_privmsgformat = config.Configs["IRC"].GetString("msgformat", m_privmsgformat);
434 if (m_server != null && m_nick != null && m_channel != null) 434 if (m_server != null && m_nick != null && m_channel != null)
435 { 435 {
436 m_nick = m_nick + Util.RandomClass.Next(1, 99); 436 m_nick = m_nick + Util.RandomClass.Next(1, 99);
437 m_enabled = true; 437 m_enabled = true;
438 } 438 }
439 } 439 }
440 catch (Exception) 440 catch (Exception)
441 { 441 {
442 m_log.Info("[CHAT]: No IRC config information, skipping IRC bridge configuration"); 442 m_log.Info("[CHAT]: No IRC config information, skipping IRC bridge configuration");
443 } 443 }
444 } 444 }
445 445
446 public bool Enabled 446 public bool Enabled
447 { 447 {
448 get { return m_enabled; } 448 get { return m_enabled; }
449 } 449 }
450 450
451 public bool Connected 451 public bool Connected
452 { 452 {
453 get { return m_connected; } 453 get { return m_connected; }
454 } 454 }
455 455
456 public string Nick 456 public string Nick
457 { 457 {
458 get { return m_nick; } 458 get { return m_nick; }
459 } 459 }
460 460
461 public bool Connect(List<Scene> scenes) 461 public bool Connect(List<Scene> scenes)
462 { 462 {
463 lock (m_syncConnect) 463 lock (m_syncConnect)
464 { 464 {
465 try 465 try
466 { 466 {
467 if (m_connected) return true; 467 if (m_connected) return true;
468 m_scenes = scenes; 468 m_scenes = scenes;
469 if (m_last_scenes == null) 469 if (m_last_scenes == null)
470 { 470 {
471 m_last_scenes = scenes; 471 m_last_scenes = scenes;
472 } 472 }
473 473
474 m_tcp = new TcpClient(m_server, (int) m_port); 474 m_tcp = new TcpClient(m_server, (int) m_port);
475 m_log.Info("[IRC]: Connecting..."); 475 m_log.Info("[IRC]: Connecting...");
476 m_stream = m_tcp.GetStream(); 476 m_stream = m_tcp.GetStream();
477 m_log.Info("[IRC]: Connected to " + m_server); 477 m_log.Info("[IRC]: Connected to " + m_server);
478 m_reader = new StreamReader(m_stream); 478 m_reader = new StreamReader(m_stream);
479 m_writer = new StreamWriter(m_stream); 479 m_writer = new StreamWriter(m_stream);
480 480
481 pingSender = new Thread(new ThreadStart(PingRun)); 481 pingSender = new Thread(new ThreadStart(PingRun));
482 pingSender.Name = "PingSenderThread"; 482 pingSender.Name = "PingSenderThread";
483 pingSender.IsBackground = true; 483 pingSender.IsBackground = true;
484 pingSender.Start(); 484 pingSender.Start();
485 ThreadTracker.Add(pingSender); 485 ThreadTracker.Add(pingSender);
486 486
487 listener = new Thread(new ThreadStart(ListenerRun)); 487 listener = new Thread(new ThreadStart(ListenerRun));
488 listener.Name = "IRCChatModuleListenerThread"; 488 listener.Name = "IRCChatModuleListenerThread";
489 listener.IsBackground = true; 489 listener.IsBackground = true;
490 listener.Start(); 490 listener.Start();
491 ThreadTracker.Add(listener); 491 ThreadTracker.Add(listener);
492 492
493 m_writer.WriteLine(m_user); 493 m_writer.WriteLine(m_user);
494 m_writer.Flush(); 494 m_writer.Flush();
495 m_writer.WriteLine("NICK " + m_nick); 495 m_writer.WriteLine("NICK " + m_nick);
496 m_writer.Flush(); 496 m_writer.Flush();
497 m_writer.WriteLine("JOIN " + m_channel); 497 m_writer.WriteLine("JOIN " + m_channel);
498 m_writer.Flush(); 498 m_writer.Flush();
499 m_log.Info("[IRC]: Connection fully established"); 499 m_log.Info("[IRC]: Connection fully established");
500 m_connected = true; 500 m_connected = true;
501 } 501 }
502 catch (Exception e) 502 catch (Exception e)
503 { 503 {
504 Console.WriteLine(e.ToString()); 504 Console.WriteLine(e.ToString());
505 } 505 }
506 return m_connected; 506 return m_connected;
507 } 507 }
508 } 508 }
509 509
510 public void Reconnect() 510 public void Reconnect()
511 { 511 {
512 m_connected = false; 512 m_connected = false;
513 listener.Abort(); 513 listener.Abort();
514 pingSender.Abort(); 514 pingSender.Abort();
515 m_writer.Close(); 515 m_writer.Close();
516 m_reader.Close(); 516 m_reader.Close();
517 m_tcp.Close(); 517 m_tcp.Close();
518 if (m_enabled) 518 if (m_enabled)
519 { 519 {
520 Connect(m_last_scenes); 520 Connect(m_last_scenes);
521 } 521 }
522 } 522 }
523 523
524 public void PrivMsg(string from, string region, string msg) 524 public void PrivMsg(string from, string region, string msg)
525 { 525 {
526 // One message to the IRC server 526 // One message to the IRC server
527 527
528 try 528 try
529 { 529 {
530 if (m_privmsgformat == null) 530 if (m_privmsgformat == null)
531 { 531 {
532 m_writer.WriteLine("PRIVMSG {0} :<{1} in {2}>: {3}", m_channel, from, region, msg); 532 m_writer.WriteLine("PRIVMSG {0} :<{1} in {2}>: {3}", m_channel, from, region, msg);
533 } 533 }
534 else 534 else
535 { 535 {
536 m_writer.WriteLine(m_privmsgformat, m_channel, from, region, msg); 536 m_writer.WriteLine(m_privmsgformat, m_channel, from, region, msg);
537 } 537 }
538 m_writer.Flush(); 538 m_writer.Flush();
539 m_log.Info("[IRC]: PrivMsg " + from + " in " + region + " :" + msg); 539 m_log.Info("[IRC]: PrivMsg " + from + " in " + region + " :" + msg);
540 } 540 }
541 catch (IOException) 541 catch (IOException)
542 { 542 {
543 m_log.Error("[IRC]: Disconnected from IRC server.(PrivMsg)"); 543 m_log.Error("[IRC]: Disconnected from IRC server.(PrivMsg)");
544 Reconnect(); 544 Reconnect();
545 } 545 }
546 catch (Exception ex) 546 catch (Exception ex)
547 { 547 {
548 m_log.Error("[IRC]: PrivMsg exception trap:" + ex.ToString()); 548 m_log.Error("[IRC]: PrivMsg exception trap:" + ex.ToString());
549 } 549 }
550 } 550 }
551 551
552 private Dictionary<string, string> ExtractMsg(string input) 552 private Dictionary<string, string> ExtractMsg(string input)
553 { 553 {
554 //examines IRC commands and extracts any private messages 554 //examines IRC commands and extracts any private messages
555 // which will then be reboadcast in the Sim 555 // which will then be reboadcast in the Sim
556 556
557 m_log.Info("[IRC]: ExtractMsg: " + input); 557 m_log.Info("[IRC]: ExtractMsg: " + input);
558 Dictionary<string, string> result = null; 558 Dictionary<string, string> result = null;
559 //string regex = @":(?<nick>\w*)!~(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)"; 559 //string regex = @":(?<nick>\w*)!~(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)";
560 string regex = @":(?<nick>\w*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)"; 560 string regex = @":(?<nick>\w*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)";
561 Regex RE = new Regex(regex, RegexOptions.Multiline); 561 Regex RE = new Regex(regex, RegexOptions.Multiline);
562 MatchCollection matches = RE.Matches(input); 562 MatchCollection matches = RE.Matches(input);
563 // Get some direct matches $1 $4 is a 563 // Get some direct matches $1 $4 is a
564 if ((matches.Count == 1) && (matches[0].Groups.Count == 5)) 564 if ((matches.Count == 1) && (matches[0].Groups.Count == 5))
565 { 565 {
566 result = new Dictionary<string, string>(); 566 result = new Dictionary<string, string>();
567 result.Add("nick", matches[0].Groups[1].Value); 567 result.Add("nick", matches[0].Groups[1].Value);
568 result.Add("user", matches[0].Groups[2].Value); 568 result.Add("user", matches[0].Groups[2].Value);
569 result.Add("channel", matches[0].Groups[3].Value); 569 result.Add("channel", matches[0].Groups[3].Value);
570 result.Add("msg", matches[0].Groups[4].Value); 570 result.Add("msg", matches[0].Groups[4].Value);
571 } 571 }
572 else 572 else
573 { 573 {
574 m_log.Info("[IRC]: Number of matches: " + matches.Count); 574 m_log.Info("[IRC]: Number of matches: " + matches.Count);
575 if (matches.Count > 0) 575 if (matches.Count > 0)
576 { 576 {
577 m_log.Info("[IRC]: Number of groups: " + matches[0].Groups.Count); 577 m_log.Info("[IRC]: Number of groups: " + matches[0].Groups.Count);
578 } 578 }
579 } 579 }
580 return result; 580 return result;
581 } 581 }
582 582
583 public void PingRun() 583 public void PingRun()
584 { 584 {
585 // IRC keep alive thread 585 // IRC keep alive thread
586 // send PING ever 15 seconds 586 // send PING ever 15 seconds
587 while (true) 587 while (true)
588 { 588 {
589 try 589 try
590 { 590 {
591 if (m_connected == true) 591 if (m_connected == true)
592 { 592 {
593 m_writer.WriteLine("PING :" + m_server); 593 m_writer.WriteLine("PING :" + m_server);
594 m_writer.Flush(); 594 m_writer.Flush();
595 Thread.Sleep(15000); 595 Thread.Sleep(15000);
596 } 596 }
597 } 597 }
598 catch (IOException) 598 catch (IOException)
599 { 599 {
600 m_log.Error("[IRC]: Disconnected from IRC server.(PingRun)"); 600 m_log.Error("[IRC]: Disconnected from IRC server.(PingRun)");
601 Reconnect(); 601 Reconnect();
602 } 602 }
603 catch (Exception ex) 603 catch (Exception ex)
604 { 604 {
605 m_log.Error("[IRC]: PingRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace); 605 m_log.Error("[IRC]: PingRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace);
606 } 606 }
607 } 607 }
608 } 608 }
609 609
610 public void ListenerRun() 610 public void ListenerRun()
611 { 611 {
612 string inputLine; 612 string inputLine;
613 LLVector3 pos = new LLVector3(128, 128, 20); 613 LLVector3 pos = new LLVector3(128, 128, 20);
614 while (true) 614 while (true)
615 { 615 {
616 try 616 try
617 { 617 {
618 while ((m_connected == true) && ((inputLine = m_reader.ReadLine()) != null)) 618 while ((m_connected == true) && ((inputLine = m_reader.ReadLine()) != null))
619 { 619 {
620 // Console.WriteLine(inputLine); 620 // Console.WriteLine(inputLine);
621 if (inputLine.Contains(m_channel)) 621 if (inputLine.Contains(m_channel))
622 { 622 {
623 Dictionary<string, string> data = ExtractMsg(inputLine); 623 Dictionary<string, string> data = ExtractMsg(inputLine);
624 // Any chat ??? 624 // Any chat ???
625 if (data != null) 625 if (data != null)
626 { 626 {
627 foreach (Scene m_scene in m_scenes) 627 foreach (Scene m_scene in m_scenes)
628 { 628 {
629 m_scene.ForEachScenePresence(delegate(ScenePresence avatar) 629 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
630 { 630 {
631 if (!avatar.IsChildAgent) 631 if (!avatar.IsChildAgent)
632 { 632 {
633 avatar.ControllingClient.SendChatMessage( 633 avatar.ControllingClient.SendChatMessage(
634 Helpers.StringToField(data["msg"]), 255, 634 Helpers.StringToField(data["msg"]), 255,
635 pos, data["nick"], 635 pos, data["nick"],
636 LLUUID.Zero); 636 LLUUID.Zero);
637 } 637 }
638 }); 638 });
639 } 639 }
640 } 640 }
641 else 641 else
642 { 642 {
643 // Was an command from the IRC server 643 // Was an command from the IRC server
644 ProcessIRCCommand(inputLine); 644 ProcessIRCCommand(inputLine);
645 } 645 }
646 } 646 }
647 else 647 else
648 { 648 {
649 // Was an command from the IRC server 649 // Was an command from the IRC server
650 ProcessIRCCommand(inputLine); 650 ProcessIRCCommand(inputLine);
651 } 651 }
652 Thread.Sleep(150); 652 Thread.Sleep(150);
653 } 653 }
654 } 654 }
655 catch (IOException) 655 catch (IOException)
656 { 656 {
657 m_log.Error("[IRC]: ListenerRun IOException. Disconnected from IRC server ??? (ListenerRun)"); 657 m_log.Error("[IRC]: ListenerRun IOException. Disconnected from IRC server ??? (ListenerRun)");
658 Reconnect(); 658 Reconnect();
659 } 659 }
660 catch (Exception ex) 660 catch (Exception ex)
661 { 661 {
662 m_log.Error("[IRC]: ListenerRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace); 662 m_log.Error("[IRC]: ListenerRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace);
663 } 663 }
664 } 664 }
665 } 665 }
666 666
667 public void BroadcastSim(string message, string sender) 667 public void BroadcastSim(string message, string sender)
668 { 668 {
669 LLVector3 pos = new LLVector3(128, 128, 20); 669 LLVector3 pos = new LLVector3(128, 128, 20);
670 try 670 try
671 { 671 {
672 foreach (Scene m_scene in m_scenes) 672 foreach (Scene m_scene in m_scenes)
673 { 673 {
674 m_scene.ForEachScenePresence(delegate(ScenePresence avatar) 674 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
675 { 675 {
676 if (!avatar.IsChildAgent) 676 if (!avatar.IsChildAgent)
677 { 677 {
678 avatar.ControllingClient.SendChatMessage( 678 avatar.ControllingClient.SendChatMessage(
679 Helpers.StringToField(message), 255, 679 Helpers.StringToField(message), 255,
680 pos, sender, 680 pos, sender,
681 LLUUID.Zero); 681 LLUUID.Zero);
682 } 682 }
683 }); 683 });
684 } 684 }
685 } 685 }
686 catch (Exception ex) // IRC gate should not crash Sim 686 catch (Exception ex) // IRC gate should not crash Sim
687 { 687 {
688 m_log.Error("[IRC]: BroadcastSim Exception Trap:" + ex.ToString() + "\n" + ex.StackTrace); 688 m_log.Error("[IRC]: BroadcastSim Exception Trap:" + ex.ToString() + "\n" + ex.StackTrace);
689 } 689 }
690 } 690 }
691 691
692 public void ProcessIRCCommand(string command) 692 public void ProcessIRCCommand(string command)
693 { 693 {
694 //m_log.Info("[IRC]: ProcessIRCCommand:" + command); 694 //m_log.Info("[IRC]: ProcessIRCCommand:" + command);
695 695
696 string[] commArgs = new string[command.Split(' ').Length]; 696 string[] commArgs = new string[command.Split(' ').Length];
697 string c_server = m_server; 697 string c_server = m_server;
698 698
699 commArgs = command.Split(' '); 699 commArgs = command.Split(' ');
700 if (commArgs[0].Substring(0, 1) == ":") 700 if (commArgs[0].Substring(0, 1) == ":")
701 { 701 {
702 commArgs[0] = commArgs[0].Remove(0, 1); 702 commArgs[0] = commArgs[0].Remove(0, 1);
703 } 703 }
704 704
705 if (commArgs[1] == "002") 705 if (commArgs[1] == "002")
706 { 706 {
707 // fetch the correct servername 707 // fetch the correct servername
708 // ex: irc.freenode.net -> brown.freenode.net/kornbluth.freenode.net/... 708 // ex: irc.freenode.net -> brown.freenode.net/kornbluth.freenode.net/...
709 // irc.bluewin.ch -> irc1.bluewin.ch/irc2.bluewin.ch 709 // irc.bluewin.ch -> irc1.bluewin.ch/irc2.bluewin.ch
710 710
711 c_server = (commArgs[6].Split('['))[0]; 711 c_server = (commArgs[6].Split('['))[0];
712 m_server = c_server; 712 m_server = c_server;
713 } 713 }
714 714
715 if (commArgs[0] == "ERROR") 715 if (commArgs[0] == "ERROR")
716 { 716 {
717 m_log.Error("[IRC]: IRC SERVER ERROR:" + command); 717 m_log.Error("[IRC]: IRC SERVER ERROR:" + command);
718 } 718 }
719 719
720 if (commArgs[0] == "PING") 720 if (commArgs[0] == "PING")
721 { 721 {
722 string p_reply = ""; 722 string p_reply = "";
723 723
724 for (int i = 1; i < commArgs.Length; i++) 724 for (int i = 1; i < commArgs.Length; i++)
725 { 725 {
726 p_reply += commArgs[i] + " "; 726 p_reply += commArgs[i] + " ";
727 } 727 }
728 728
729 m_writer.WriteLine("PONG " + p_reply); 729 m_writer.WriteLine("PONG " + p_reply);
730 m_writer.Flush(); 730 m_writer.Flush();
731 } 731 }
732 else if (commArgs[0] == c_server) 732 else if (commArgs[0] == c_server)
733 { 733 {
734 // server message 734 // server message
735 try 735 try
736 { 736 {
737 Int32 commandCode = Int32.Parse(commArgs[1]); 737 Int32 commandCode = Int32.Parse(commArgs[1]);
738 switch (commandCode) 738 switch (commandCode)
739 { 739 {
740 case (int) ErrorReplies.NicknameInUse: 740 case (int) ErrorReplies.NicknameInUse:
741 // Gen a new name 741 // Gen a new name
742 m_nick = m_basenick + Util.RandomClass.Next(1, 99); 742 m_nick = m_basenick + Util.RandomClass.Next(1, 99);
743 m_log.Error("[IRC]: IRC SERVER reports NicknameInUse, trying " + m_nick); 743 m_log.Error("[IRC]: IRC SERVER reports NicknameInUse, trying " + m_nick);
744 // Retry 744 // Retry
745 m_writer.WriteLine("NICK " + m_nick); 745 m_writer.WriteLine("NICK " + m_nick);
746 m_writer.Flush(); 746 m_writer.Flush();
747 m_writer.WriteLine("JOIN " + m_channel); 747 m_writer.WriteLine("JOIN " + m_channel);
748 m_writer.Flush(); 748 m_writer.Flush();
749 break; 749 break;
750 case (int) ErrorReplies.NotRegistered: 750 case (int) ErrorReplies.NotRegistered:
751 break; 751 break;
752 case (int) Replies.EndOfMotd: 752 case (int) Replies.EndOfMotd:
753 break; 753 break;
754 } 754 }
755 } 755 }
756 catch (Exception) 756 catch (Exception)
757 { 757 {
758 } 758 }
759 } 759 }
760 else 760 else
761 { 761 {
762 // Normal message 762 // Normal message
763 string commAct = commArgs[1]; 763 string commAct = commArgs[1];
764 switch (commAct) 764 switch (commAct)
765 { 765 {
766 case "JOIN": 766 case "JOIN":
767 eventIrcJoin(commArgs); 767 eventIrcJoin(commArgs);
768 break; 768 break;
769 case "PART": 769 case "PART":
770 eventIrcPart(commArgs); 770 eventIrcPart(commArgs);
771 break; 771 break;
772 case "MODE": 772 case "MODE":
773 eventIrcMode(commArgs); 773 eventIrcMode(commArgs);
774 break; 774 break;
775 case "NICK": 775 case "NICK":
776 eventIrcNickChange(commArgs); 776 eventIrcNickChange(commArgs);
777 break; 777 break;
778 case "KICK": 778 case "KICK":
779 eventIrcKick(commArgs); 779 eventIrcKick(commArgs);
780 break; 780 break;
781 case "QUIT": 781 case "QUIT":
782 eventIrcQuit(commArgs); 782 eventIrcQuit(commArgs);
783 break; 783 break;
784 case "PONG": 784 case "PONG":
785 break; // that's nice 785 break; // that's nice
786 } 786 }
787 } 787 }
788 } 788 }
789 789
790 public void eventIrcJoin(string[] commArgs) 790 public void eventIrcJoin(string[] commArgs)
791 { 791 {
792 string IrcChannel = commArgs[2]; 792 string IrcChannel = commArgs[2];
793 string IrcUser = commArgs[0].Split('!')[0]; 793 string IrcUser = commArgs[0].Split('!')[0];
794 BroadcastSim(IrcUser + " is joining " + IrcChannel, m_nick); 794 BroadcastSim(IrcUser + " is joining " + IrcChannel, m_nick);
795 } 795 }
796 796
797 public void eventIrcPart(string[] commArgs) 797 public void eventIrcPart(string[] commArgs)
798 { 798 {
799 string IrcChannel = commArgs[2]; 799 string IrcChannel = commArgs[2];
800 string IrcUser = commArgs[0].Split('!')[0]; 800 string IrcUser = commArgs[0].Split('!')[0];
801 BroadcastSim(IrcUser + " is parting " + IrcChannel, m_nick); 801 BroadcastSim(IrcUser + " is parting " + IrcChannel, m_nick);
802 } 802 }
803 803
804 public void eventIrcMode(string[] commArgs) 804 public void eventIrcMode(string[] commArgs)
805 { 805 {
806 string IrcChannel = commArgs[2]; 806 string IrcChannel = commArgs[2];
807 string IrcUser = commArgs[0].Split('!')[0]; 807 string IrcUser = commArgs[0].Split('!')[0];
808 string UserMode = ""; 808 string UserMode = "";
809 for (int i = 3; i < commArgs.Length; i++) 809 for (int i = 3; i < commArgs.Length; i++)
810 { 810 {
811 UserMode += commArgs[i] + " "; 811 UserMode += commArgs[i] + " ";
812 } 812 }
813 813
814 if (UserMode.Substring(0, 1) == ":") 814 if (UserMode.Substring(0, 1) == ":")
815 { 815 {
816 UserMode = UserMode.Remove(0, 1); 816 UserMode = UserMode.Remove(0, 1);
817 } 817 }
818 } 818 }
819 819
820 public void eventIrcNickChange(string[] commArgs) 820 public void eventIrcNickChange(string[] commArgs)
821 { 821 {
822 string UserOldNick = commArgs[0].Split('!')[0]; 822 string UserOldNick = commArgs[0].Split('!')[0];
823 string UserNewNick = commArgs[2].Remove(0, 1); 823 string UserNewNick = commArgs[2].Remove(0, 1);
824 BroadcastSim(UserOldNick + " changed their nick to " + UserNewNick, m_nick); 824 BroadcastSim(UserOldNick + " changed their nick to " + UserNewNick, m_nick);
825 } 825 }
826 826
827 public void eventIrcKick(string[] commArgs) 827 public void eventIrcKick(string[] commArgs)
828 { 828 {
829 string UserKicker = commArgs[0].Split('!')[0]; 829 string UserKicker = commArgs[0].Split('!')[0];
830 string UserKicked = commArgs[3]; 830 string UserKicked = commArgs[3];
831 string IrcChannel = commArgs[2]; 831 string IrcChannel = commArgs[2];
832 string KickMessage = ""; 832 string KickMessage = "";
833 for (int i = 4; i < commArgs.Length; i++) 833 for (int i = 4; i < commArgs.Length; i++)
834 { 834 {
835 KickMessage += commArgs[i] + " "; 835 KickMessage += commArgs[i] + " ";
836 } 836 }
837 BroadcastSim(UserKicker + " kicked " + UserKicked + " on " + IrcChannel + " saying " + KickMessage, m_nick); 837 BroadcastSim(UserKicker + " kicked " + UserKicked + " on " + IrcChannel + " saying " + KickMessage, m_nick);
838 if (UserKicked == m_nick) 838 if (UserKicked == m_nick)
839 { 839 {
840 BroadcastSim("Hey, that was me!!!", m_nick); 840 BroadcastSim("Hey, that was me!!!", m_nick);
841 } 841 }
842 } 842 }
843 843
844 public void eventIrcQuit(string[] commArgs) 844 public void eventIrcQuit(string[] commArgs)
845 { 845 {
846 string IrcUser = commArgs[0].Split('!')[0]; 846 string IrcUser = commArgs[0].Split('!')[0];
847 string QuitMessage = ""; 847 string QuitMessage = "";
848 848
849 for (int i = 2; i < commArgs.Length; i++) 849 for (int i = 2; i < commArgs.Length; i++)
850 { 850 {
851 QuitMessage += commArgs[i] + " "; 851 QuitMessage += commArgs[i] + " ";
852 } 852 }
853 BroadcastSim(IrcUser + " quits saying " + QuitMessage, m_nick); 853 BroadcastSim(IrcUser + " quits saying " + QuitMessage, m_nick);
854 } 854 }
855 855
856 public void Close() 856 public void Close()
857 { 857 {
858 m_connected = false; 858 m_connected = false;
859 m_writer.WriteLine("QUIT :" + m_nick + " to " + m_channel + " wormhole with " + m_server + " closing"); 859 m_writer.WriteLine("QUIT :" + m_nick + " to " + m_channel + " wormhole with " + m_server + " closing");
860 m_writer.Flush(); 860 m_writer.Flush();
861 listener.Abort(); 861 listener.Abort();
862 pingSender.Abort(); 862 pingSender.Abort();
863 m_writer.Close(); 863 m_writer.Close();
864 m_reader.Close(); 864 m_reader.Close();
865 m_tcp.Close(); 865 m_tcp.Close();
866 } 866 }
867 } 867 }
868} \ No newline at end of file 868} \ No newline at end of file