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