aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs
diff options
context:
space:
mode:
authorAdam Frisby2008-04-30 21:16:36 +0000
committerAdam Frisby2008-04-30 21:16:36 +0000
commitf5c312bc3c2567449c7268a54a08a54119f58d53 (patch)
tree424668a4bbec6873ebc5b8256f3671db102f5e9c /OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs
parent* Adds the AuthbuyerID field to sqlite and makes use of it. (diff)
downloadopensim-SC_OLD-f5c312bc3c2567449c7268a54a08a54119f58d53.zip
opensim-SC_OLD-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.gz
opensim-SC_OLD-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.bz2
opensim-SC_OLD-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.xz
* Refactored Environment/Modules directory - modules now reside in their own directory with any associated module-specific classes.
* Each module directory is currently inside one of the following category folders: Agent (Anything relating to do with Client<->Server communications.), Avatar (Anything to do with the avatar or presence inworld), Framework (Classes modules can use), Grid (Grid traffic, new OGS2 grid comms), Scripting (Scripting functions, etc), World (The enrivonment/scene, IE Sun/Tree modules.) * This should be moved into a seperate project file.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs (renamed from OpenSim/Region/Environment/Modules/ChatModule.cs)1662
1 files changed, 831 insertions, 831 deletions
diff --git a/OpenSim/Region/Environment/Modules/ChatModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs
index 30c1397..1281873 100644
--- a/OpenSim/Region/Environment/Modules/ChatModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs
@@ -1,831 +1,831 @@
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 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 47
48 private List<Scene> m_scenes = new List<Scene>(); 48 private List<Scene> m_scenes = new List<Scene>();
49 49
50 private int m_whisperdistance = 10; 50 private int m_whisperdistance = 10;
51 private int m_saydistance = 30; 51 private int m_saydistance = 30;
52 private int m_shoutdistance = 100; 52 private int m_shoutdistance = 100;
53 53
54 private IRCChatModule m_irc = null; 54 private IRCChatModule m_irc = null;
55 55
56 private string m_last_new_user = null; 56 private string m_last_new_user = null;
57 private string m_last_leaving_user = null; 57 private string m_last_leaving_user = null;
58 private string m_defaultzone = null; 58 private string m_defaultzone = null;
59 internal object m_syncInit = new object(); 59 internal object m_syncInit = new object();
60 internal object m_syncLogout = new object(); 60 internal object m_syncLogout = new object();
61 private Thread m_irc_connector=null; 61 private Thread m_irc_connector=null;
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) { m_irc = new IRCChatModule(config); } 95 if (m_irc == null) { m_irc = new IRCChatModule(config); }
96 if (m_irc_connector == null) 96 if (m_irc_connector == null)
97 { 97 {
98 m_irc_connector = new Thread(IRCConnectRun); 98 m_irc_connector = new Thread(IRCConnectRun);
99 m_irc_connector.Name = "IRCConnectorThread"; 99 m_irc_connector.Name = "IRCConnectorThread";
100 m_irc_connector.IsBackground = true; 100 m_irc_connector.IsBackground = true;
101 } 101 }
102 } 102 }
103 } 103 }
104 104
105 public void PostInitialise() 105 public void PostInitialise()
106 { 106 {
107 if (m_irc.Enabled) 107 if (m_irc.Enabled)
108 { 108 {
109 try 109 try
110 { 110 {
111 //m_irc.Connect(m_scenes); 111 //m_irc.Connect(m_scenes);
112 if (m_irc_connector == null) 112 if (m_irc_connector == null)
113 { 113 {
114 m_irc_connector = new Thread(IRCConnectRun); 114 m_irc_connector = new Thread(IRCConnectRun);
115 m_irc_connector.Name = "IRCConnectorThread"; 115 m_irc_connector.Name = "IRCConnectorThread";
116 m_irc_connector.IsBackground = true; 116 m_irc_connector.IsBackground = true;
117 } 117 }
118 if (!m_irc_connector.IsAlive) 118 if (!m_irc_connector.IsAlive)
119 { 119 {
120 m_irc_connector.Start(); 120 m_irc_connector.Start();
121 ThreadTracker.Add(m_irc_connector); 121 ThreadTracker.Add(m_irc_connector);
122 } 122 }
123 } 123 }
124 catch (Exception) 124 catch (Exception)
125 { 125 {
126 } 126 }
127 } 127 }
128 } 128 }
129 129
130 public void Close() 130 public void Close()
131 { 131 {
132 m_irc.Close(); 132 m_irc.Close();
133 } 133 }
134 134
135 public string Name 135 public string Name
136 { 136 {
137 get { return "ChatModule"; } 137 get { return "ChatModule"; }
138 } 138 }
139 139
140 public bool IsSharedModule 140 public bool IsSharedModule
141 { 141 {
142 get { return true; } 142 get { return true; }
143 } 143 }
144 144
145 public void NewClient(IClientAPI client) 145 public void NewClient(IClientAPI client)
146 { 146 {
147 try 147 try
148 { 148 {
149 client.OnChatFromViewer += SimChat; 149 client.OnChatFromViewer += SimChat;
150 150
151 if ((m_irc.Enabled) && (m_irc.Connected)) 151 if ((m_irc.Enabled) && (m_irc.Connected))
152 { 152 {
153 string clientName = client.FirstName + " " + client.LastName; 153 string clientName = client.FirstName + " " + client.LastName;
154 // handles simple case. May not work for hundred connecting in per second. 154 // handles simple case. May not work for hundred connecting in per second.
155 // and the NewClients calles getting interleved 155 // and the NewClients calles getting interleved
156 // but filters out multiple reports 156 // but filters out multiple reports
157 if (clientName != m_last_new_user) 157 if (clientName != m_last_new_user)
158 { 158 {
159 m_last_new_user = clientName; 159 m_last_new_user = clientName;
160 string clientRegion = FindClientRegion(client.FirstName, client.LastName); 160 string clientRegion = FindClientRegion(client.FirstName, client.LastName);
161 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " in "+clientRegion); 161 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " in "+clientRegion);
162 } 162 }
163 } 163 }
164 client.OnLogout += ClientLoggedOut; 164 client.OnLogout += ClientLoggedOut;
165 client.OnConnectionClosed += ClientLoggedOut; 165 client.OnConnectionClosed += ClientLoggedOut;
166 client.OnLogout += ClientLoggedOut; 166 client.OnLogout += ClientLoggedOut;
167 } 167 }
168 catch (Exception ex) 168 catch (Exception ex)
169 { 169 {
170 m_log.Error("[IRC]: NewClient exception trap:" + ex.ToString()); 170 m_log.Error("[IRC]: NewClient exception trap:" + ex.ToString());
171 } 171 }
172 } 172 }
173 173
174 public void ClientLoggedOut(IClientAPI client) 174 public void ClientLoggedOut(IClientAPI client)
175 { 175 {
176 lock (m_syncLogout) 176 lock (m_syncLogout)
177 { 177 {
178 try 178 try
179 { 179 {
180 if ((m_irc.Enabled) && (m_irc.Connected)) 180 if ((m_irc.Enabled) && (m_irc.Connected))
181 { 181 {
182 string clientName = client.FirstName + " " + client.LastName; 182 string clientName = client.FirstName + " " + client.LastName;
183 string clientRegion = FindClientRegion(client.FirstName, client.LastName); 183 string clientRegion = FindClientRegion(client.FirstName, client.LastName);
184 // handles simple case. May not work for hundred connecting in per second. 184 // handles simple case. May not work for hundred connecting in per second.
185 // and the NewClients calles getting interleved 185 // and the NewClients calles getting interleved
186 // but filters out multiple reports 186 // but filters out multiple reports
187 if (clientName != m_last_leaving_user) 187 if (clientName != m_last_leaving_user)
188 { 188 {
189 m_last_leaving_user = clientName; 189 m_last_leaving_user = clientName;
190 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " left " + clientRegion); 190 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " left " + clientRegion);
191 m_log.Info("[IRC]: IRC watcher notices " + clientName + " left " + clientRegion); 191 m_log.Info("[IRC]: IRC watcher notices " + clientName + " left " + clientRegion);
192 } 192 }
193 } 193 }
194 } 194 }
195 catch (Exception ex) 195 catch (Exception ex)
196 { 196 {
197 m_log.Error("[IRC]: ClientLoggedOut exception trap:" + ex.ToString()); 197 m_log.Error("[IRC]: ClientLoggedOut exception trap:" + ex.ToString());
198 } 198 }
199 } 199 }
200 } 200 }
201 201
202 private void TrySendChatMessage(ScenePresence presence, LLVector3 fromPos, LLVector3 regionPos, 202 private void TrySendChatMessage(ScenePresence presence, LLVector3 fromPos, LLVector3 regionPos,
203 LLUUID fromAgentID, string fromName, ChatTypeEnum type, string message) 203 LLUUID fromAgentID, string fromName, ChatTypeEnum type, string message)
204 { 204 {
205 if (!presence.IsChildAgent) 205 if (!presence.IsChildAgent)
206 { 206 {
207 LLVector3 fromRegionPos = fromPos + regionPos; 207 LLVector3 fromRegionPos = fromPos + regionPos;
208 LLVector3 toRegionPos = presence.AbsolutePosition + regionPos; 208 LLVector3 toRegionPos = presence.AbsolutePosition + regionPos;
209 int dis = Math.Abs((int) Util.GetDistanceTo(toRegionPos, fromRegionPos)); 209 int dis = Math.Abs((int) Util.GetDistanceTo(toRegionPos, fromRegionPos));
210 210
211 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || 211 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance ||
212 type == ChatTypeEnum.Say && dis > m_saydistance || 212 type == ChatTypeEnum.Say && dis > m_saydistance ||
213 type == ChatTypeEnum.Shout && dis > m_shoutdistance) 213 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
214 { 214 {
215 return; 215 return;
216 } 216 }
217 217
218 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView 218 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView
219 presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName, fromAgentID); 219 presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName, fromAgentID);
220 } 220 }
221 } 221 }
222 222
223 public void SimChat(Object sender, ChatFromViewerArgs e) 223 public void SimChat(Object sender, ChatFromViewerArgs e)
224 { 224 {
225 // FROM: Sim TO: IRC 225 // FROM: Sim TO: IRC
226 226
227 ScenePresence avatar = null; 227 ScenePresence avatar = null;
228 228
229 //TODO: Move ForEachScenePresence and others into IScene. 229 //TODO: Move ForEachScenePresence and others into IScene.
230 Scene scene = (Scene) e.Scene; 230 Scene scene = (Scene) e.Scene;
231 231
232 //TODO: Remove the need for this check 232 //TODO: Remove the need for this check
233 if (scene == null) 233 if (scene == null)
234 scene = m_scenes[0]; 234 scene = m_scenes[0];
235 235
236 // Filled in since it's easier than rewriting right now. 236 // Filled in since it's easier than rewriting right now.
237 LLVector3 fromPos = e.Position; 237 LLVector3 fromPos = e.Position;
238 LLVector3 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 238 LLVector3 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
239 239
240 string fromName = e.From; 240 string fromName = e.From;
241 string message = e.Message; 241 string message = e.Message;
242 LLUUID fromAgentID = LLUUID.Zero; 242 LLUUID fromAgentID = LLUUID.Zero;
243 243
244 if (e.Sender != null) 244 if (e.Sender != null)
245 { 245 {
246 avatar = scene.GetScenePresence(e.Sender.AgentId); 246 avatar = scene.GetScenePresence(e.Sender.AgentId);
247 } 247 }
248 248
249 if (avatar != null) 249 if (avatar != null)
250 { 250 {
251 fromPos = avatar.AbsolutePosition; 251 fromPos = avatar.AbsolutePosition;
252 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 252 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
253 fromName = avatar.Firstname + " " + avatar.Lastname; 253 fromName = avatar.Firstname + " " + avatar.Lastname;
254 fromAgentID = e.Sender.AgentId; 254 fromAgentID = e.Sender.AgentId;
255 } 255 }
256 256
257 // Try to reconnect to server if not connected 257 // Try to reconnect to server if not connected
258 if (m_irc.Enabled && !m_irc.Connected) 258 if (m_irc.Enabled && !m_irc.Connected)
259 { 259 {
260 // In a non-blocking way. Eventually the connector will get it started 260 // In a non-blocking way. Eventually the connector will get it started
261 try 261 try
262 { 262 {
263 if (m_irc_connector == null) 263 if (m_irc_connector == null)
264 { 264 {
265 m_irc_connector = new Thread(IRCConnectRun); 265 m_irc_connector = new Thread(IRCConnectRun);
266 m_irc_connector.Name = "IRCConnectorThread"; 266 m_irc_connector.Name = "IRCConnectorThread";
267 m_irc_connector.IsBackground = true; 267 m_irc_connector.IsBackground = true;
268 } 268 }
269 if (!m_irc_connector.IsAlive) 269 if (!m_irc_connector.IsAlive)
270 { 270 {
271 m_irc_connector.Start(); 271 m_irc_connector.Start();
272 ThreadTracker.Add(m_irc_connector); 272 ThreadTracker.Add(m_irc_connector);
273 } 273 }
274 } 274 }
275 catch (Exception) 275 catch (Exception)
276 { 276 {
277 } 277 }
278 } 278 }
279 279
280 280
281 // We only want to relay stuff on channel 0 281 // We only want to relay stuff on channel 0
282 if (e.Channel == 0) 282 if (e.Channel == 0)
283 { 283 {
284 // IRC stuff 284 // IRC stuff
285 if (e.Message.Length > 0) 285 if (e.Message.Length > 0)
286 { 286 {
287 if (m_irc.Connected && (avatar != null)) // this is to keep objects from talking to IRC 287 if (m_irc.Connected && (avatar != null)) // this is to keep objects from talking to IRC
288 { 288 {
289 m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, e.Message); 289 m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, e.Message);
290 } 290 }
291 } 291 }
292 292
293 foreach (Scene s in m_scenes) 293 foreach (Scene s in m_scenes)
294 { 294 {
295 s.ForEachScenePresence(delegate(ScenePresence presence) 295 s.ForEachScenePresence(delegate(ScenePresence presence)
296 { 296 {
297 TrySendChatMessage(presence, fromPos, regionPos, 297 TrySendChatMessage(presence, fromPos, regionPos,
298 fromAgentID, fromName, e.Type, message); 298 fromAgentID, fromName, e.Type, message);
299 }); 299 });
300 } 300 }
301 } 301 }
302 } 302 }
303 303
304 // if IRC is enabled then just keep trying using a monitor thread 304 // if IRC is enabled then just keep trying using a monitor thread
305 public void IRCConnectRun() 305 public void IRCConnectRun()
306 { 306 {
307 while(true) 307 while(true)
308 { 308 {
309 if ((m_irc.Enabled)&&(!m_irc.Connected)) 309 if ((m_irc.Enabled)&&(!m_irc.Connected))
310 { 310 {
311 m_irc.Connect(m_scenes); 311 m_irc.Connect(m_scenes);
312 } 312 }
313 Thread.Sleep(15000); 313 Thread.Sleep(15000);
314 } 314 }
315 } 315 }
316 316
317 public string FindClientRegion(string client_FirstName,string client_LastName) 317 public string FindClientRegion(string client_FirstName,string client_LastName)
318 { 318 {
319 string sourceRegion = null; 319 string sourceRegion = null;
320 foreach (Scene s in m_scenes) 320 foreach (Scene s in m_scenes)
321 { 321 {
322 s.ForEachScenePresence(delegate(ScenePresence presence) 322 s.ForEachScenePresence(delegate(ScenePresence presence)
323 { 323 {
324 if ((presence.IsChildAgent==false) 324 if ((presence.IsChildAgent==false)
325 &&(presence.Firstname==client_FirstName) 325 &&(presence.Firstname==client_FirstName)
326 &&(presence.Lastname==client_LastName)) 326 &&(presence.Lastname==client_LastName))
327 { 327 {
328 sourceRegion = presence.Scene.RegionInfo.RegionName; 328 sourceRegion = presence.Scene.RegionInfo.RegionName;
329 //sourceRegion= s.RegionInfo.RegionName; 329 //sourceRegion= s.RegionInfo.RegionName;
330 } 330 }
331 }); 331 });
332 if (sourceRegion != null) return sourceRegion; 332 if (sourceRegion != null) return sourceRegion;
333 } 333 }
334 if (m_defaultzone == null) { m_defaultzone = "Sim"; } 334 if (m_defaultzone == null) { m_defaultzone = "Sim"; }
335 return m_defaultzone; 335 return m_defaultzone;
336 } 336 }
337 } 337 }
338 338
339 internal class IRCChatModule 339 internal class IRCChatModule
340 { 340 {
341 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 341 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
342 342
343 private string m_server = null; 343 private string m_server = null;
344 private uint m_port = 6668; 344 private uint m_port = 6668;
345 private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot"; 345 private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot";
346 private string m_nick = null; 346 private string m_nick = null;
347 private string m_basenick = null; 347 private string m_basenick = null;
348 private string m_channel = null; 348 private string m_channel = null;
349 private string m_privmsgformat = "PRIVMSG {0} :<{1} in {2}>: {3}"; 349 private string m_privmsgformat = "PRIVMSG {0} :<{1} in {2}>: {3}";
350 350
351 private NetworkStream m_stream; 351 private NetworkStream m_stream;
352 private TcpClient m_tcp; 352 private TcpClient m_tcp;
353 private StreamWriter m_writer; 353 private StreamWriter m_writer;
354 private StreamReader m_reader; 354 private StreamReader m_reader;
355 355
356 private Thread pingSender; 356 private Thread pingSender;
357 private Thread listener; 357 private Thread listener;
358 internal object m_syncConnect = new object(); 358 internal object m_syncConnect = new object();
359 359
360 private bool m_enabled = false; 360 private bool m_enabled = false;
361 private bool m_connected = false; 361 private bool m_connected = false;
362 362
363 private List<Scene> m_scenes = null; 363 private List<Scene> m_scenes = null;
364 private List<Scene> m_last_scenes = null; 364 private List<Scene> m_last_scenes = null;
365 365
366 public IRCChatModule(IConfigSource config) 366 public IRCChatModule(IConfigSource config)
367 { 367 {
368 m_nick = "OSimBot" + Util.RandomClass.Next(1, 99); 368 m_nick = "OSimBot" + Util.RandomClass.Next(1, 99);
369 m_tcp = null; 369 m_tcp = null;
370 m_writer = null; 370 m_writer = null;
371 m_reader = null; 371 m_reader = null;
372 372
373 // configuration in OpenSim.ini 373 // configuration in OpenSim.ini
374 // [IRC] 374 // [IRC]
375 // server = chat.freenode.net 375 // server = chat.freenode.net
376 // nick = OSimBot_mysim 376 // nick = OSimBot_mysim
377 // ;username = USER OpenSimBot 8 * :I'm a OpenSim to irc bot 377 // ;username = USER OpenSimBot 8 * :I'm a OpenSim to irc bot
378 // ; username is the IRC command line sent 378 // ; username is the IRC command line sent
379 // ; USER <irc_user> <visible=8,invisible=0> * : <IRC_realname> 379 // ; USER <irc_user> <visible=8,invisible=0> * : <IRC_realname>
380 // channel = #opensim-regions 380 // channel = #opensim-regions
381 // port = 6667 381 // port = 6667
382 // ;MSGformat fields : 0=botnick, 1=user, 2=region, 3=message 382 // ;MSGformat fields : 0=botnick, 1=user, 2=region, 3=message
383 // ;for <bot>:<user in region> :<message> 383 // ;for <bot>:<user in region> :<message>
384 // ;msgformat = "PRIVMSG {0} :<{1} in {2}>: {3}" 384 // ;msgformat = "PRIVMSG {0} :<{1} in {2}>: {3}"
385 // ;for <bot>:<message> - <user of region> : 385 // ;for <bot>:<message> - <user of region> :
386 // ;msgformat = "PRIVMSG {0} : {3} - {1} of {2}" 386 // ;msgformat = "PRIVMSG {0} : {3} - {1} of {2}"
387 // ;for <bot>:<message> - from <user> : 387 // ;for <bot>:<message> - from <user> :
388 // ;msgformat = "PRIVMSG {0} : {3} - from {1}" 388 // ;msgformat = "PRIVMSG {0} : {3} - from {1}"
389 // Traps I/O disconnects so it does not crash the sim 389 // Traps I/O disconnects so it does not crash the sim
390 // Trys to reconnect if disconnected and someone says something 390 // Trys to reconnect if disconnected and someone says something
391 // Tells IRC server "QUIT" when doing a close (just to be nice) 391 // Tells IRC server "QUIT" when doing a close (just to be nice)
392 // Default port back to 6667 392 // Default port back to 6667
393 393
394 try 394 try
395 { 395 {
396 m_server = config.Configs["IRC"].GetString("server"); 396 m_server = config.Configs["IRC"].GetString("server");
397 m_nick = config.Configs["IRC"].GetString("nick"); 397 m_nick = config.Configs["IRC"].GetString("nick");
398 m_basenick = m_nick; 398 m_basenick = m_nick;
399 m_channel = config.Configs["IRC"].GetString("channel"); 399 m_channel = config.Configs["IRC"].GetString("channel");
400 m_port = (uint) config.Configs["IRC"].GetInt("port", (int) m_port); 400 m_port = (uint) config.Configs["IRC"].GetInt("port", (int) m_port);
401 m_user = config.Configs["IRC"].GetString("username", m_user); 401 m_user = config.Configs["IRC"].GetString("username", m_user);
402 m_privmsgformat = config.Configs["IRC"].GetString("msgformat", m_privmsgformat); 402 m_privmsgformat = config.Configs["IRC"].GetString("msgformat", m_privmsgformat);
403 if (m_server != null && m_nick != null && m_channel != null) 403 if (m_server != null && m_nick != null && m_channel != null)
404 { 404 {
405 m_nick = m_nick + Util.RandomClass.Next(1, 99); 405 m_nick = m_nick + Util.RandomClass.Next(1, 99);
406 m_enabled = true; 406 m_enabled = true;
407 } 407 }
408 } 408 }
409 catch (Exception) 409 catch (Exception)
410 { 410 {
411 m_log.Info("[CHAT]: No IRC config information, skipping IRC bridge configuration"); 411 m_log.Info("[CHAT]: No IRC config information, skipping IRC bridge configuration");
412 } 412 }
413 } 413 }
414 414
415 public bool Connect(List<Scene> scenes) 415 public bool Connect(List<Scene> scenes)
416 { 416 {
417 lock (m_syncConnect) 417 lock (m_syncConnect)
418 { 418 {
419 try 419 try
420 { 420 {
421 if (m_connected) return true; 421 if (m_connected) return true;
422 m_scenes = scenes; 422 m_scenes = scenes;
423 if (m_last_scenes == null) { m_last_scenes = scenes; } 423 if (m_last_scenes == null) { m_last_scenes = scenes; }
424 424
425 m_tcp = new TcpClient(m_server, (int)m_port); 425 m_tcp = new TcpClient(m_server, (int)m_port);
426 m_log.Info("[IRC]: Connecting..."); 426 m_log.Info("[IRC]: Connecting...");
427 m_stream = m_tcp.GetStream(); 427 m_stream = m_tcp.GetStream();
428 m_log.Info("[IRC]: Connected to " + m_server); 428 m_log.Info("[IRC]: Connected to " + m_server);
429 m_reader = new StreamReader(m_stream); 429 m_reader = new StreamReader(m_stream);
430 m_writer = new StreamWriter(m_stream); 430 m_writer = new StreamWriter(m_stream);
431 431
432 pingSender = new Thread(new ThreadStart(PingRun)); 432 pingSender = new Thread(new ThreadStart(PingRun));
433 pingSender.Name = "PingSenderThread"; 433 pingSender.Name = "PingSenderThread";
434 pingSender.IsBackground = true; 434 pingSender.IsBackground = true;
435 pingSender.Start(); 435 pingSender.Start();
436 ThreadTracker.Add(pingSender); 436 ThreadTracker.Add(pingSender);
437 437
438 listener = new Thread(new ThreadStart(ListenerRun)); 438 listener = new Thread(new ThreadStart(ListenerRun));
439 listener.Name = "IRCChatModuleListenerThread"; 439 listener.Name = "IRCChatModuleListenerThread";
440 listener.IsBackground = true; 440 listener.IsBackground = true;
441 listener.Start(); 441 listener.Start();
442 ThreadTracker.Add(listener); 442 ThreadTracker.Add(listener);
443 443
444 m_writer.WriteLine(m_user); 444 m_writer.WriteLine(m_user);
445 m_writer.Flush(); 445 m_writer.Flush();
446 m_writer.WriteLine("NICK " + m_nick); 446 m_writer.WriteLine("NICK " + m_nick);
447 m_writer.Flush(); 447 m_writer.Flush();
448 m_writer.WriteLine("JOIN " + m_channel); 448 m_writer.WriteLine("JOIN " + m_channel);
449 m_writer.Flush(); 449 m_writer.Flush();
450 m_log.Info("[IRC]: Connection fully established"); 450 m_log.Info("[IRC]: Connection fully established");
451 m_connected = true; 451 m_connected = true;
452 } 452 }
453 catch (Exception e) 453 catch (Exception e)
454 { 454 {
455 Console.WriteLine(e.ToString()); 455 Console.WriteLine(e.ToString());
456 } 456 }
457 return m_connected; 457 return m_connected;
458 } 458 }
459 } 459 }
460 460
461 public bool Enabled 461 public bool Enabled
462 { 462 {
463 get { return m_enabled; } 463 get { return m_enabled; }
464 } 464 }
465 465
466 public bool Connected 466 public bool Connected
467 { 467 {
468 get { return m_connected; } 468 get { return m_connected; }
469 } 469 }
470 470
471 public string Nick 471 public string Nick
472 { 472 {
473 get { return m_nick; } 473 get { return m_nick; }
474 } 474 }
475 475
476 public void Reconnect() 476 public void Reconnect()
477 { 477 {
478 m_connected = false; 478 m_connected = false;
479 listener.Abort(); 479 listener.Abort();
480 pingSender.Abort(); 480 pingSender.Abort();
481 m_writer.Close(); 481 m_writer.Close();
482 m_reader.Close(); 482 m_reader.Close();
483 m_tcp.Close(); 483 m_tcp.Close();
484 if (m_enabled) { Connect(m_last_scenes); } 484 if (m_enabled) { Connect(m_last_scenes); }
485 } 485 }
486 486
487 public void PrivMsg(string from, string region, string msg) 487 public void PrivMsg(string from, string region, string msg)
488 { 488 {
489 // One message to the IRC server 489 // One message to the IRC server
490 490
491 try 491 try
492 { 492 {
493 if (m_privmsgformat == null) 493 if (m_privmsgformat == null)
494 { 494 {
495 m_writer.WriteLine("PRIVMSG {0} :<{1} in {2}>: {3}", m_channel, from, region, msg); 495 m_writer.WriteLine("PRIVMSG {0} :<{1} in {2}>: {3}", m_channel, from, region, msg);
496 } 496 }
497 else 497 else
498 { 498 {
499 m_writer.WriteLine(m_privmsgformat, m_channel, from, region, msg); 499 m_writer.WriteLine(m_privmsgformat, m_channel, from, region, msg);
500 } 500 }
501 m_writer.Flush(); 501 m_writer.Flush();
502 m_log.Info("[IRC]: PrivMsg " + from + " in " + region + " :" + msg); 502 m_log.Info("[IRC]: PrivMsg " + from + " in " + region + " :" + msg);
503 } 503 }
504 catch (IOException) 504 catch (IOException)
505 { 505 {
506 m_log.Error("[IRC]: Disconnected from IRC server.(PrivMsg)"); 506 m_log.Error("[IRC]: Disconnected from IRC server.(PrivMsg)");
507 Reconnect(); 507 Reconnect();
508 } 508 }
509 catch (Exception ex) 509 catch (Exception ex)
510 { 510 {
511 m_log.Error("[IRC]: PrivMsg exception trap:" + ex.ToString()); 511 m_log.Error("[IRC]: PrivMsg exception trap:" + ex.ToString());
512 } 512 }
513 } 513 }
514 514
515 private Dictionary<string, string> ExtractMsg(string input) 515 private Dictionary<string, string> ExtractMsg(string input)
516 { 516 {
517 //examines IRC commands and extracts any private messages 517 //examines IRC commands and extracts any private messages
518 // which will then be reboadcast in the Sim 518 // which will then be reboadcast in the Sim
519 519
520 m_log.Info("[IRC]: ExtractMsg: " + input); 520 m_log.Info("[IRC]: ExtractMsg: " + input);
521 Dictionary<string, string> result = null; 521 Dictionary<string, string> result = null;
522 //string regex = @":(?<nick>\w*)!~(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)"; 522 //string regex = @":(?<nick>\w*)!~(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)";
523 string regex = @":(?<nick>\w*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)"; 523 string regex = @":(?<nick>\w*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)";
524 Regex RE = new Regex(regex, RegexOptions.Multiline); 524 Regex RE = new Regex(regex, RegexOptions.Multiline);
525 MatchCollection matches = RE.Matches(input); 525 MatchCollection matches = RE.Matches(input);
526 // Get some direct matches $1 $4 is a 526 // Get some direct matches $1 $4 is a
527 if ((matches.Count == 1) && (matches[0].Groups.Count == 5)) 527 if ((matches.Count == 1) && (matches[0].Groups.Count == 5))
528 { 528 {
529 result = new Dictionary<string, string>(); 529 result = new Dictionary<string, string>();
530 result.Add("nick", matches[0].Groups[1].Value); 530 result.Add("nick", matches[0].Groups[1].Value);
531 result.Add("user", matches[0].Groups[2].Value); 531 result.Add("user", matches[0].Groups[2].Value);
532 result.Add("channel", matches[0].Groups[3].Value); 532 result.Add("channel", matches[0].Groups[3].Value);
533 result.Add("msg", matches[0].Groups[4].Value); 533 result.Add("msg", matches[0].Groups[4].Value);
534 } 534 }
535 else 535 else
536 { 536 {
537 m_log.Info("[IRC]: Number of matches: " + matches.Count); 537 m_log.Info("[IRC]: Number of matches: " + matches.Count);
538 if (matches.Count > 0) 538 if (matches.Count > 0)
539 { 539 {
540 m_log.Info("[IRC]: Number of groups: " + matches[0].Groups.Count); 540 m_log.Info("[IRC]: Number of groups: " + matches[0].Groups.Count);
541 } 541 }
542 } 542 }
543 return result; 543 return result;
544 } 544 }
545 545
546 public void PingRun() 546 public void PingRun()
547 { 547 {
548 // IRC keep alive thread 548 // IRC keep alive thread
549 // send PING ever 15 seconds 549 // send PING ever 15 seconds
550 while (true) 550 while (true)
551 { 551 {
552 try 552 try
553 { 553 {
554 if (m_connected == true) 554 if (m_connected == true)
555 { 555 {
556 m_writer.WriteLine("PING :" + m_server); 556 m_writer.WriteLine("PING :" + m_server);
557 m_writer.Flush(); 557 m_writer.Flush();
558 Thread.Sleep(15000); 558 Thread.Sleep(15000);
559 } 559 }
560 } 560 }
561 catch (IOException) 561 catch (IOException)
562 { 562 {
563 m_log.Error("[IRC]: Disconnected from IRC server.(PingRun)"); 563 m_log.Error("[IRC]: Disconnected from IRC server.(PingRun)");
564 Reconnect(); 564 Reconnect();
565 } 565 }
566 catch (Exception ex) 566 catch (Exception ex)
567 { 567 {
568 m_log.Error("[IRC]: PingRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace); 568 m_log.Error("[IRC]: PingRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace);
569 } 569 }
570 } 570 }
571 } 571 }
572 572
573 public void ListenerRun() 573 public void ListenerRun()
574 { 574 {
575 string inputLine; 575 string inputLine;
576 LLVector3 pos = new LLVector3(128, 128, 20); 576 LLVector3 pos = new LLVector3(128, 128, 20);
577 while (true) 577 while (true)
578 { 578 {
579 try 579 try
580 { 580 {
581 while ((m_connected == true) && ((inputLine = m_reader.ReadLine()) != null)) 581 while ((m_connected == true) && ((inputLine = m_reader.ReadLine()) != null))
582 { 582 {
583 // Console.WriteLine(inputLine); 583 // Console.WriteLine(inputLine);
584 if (inputLine.Contains(m_channel)) 584 if (inputLine.Contains(m_channel))
585 { 585 {
586 Dictionary<string, string> data = ExtractMsg(inputLine); 586 Dictionary<string, string> data = ExtractMsg(inputLine);
587 // Any chat ??? 587 // Any chat ???
588 if (data != null) 588 if (data != null)
589 { 589 {
590 foreach (Scene m_scene in m_scenes) 590 foreach (Scene m_scene in m_scenes)
591 { 591 {
592 m_scene.ForEachScenePresence(delegate(ScenePresence avatar) 592 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
593 { 593 {
594 if (!avatar.IsChildAgent) 594 if (!avatar.IsChildAgent)
595 { 595 {
596 avatar.ControllingClient.SendChatMessage( 596 avatar.ControllingClient.SendChatMessage(
597 Helpers.StringToField(data["msg"]), 255, 597 Helpers.StringToField(data["msg"]), 255,
598 pos, data["nick"], 598 pos, data["nick"],
599 LLUUID.Zero); 599 LLUUID.Zero);
600 } 600 }
601 }); 601 });
602 } 602 }
603 } 603 }
604 else 604 else
605 { 605 {
606 // Was an command from the IRC server 606 // Was an command from the IRC server
607 ProcessIRCCommand(inputLine); 607 ProcessIRCCommand(inputLine);
608 } 608 }
609 } 609 }
610 else 610 else
611 { 611 {
612 // Was an command from the IRC server 612 // Was an command from the IRC server
613 ProcessIRCCommand(inputLine); 613 ProcessIRCCommand(inputLine);
614 } 614 }
615 Thread.Sleep(150); 615 Thread.Sleep(150);
616 } 616 }
617 } 617 }
618 catch (IOException) 618 catch (IOException)
619 { 619 {
620 m_log.Error("[IRC]: ListenerRun IOException. Disconnected from IRC server ??? (ListenerRun)"); 620 m_log.Error("[IRC]: ListenerRun IOException. Disconnected from IRC server ??? (ListenerRun)");
621 Reconnect(); 621 Reconnect();
622 } 622 }
623 catch (Exception ex) 623 catch (Exception ex)
624 { 624 {
625 m_log.Error("[IRC]: ListenerRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace); 625 m_log.Error("[IRC]: ListenerRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace);
626 } 626 }
627 } 627 }
628 } 628 }
629 629
630 public void BroadcastSim(string message,string sender) 630 public void BroadcastSim(string message,string sender)
631 { 631 {
632 LLVector3 pos = new LLVector3(128, 128, 20); 632 LLVector3 pos = new LLVector3(128, 128, 20);
633 try 633 try
634 { 634 {
635 foreach (Scene m_scene in m_scenes) 635 foreach (Scene m_scene in m_scenes)
636 { 636 {
637 m_scene.ForEachScenePresence(delegate(ScenePresence avatar) 637 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
638 { 638 {
639 if (!avatar.IsChildAgent) 639 if (!avatar.IsChildAgent)
640 { 640 {
641 avatar.ControllingClient.SendChatMessage( 641 avatar.ControllingClient.SendChatMessage(
642 Helpers.StringToField(message), 255, 642 Helpers.StringToField(message), 255,
643 pos, sender, 643 pos, sender,
644 LLUUID.Zero); 644 LLUUID.Zero);
645 } 645 }
646 }); 646 });
647 } 647 }
648 } 648 }
649 catch (Exception ex) // IRC gate should not crash Sim 649 catch (Exception ex) // IRC gate should not crash Sim
650 { 650 {
651 m_log.Error("[IRC]: BroadcastSim Exception Trap:" + ex.ToString() + "\n" + ex.StackTrace); 651 m_log.Error("[IRC]: BroadcastSim Exception Trap:" + ex.ToString() + "\n" + ex.StackTrace);
652 } 652 }
653 } 653 }
654 654
655 public enum ErrorReplies 655 public enum ErrorReplies
656 { 656 {
657 NotRegistered = 451, // ":You have not registered" 657 NotRegistered = 451, // ":You have not registered"
658 NicknameInUse = 433 // "<nick> :Nickname is already in use" 658 NicknameInUse = 433 // "<nick> :Nickname is already in use"
659 } 659 }
660 660
661 public enum Replies 661 public enum Replies
662 { 662 {
663 MotdStart = 375, // ":- <server> Message of the day - " 663 MotdStart = 375, // ":- <server> Message of the day - "
664 Motd = 372, // ":- <text>" 664 Motd = 372, // ":- <text>"
665 EndOfMotd = 376 // ":End of /MOTD command" 665 EndOfMotd = 376 // ":End of /MOTD command"
666 } 666 }
667 667
668 public void ProcessIRCCommand(string command) 668 public void ProcessIRCCommand(string command)
669 { 669 {
670 //m_log.Info("[IRC]: ProcessIRCCommand:" + command); 670 //m_log.Info("[IRC]: ProcessIRCCommand:" + command);
671 671
672 string[] commArgs = new string[command.Split(' ').Length]; 672 string[] commArgs = new string[command.Split(' ').Length];
673 string c_server = m_server; 673 string c_server = m_server;
674 674
675 commArgs = command.Split(' '); 675 commArgs = command.Split(' ');
676 if (commArgs[0].Substring(0, 1) == ":") 676 if (commArgs[0].Substring(0, 1) == ":")
677 { 677 {
678 commArgs[0] = commArgs[0].Remove(0, 1); 678 commArgs[0] = commArgs[0].Remove(0, 1);
679 } 679 }
680 680
681 if (commArgs[1] == "002") 681 if (commArgs[1] == "002")
682 { 682 {
683 // fetch the correct servername 683 // fetch the correct servername
684 // ex: irc.freenode.net -> brown.freenode.net/kornbluth.freenode.net/... 684 // ex: irc.freenode.net -> brown.freenode.net/kornbluth.freenode.net/...
685 // irc.bluewin.ch -> irc1.bluewin.ch/irc2.bluewin.ch 685 // irc.bluewin.ch -> irc1.bluewin.ch/irc2.bluewin.ch
686 686
687 c_server = (commArgs[6].Split('['))[0]; 687 c_server = (commArgs[6].Split('['))[0];
688 m_server = c_server; 688 m_server = c_server;
689 } 689 }
690 690
691 if (commArgs[0] == "ERROR") 691 if (commArgs[0] == "ERROR")
692 { 692 {
693 m_log.Error("[IRC]: IRC SERVER ERROR:" + command); 693 m_log.Error("[IRC]: IRC SERVER ERROR:" + command);
694 } 694 }
695 695
696 if (commArgs[0] == "PING") 696 if (commArgs[0] == "PING")
697 { 697 {
698 string p_reply = ""; 698 string p_reply = "";
699 699
700 for (int i = 1; i < commArgs.Length; i++) 700 for (int i = 1; i < commArgs.Length; i++)
701 { 701 {
702 p_reply += commArgs[i] + " "; 702 p_reply += commArgs[i] + " ";
703 } 703 }
704 704
705 m_writer.WriteLine("PONG " + p_reply); 705 m_writer.WriteLine("PONG " + p_reply);
706 m_writer.Flush(); 706 m_writer.Flush();
707 } 707 }
708 else if (commArgs[0] == c_server) 708 else if (commArgs[0] == c_server)
709 { 709 {
710 // server message 710 // server message
711 try 711 try
712 { 712 {
713 Int32 commandCode = Int32.Parse(commArgs[1]); 713 Int32 commandCode = Int32.Parse(commArgs[1]);
714 switch (commandCode) 714 switch (commandCode)
715 { 715 {
716 case (int)ErrorReplies.NicknameInUse: 716 case (int)ErrorReplies.NicknameInUse:
717 // Gen a new name 717 // Gen a new name
718 m_nick = m_basenick + Util.RandomClass.Next(1, 99); 718 m_nick = m_basenick + Util.RandomClass.Next(1, 99);
719 m_log.Error("[IRC]: IRC SERVER reports NicknameInUse, trying " + m_nick); 719 m_log.Error("[IRC]: IRC SERVER reports NicknameInUse, trying " + m_nick);
720 // Retry 720 // Retry
721 m_writer.WriteLine("NICK " + m_nick); 721 m_writer.WriteLine("NICK " + m_nick);
722 m_writer.Flush(); 722 m_writer.Flush();
723 m_writer.WriteLine("JOIN " + m_channel); 723 m_writer.WriteLine("JOIN " + m_channel);
724 m_writer.Flush(); 724 m_writer.Flush();
725 break; 725 break;
726 case (int)ErrorReplies.NotRegistered: 726 case (int)ErrorReplies.NotRegistered:
727 break; 727 break;
728 case (int)Replies.EndOfMotd: 728 case (int)Replies.EndOfMotd:
729 break; 729 break;
730 } 730 }
731 } 731 }
732 catch (Exception) 732 catch (Exception)
733 { 733 {
734 } 734 }
735 } 735 }
736 else 736 else
737 { 737 {
738 // Normal message 738 // Normal message
739 string commAct = commArgs[1]; 739 string commAct = commArgs[1];
740 switch (commAct) 740 switch (commAct)
741 { 741 {
742 case "JOIN": eventIrcJoin(commArgs); break; 742 case "JOIN": eventIrcJoin(commArgs); break;
743 case "PART": eventIrcPart(commArgs); break; 743 case "PART": eventIrcPart(commArgs); break;
744 case "MODE": eventIrcMode(commArgs); break; 744 case "MODE": eventIrcMode(commArgs); break;
745 case "NICK": eventIrcNickChange(commArgs); break; 745 case "NICK": eventIrcNickChange(commArgs); break;
746 case "KICK": eventIrcKick(commArgs); break; 746 case "KICK": eventIrcKick(commArgs); break;
747 case "QUIT": eventIrcQuit(commArgs); break; 747 case "QUIT": eventIrcQuit(commArgs); break;
748 case "PONG": break; // that's nice 748 case "PONG": break; // that's nice
749 } 749 }
750 } 750 }
751 } 751 }
752 752
753 public void eventIrcJoin(string[] commArgs) 753 public void eventIrcJoin(string[] commArgs)
754 { 754 {
755 string IrcChannel = commArgs[2]; 755 string IrcChannel = commArgs[2];
756 string IrcUser = commArgs[0].Split('!')[0]; 756 string IrcUser = commArgs[0].Split('!')[0];
757 BroadcastSim(IrcUser + " is joining " + IrcChannel, m_nick); 757 BroadcastSim(IrcUser + " is joining " + IrcChannel, m_nick);
758 } 758 }
759 759
760 public void eventIrcPart(string[] commArgs) 760 public void eventIrcPart(string[] commArgs)
761 { 761 {
762 string IrcChannel = commArgs[2]; 762 string IrcChannel = commArgs[2];
763 string IrcUser = commArgs[0].Split('!')[0]; 763 string IrcUser = commArgs[0].Split('!')[0];
764 BroadcastSim(IrcUser + " is parting " + IrcChannel, m_nick); 764 BroadcastSim(IrcUser + " is parting " + IrcChannel, m_nick);
765 } 765 }
766 766
767 public void eventIrcMode(string[] commArgs) 767 public void eventIrcMode(string[] commArgs)
768 { 768 {
769 string IrcChannel = commArgs[2]; 769 string IrcChannel = commArgs[2];
770 string IrcUser = commArgs[0].Split('!')[0]; 770 string IrcUser = commArgs[0].Split('!')[0];
771 string UserMode = ""; 771 string UserMode = "";
772 for (int i = 3; i < commArgs.Length; i++) 772 for (int i = 3; i < commArgs.Length; i++)
773 { 773 {
774 UserMode += commArgs[i] + " "; 774 UserMode += commArgs[i] + " ";
775 } 775 }
776 776
777 if (UserMode.Substring(0, 1) == ":") 777 if (UserMode.Substring(0, 1) == ":")
778 { 778 {
779 UserMode = UserMode.Remove(0, 1); 779 UserMode = UserMode.Remove(0, 1);
780 } 780 }
781 } 781 }
782 782
783 public void eventIrcNickChange(string[] commArgs) 783 public void eventIrcNickChange(string[] commArgs)
784 { 784 {
785 string UserOldNick = commArgs[0].Split('!')[0]; 785 string UserOldNick = commArgs[0].Split('!')[0];
786 string UserNewNick = commArgs[2].Remove(0, 1); 786 string UserNewNick = commArgs[2].Remove(0, 1);
787 BroadcastSim(UserOldNick + " changed their nick to " + UserNewNick, m_nick); 787 BroadcastSim(UserOldNick + " changed their nick to " + UserNewNick, m_nick);
788 } 788 }
789 789
790 public void eventIrcKick(string[] commArgs) 790 public void eventIrcKick(string[] commArgs)
791 { 791 {
792 string UserKicker = commArgs[0].Split('!')[0]; 792 string UserKicker = commArgs[0].Split('!')[0];
793 string UserKicked = commArgs[3]; 793 string UserKicked = commArgs[3];
794 string IrcChannel = commArgs[2]; 794 string IrcChannel = commArgs[2];
795 string KickMessage = ""; 795 string KickMessage = "";
796 for (int i = 4; i < commArgs.Length; i++) 796 for (int i = 4; i < commArgs.Length; i++)
797 { 797 {
798 KickMessage += commArgs[i] + " "; 798 KickMessage += commArgs[i] + " ";
799 } 799 }
800 BroadcastSim(UserKicker + " kicked " + UserKicked +" on "+IrcChannel+" saying "+KickMessage, m_nick); 800 BroadcastSim(UserKicker + " kicked " + UserKicked +" on "+IrcChannel+" saying "+KickMessage, m_nick);
801 if (UserKicked == m_nick) 801 if (UserKicked == m_nick)
802 { 802 {
803 BroadcastSim("Hey, that was me!!!", m_nick); 803 BroadcastSim("Hey, that was me!!!", m_nick);
804 } 804 }
805 } 805 }
806 806
807 public void eventIrcQuit(string[] commArgs) 807 public void eventIrcQuit(string[] commArgs)
808 { 808 {
809 string IrcUser = commArgs[0].Split('!')[0]; 809 string IrcUser = commArgs[0].Split('!')[0];
810 string QuitMessage = ""; 810 string QuitMessage = "";
811 811
812 for (int i = 2; i < commArgs.Length; i++) 812 for (int i = 2; i < commArgs.Length; i++)
813 { 813 {
814 QuitMessage += commArgs[i] + " "; 814 QuitMessage += commArgs[i] + " ";
815 } 815 }
816 BroadcastSim(IrcUser + " quits saying " + QuitMessage, m_nick); 816 BroadcastSim(IrcUser + " quits saying " + QuitMessage, m_nick);
817 } 817 }
818 818
819 public void Close() 819 public void Close()
820 { 820 {
821 m_connected = false; 821 m_connected = false;
822 m_writer.WriteLine("QUIT :" + m_nick + " to " + m_channel + " wormhole with " + m_server + " closing"); 822 m_writer.WriteLine("QUIT :" + m_nick + " to " + m_channel + " wormhole with " + m_server + " closing");
823 m_writer.Flush(); 823 m_writer.Flush();
824 listener.Abort(); 824 listener.Abort();
825 pingSender.Abort(); 825 pingSender.Abort();
826 m_writer.Close(); 826 m_writer.Close();
827 m_reader.Close(); 827 m_reader.Close();
828 m_tcp.Close(); 828 m_tcp.Close();
829 } 829 }
830 } 830 }
831} 831} \ No newline at end of file