diff options
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 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.IO; | 30 | using System.IO; |
31 | using System.Net.Sockets; | 31 | using System.Net.Sockets; |
32 | using System.Reflection; | 32 | using System.Reflection; |
33 | using System.Text.RegularExpressions; | 33 | using System.Text.RegularExpressions; |
34 | using System.Threading; | 34 | using System.Threading; |
35 | using libsecondlife; | 35 | using libsecondlife; |
36 | using log4net; | 36 | using log4net; |
37 | using Nini.Config; | 37 | using Nini.Config; |
38 | using OpenSim.Framework; | 38 | using OpenSim.Framework; |
39 | using OpenSim.Region.Environment.Interfaces; | 39 | using OpenSim.Region.Environment.Interfaces; |
40 | using OpenSim.Region.Environment.Scenes; | 40 | using OpenSim.Region.Environment.Scenes; |
41 | 41 | ||
42 | namespace OpenSim.Region.Environment.Modules | 42 | namespace 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 |