aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/ChatModule.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Modules/ChatModule.cs266
1 files changed, 151 insertions, 115 deletions
diff --git a/OpenSim/Region/Environment/Modules/ChatModule.cs b/OpenSim/Region/Environment/Modules/ChatModule.cs
index bdb8ee5..9d4187a 100644
--- a/OpenSim/Region/Environment/Modules/ChatModule.cs
+++ b/OpenSim/Region/Environment/Modules/ChatModule.cs
@@ -27,13 +27,13 @@
27*/ 27*/
28 28
29using System; 29using System;
30using System.Collections.Generic;
30using System.IO; 31using System.IO;
31using System.Net.Sockets; 32using System.Net.Sockets;
32using System.Threading;
33using System.Collections.Generic;
34using System.Text.RegularExpressions; 33using System.Text.RegularExpressions;
34using System.Threading;
35using libsecondlife; 35using libsecondlife;
36using OpenSim.Framework.Interfaces; 36using Nini.Config;
37using OpenSim.Framework; 37using OpenSim.Framework;
38using OpenSim.Framework.Console; 38using OpenSim.Framework.Console;
39using OpenSim.Region.Environment.Interfaces; 39using OpenSim.Region.Environment.Interfaces;
@@ -54,18 +54,22 @@ namespace OpenSim.Region.Environment.Modules
54 54
55 public ChatModule() 55 public ChatModule()
56 { 56 {
57 m_log = OpenSim.Framework.Console.MainLog.Instance; 57 m_log = MainLog.Instance;
58 } 58 }
59 59
60 public void Initialise(Scene scene, Nini.Config.IConfigSource config) 60 public void Initialise(Scene scene, IConfigSource config)
61 { 61 {
62 // wrap this in a try block so that defaults will work if 62 // wrap this in a try block so that defaults will work if
63 // the config file doesn't specify otherwise. 63 // the config file doesn't specify otherwise.
64 try { 64 try
65 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); 65 {
66 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance);
66 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); 67 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance);
67 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); 68 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance);
68 } catch (Exception e) {} 69 }
70 catch (Exception e)
71 {
72 }
69 73
70 if (!m_scenes.Contains(scene)) 74 if (!m_scenes.Contains(scene))
71 { 75 {
@@ -73,20 +77,20 @@ namespace OpenSim.Region.Environment.Modules
73 scene.EventManager.OnNewClient += NewClient; 77 scene.EventManager.OnNewClient += NewClient;
74 scene.RegisterModuleInterface<ISimChat>(this); 78 scene.RegisterModuleInterface<ISimChat>(this);
75 } 79 }
76 80
77 // setup IRC Relay 81 // setup IRC Relay
78 m_irc = new IRCChatModule(config); 82 m_irc = new IRCChatModule(config);
79 } 83 }
80 84
81 public void PostInitialise() 85 public void PostInitialise()
82 { 86 {
83 87 if (m_irc.Enabled)
84 if (m_irc.Enabled) { 88 {
85 m_irc.Connect(m_scenes); 89 m_irc.Connect(m_scenes);
86 } 90 }
87 } 91 }
88 92
89 public void Close() 93 public void Close()
90 { 94 {
91 m_irc.Close(); 95 m_irc.Close();
92 } 96 }
@@ -111,7 +115,7 @@ namespace OpenSim.Region.Environment.Modules
111 ScenePresence avatar = null; 115 ScenePresence avatar = null;
112 116
113 //TODO: Move ForEachScenePresence and others into IScene. 117 //TODO: Move ForEachScenePresence and others into IScene.
114 Scene scene = (Scene)e.Scene; 118 Scene scene = (Scene) e.Scene;
115 119
116 //TODO: Remove the need for this check 120 //TODO: Remove the need for this check
117 if (scene == null) 121 if (scene == null)
@@ -119,10 +123,12 @@ namespace OpenSim.Region.Environment.Modules
119 123
120 // Filled in since it's easier than rewriting right now. 124 // Filled in since it's easier than rewriting right now.
121 LLVector3 fromPos = e.Position; 125 LLVector3 fromPos = e.Position;
122 LLVector3 fromRegionPos = e.Position + new LLVector3(e.Scene.RegionInfo.RegionLocX * 256, e.Scene.RegionInfo.RegionLocY * 256, 0); 126 LLVector3 fromRegionPos = e.Position +
127 new LLVector3(e.Scene.RegionInfo.RegionLocX*256, e.Scene.RegionInfo.RegionLocY*256,
128 0);
123 string fromName = e.From; 129 string fromName = e.From;
124 string message = e.Message; 130 string message = e.Message;
125 byte type = (byte)e.Type; 131 byte type = (byte) e.Type;
126 LLUUID fromAgentID = LLUUID.Zero; 132 LLUUID fromAgentID = LLUUID.Zero;
127 133
128 if (e.Sender != null) 134 if (e.Sender != null)
@@ -133,7 +139,8 @@ namespace OpenSim.Region.Environment.Modules
133 if (avatar != null) 139 if (avatar != null)
134 { 140 {
135 fromPos = avatar.AbsolutePosition; 141 fromPos = avatar.AbsolutePosition;
136 fromRegionPos = fromPos + new LLVector3(e.Scene.RegionInfo.RegionLocX * 256, e.Scene.RegionInfo.RegionLocY * 256, 0); 142 fromRegionPos = fromPos +
143 new LLVector3(e.Scene.RegionInfo.RegionLocX*256, e.Scene.RegionInfo.RegionLocY*256, 0);
137 fromName = avatar.Firstname + " " + avatar.Lastname; 144 fromName = avatar.Firstname + " " + avatar.Lastname;
138 fromAgentID = e.Sender.AgentId; 145 fromAgentID = e.Sender.AgentId;
139 avatar = null; 146 avatar = null;
@@ -159,75 +166,84 @@ namespace OpenSim.Region.Environment.Modules
159 break; 166 break;
160 } 167 }
161 168
162 m_log.Verbose("CHAT", fromName + " (" + e.Channel + " @ " + scene.RegionInfo.RegionName + ") " + typeName + ": " + e.Message); 169 m_log.Verbose("CHAT",
163 170 fromName + " (" + e.Channel + " @ " + scene.RegionInfo.RegionName + ") " + typeName + ": " +
164 if (m_irc.Connected) 171 e.Message);
165 { 172
166 m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, e.Message); 173 if (m_irc.Connected)
167 } 174 {
168 175 m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, e.Message);
169 if (e.Channel == 0) 176 }
170 { 177
171 foreach (Scene m_scene in m_scenes) 178 if (e.Channel == 0)
172 { 179 {
173 m_scene.ForEachScenePresence(delegate(ScenePresence presence) 180 foreach (Scene m_scene in m_scenes)
174 { 181 {
175 int dis = -100000; 182 m_scene.ForEachScenePresence(delegate(ScenePresence presence)
176 183 {
177 LLVector3 avatarRegionPos = presence.AbsolutePosition + new LLVector3(scene.RegionInfo.RegionLocX * 256, scene.RegionInfo.RegionLocY * 256, 0); 184 int dis = -100000;
178 dis = Math.Abs((int)avatarRegionPos.GetDistanceTo(fromRegionPos)); 185
179 186 LLVector3 avatarRegionPos = presence.AbsolutePosition +
180 switch (e.Type) 187 new LLVector3(
181 { 188 scene.RegionInfo.RegionLocX*256,
182 case ChatTypeEnum.Whisper: 189 scene.RegionInfo.RegionLocY*256,
183 if (dis < m_whisperdistance) 190 0);
184 { 191 dis =
185 //should change so the message is sent through the avatar rather than direct to the ClientView 192 Math.Abs((int) avatarRegionPos.GetDistanceTo(fromRegionPos));
186 presence.ControllingClient.SendChatMessage(message, 193
187 type, 194 switch (e.Type)
188 fromPos, 195 {
189 fromName, 196 case ChatTypeEnum.Whisper:
190 fromAgentID); 197 if (dis < m_whisperdistance)
191 } 198 {
192 break; 199 //should change so the message is sent through the avatar rather than direct to the ClientView
193 case ChatTypeEnum.Say: 200 presence.ControllingClient.SendChatMessage(message,
194 if (dis < m_saydistance) 201 type,
195 { 202 fromPos,
196 //Console.WriteLine("sending chat"); 203 fromName,
197 presence.ControllingClient.SendChatMessage(message, 204 fromAgentID);
198 type, 205 }
199 fromPos, 206 break;
200 fromName, 207 case ChatTypeEnum.Say:
201 fromAgentID); 208 if (dis < m_saydistance)
202 } 209 {
203 break; 210 //Console.WriteLine("sending chat");
204 case ChatTypeEnum.Shout: 211 presence.ControllingClient.SendChatMessage(message,
205 if (dis < m_shoutdistance) 212 type,
206 { 213 fromPos,
207 presence.ControllingClient.SendChatMessage(message, 214 fromName,
208 type, 215 fromAgentID);
209 fromPos, 216 }
210 fromName, 217 break;
211 fromAgentID); 218 case ChatTypeEnum.Shout:
212 } 219 if (dis < m_shoutdistance)
213 break; 220 {
214 221 presence.ControllingClient.SendChatMessage(message,
215 case ChatTypeEnum.Broadcast: 222 type,
216 presence.ControllingClient.SendChatMessage(message, type, 223 fromPos,
217 fromPos, 224 fromName,
218 fromName, 225 fromAgentID);
219 fromAgentID); 226 }
220 break; 227 break;
221 default: 228
222 break; 229 case ChatTypeEnum.Broadcast:
223 } 230 presence.ControllingClient.SendChatMessage(message,
224 }); 231 type,
232 fromPos,
233 fromName,
234 fromAgentID);
235 break;
236 default:
237 break;
238 }
239 });
225 } 240 }
226 } 241 }
227 } 242 }
228 } 243 }
229 244
230 class IRCChatModule { 245 internal class IRCChatModule
246 {
231 private string m_server = null; 247 private string m_server = null;
232 private int m_port = 6668; 248 private int m_port = 6668;
233 private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot"; 249 private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot";
@@ -238,7 +254,7 @@ namespace OpenSim.Region.Environment.Modules
238 private TcpClient m_tcp; 254 private TcpClient m_tcp;
239 private StreamWriter m_writer; 255 private StreamWriter m_writer;
240 private StreamReader m_reader; 256 private StreamReader m_reader;
241 257
242 private Thread pingSender; 258 private Thread pingSender;
243 private Thread listener; 259 private Thread listener;
244 260
@@ -248,29 +264,36 @@ namespace OpenSim.Region.Environment.Modules
248 private List<Scene> m_scenes = null; 264 private List<Scene> m_scenes = null;
249 private LogBase m_log; 265 private LogBase m_log;
250 266
251 public IRCChatModule(Nini.Config.IConfigSource config) { 267 public IRCChatModule(IConfigSource config)
268 {
252 m_nick = "OSimBot" + Util.RandomClass.Next(1, 99); 269 m_nick = "OSimBot" + Util.RandomClass.Next(1, 99);
253 m_tcp = null; 270 m_tcp = null;
254 m_writer = null; 271 m_writer = null;
255 m_reader = null; 272 m_reader = null;
256 273
257 try { 274 try
275 {
258 m_server = config.Configs["IRC"].GetString("server"); 276 m_server = config.Configs["IRC"].GetString("server");
259 m_nick = config.Configs["IRC"].GetString("nick"); 277 m_nick = config.Configs["IRC"].GetString("nick");
260 m_channel = config.Configs["IRC"].GetString("channel"); 278 m_channel = config.Configs["IRC"].GetString("channel");
261 m_port = config.Configs["IRC"].GetInt("port", m_port); 279 m_port = config.Configs["IRC"].GetInt("port", m_port);
262 m_user = config.Configs["IRC"].GetString("username", m_user); 280 m_user = config.Configs["IRC"].GetString("username", m_user);
263 if (m_server != null && m_nick != null && m_channel != null) { 281 if (m_server != null && m_nick != null && m_channel != null)
282 {
264 m_enabled = true; 283 m_enabled = true;
265 } 284 }
266 } catch (Exception e) { 285 }
286 catch (Exception e)
287 {
267 Console.WriteLine("No IRC config information, skipping IRC bridge configuration"); 288 Console.WriteLine("No IRC config information, skipping IRC bridge configuration");
268 } 289 }
269 m_log = OpenSim.Framework.Console.MainLog.Instance; 290 m_log = MainLog.Instance;
270 } 291 }
271 292
272 public bool Connect(List<Scene> scenes) { 293 public bool Connect(List<Scene> scenes)
273 try { 294 {
295 try
296 {
274 m_scenes = scenes; 297 m_scenes = scenes;
275 298
276 m_tcp = new TcpClient(m_server, m_port); 299 m_tcp = new TcpClient(m_server, m_port);
@@ -279,13 +302,13 @@ namespace OpenSim.Region.Environment.Modules
279 m_log.Verbose("IRC", "Connected to " + m_server); 302 m_log.Verbose("IRC", "Connected to " + m_server);
280 m_reader = new StreamReader(m_stream); 303 m_reader = new StreamReader(m_stream);
281 m_writer = new StreamWriter(m_stream); 304 m_writer = new StreamWriter(m_stream);
282 305
283 pingSender = new Thread(new ThreadStart(this.PingRun)); 306 pingSender = new Thread(new ThreadStart(PingRun));
284 pingSender.Start(); 307 pingSender.Start();
285 308
286 listener = new Thread(new ThreadStart(this.ListenerRun)); 309 listener = new Thread(new ThreadStart(ListenerRun));
287 listener.Start(); 310 listener.Start();
288 311
289 m_writer.WriteLine(m_user); 312 m_writer.WriteLine(m_user);
290 m_writer.Flush(); 313 m_writer.Flush();
291 m_writer.WriteLine("NICK " + m_nick); 314 m_writer.WriteLine("NICK " + m_nick);
@@ -294,50 +317,61 @@ namespace OpenSim.Region.Environment.Modules
294 m_writer.Flush(); 317 m_writer.Flush();
295 m_log.Verbose("IRC", "Connection fully established"); 318 m_log.Verbose("IRC", "Connection fully established");
296 m_connected = true; 319 m_connected = true;
297 } catch (Exception e) { 320 }
321 catch (Exception e)
322 {
298 Console.WriteLine(e.ToString()); 323 Console.WriteLine(e.ToString());
299 } 324 }
300 return m_connected; 325 return m_connected;
301 } 326 }
302 327
303 public bool Enabled 328 public bool Enabled
304 { 329 {
305 get { return m_enabled; } 330 get { return m_enabled; }
306 } 331 }
307 332
308 public bool Connected 333 public bool Connected
309 { 334 {
310 get { return m_connected; } 335 get { return m_connected; }
311 } 336 }
312 337
313 public void PrivMsg(string from, string region, string msg) { 338 public void PrivMsg(string from, string region, string msg)
314 try { 339 {
340 try
341 {
315 m_writer.WriteLine("PRIVMSG {0} :<{1} in {2}>: {3}", m_channel, from, region, msg); 342 m_writer.WriteLine("PRIVMSG {0} :<{1} in {2}>: {3}", m_channel, from, region, msg);
316 m_writer.Flush(); 343 m_writer.Flush();
317 } catch (IOException) { 344 }
318 m_log.Error("IRC","Disconnected from IRC server."); 345 catch (IOException)
346 {
347 m_log.Error("IRC", "Disconnected from IRC server.");
319 listener.Abort(); 348 listener.Abort();
320 pingSender.Abort(); 349 pingSender.Abort();
321 m_connected = false; 350 m_connected = false;
322 } 351 }
323 } 352 }
324 353
325 private Dictionary<string, string> ExtractMsg(string input) { 354 private Dictionary<string, string> ExtractMsg(string input)
355 {
326 Dictionary<string, string> result = null; 356 Dictionary<string, string> result = null;
327 string regex = @":(?<nick>\w*)!~(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)"; 357 string regex = @":(?<nick>\w*)!~(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)";
328 Regex RE = new Regex(regex, RegexOptions.Multiline); 358 Regex RE = new Regex(regex, RegexOptions.Multiline);
329 MatchCollection matches = RE.Matches(input); 359 MatchCollection matches = RE.Matches(input);
330 // Get some direct matches $1 $4 is a 360 // Get some direct matches $1 $4 is a
331 if ((matches.Count == 1) && (matches[0].Groups.Count == 5)) { 361 if ((matches.Count == 1) && (matches[0].Groups.Count == 5))
362 {
332 result = new Dictionary<string, string>(); 363 result = new Dictionary<string, string>();
333 result.Add("nick", matches[0].Groups[1].Value); 364 result.Add("nick", matches[0].Groups[1].Value);
334 result.Add("user", matches[0].Groups[2].Value); 365 result.Add("user", matches[0].Groups[2].Value);
335 result.Add("channel", matches[0].Groups[3].Value); 366 result.Add("channel", matches[0].Groups[3].Value);
336 result.Add("msg", matches[0].Groups[4].Value); 367 result.Add("msg", matches[0].Groups[4].Value);
337 } else { 368 }
369 else
370 {
338 m_log.Verbose("IRC", "Number of matches: " + matches.Count); 371 m_log.Verbose("IRC", "Number of matches: " + matches.Count);
339 if (matches.Count > 0) { 372 if (matches.Count > 0)
340 m_log.Verbose("IRC", "Number of groups: " + matches[0].Groups.Count); 373 {
374 m_log.Verbose("IRC", "Number of groups: " + matches[0].Groups.Count);
341 } 375 }
342 } 376 }
343 return result; 377 return result;
@@ -365,19 +399,20 @@ namespace OpenSim.Region.Environment.Modules
365 if (inputLine.Contains(m_channel)) 399 if (inputLine.Contains(m_channel))
366 { 400 {
367 Dictionary<string, string> data = ExtractMsg(inputLine); 401 Dictionary<string, string> data = ExtractMsg(inputLine);
368 if (data != null ) 402 if (data != null)
369 { 403 {
370 foreach (Scene m_scene in m_scenes) 404 foreach (Scene m_scene in m_scenes)
371 { 405 {
372 m_scene.ForEachScenePresence(delegate(ScenePresence avatar) 406 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
373 {
374 if (!avatar.IsChildAgent)
375 { 407 {
376 avatar.ControllingClient.SendChatMessage( 408 if (!avatar.IsChildAgent)
377 Helpers.StringToField(data["msg"]), 255, pos, data["nick"], 409 {
378 LLUUID.Zero); 410 avatar.ControllingClient.SendChatMessage(
379 } 411 Helpers.StringToField(data["msg"]), 255,
380 }); 412 pos, data["nick"],
413 LLUUID.Zero);
414 }
415 });
381 } 416 }
382 } 417 }
383 } 418 }
@@ -387,7 +422,8 @@ namespace OpenSim.Region.Environment.Modules
387 } 422 }
388 423
389 424
390 public void Close() { 425 public void Close()
426 {
391 listener.Abort(); 427 listener.Abort();
392 pingSender.Abort(); 428 pingSender.Abort();
393 m_writer.Close(); 429 m_writer.Close();
@@ -395,4 +431,4 @@ namespace OpenSim.Region.Environment.Modules
395 m_tcp.Close(); 431 m_tcp.Close();
396 } 432 }
397 } 433 }
398} 434} \ No newline at end of file