diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | 158 |
1 files changed, 102 insertions, 56 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index e4452fb..dbbb0ae 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | |||
@@ -49,7 +49,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
49 | private int m_shoutdistance = 100; | 49 | private int m_shoutdistance = 100; |
50 | private int m_whisperdistance = 10; | 50 | private int m_whisperdistance = 10; |
51 | private List<Scene> m_scenes = new List<Scene>(); | 51 | private List<Scene> m_scenes = new List<Scene>(); |
52 | 52 | private List<string> FreezeCache = new List<string>(); | |
53 | private string m_adminPrefix = ""; | ||
53 | internal object m_syncy = new object(); | 54 | internal object m_syncy = new object(); |
54 | 55 | ||
55 | internal IConfig m_config; | 56 | internal IConfig m_config; |
@@ -76,6 +77,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
76 | m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); | 77 | m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); |
77 | m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); | 78 | m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); |
78 | m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); | 79 | m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); |
80 | m_adminPrefix = config.Configs["Chat"].GetString("admin_prefix", ""); | ||
79 | } | 81 | } |
80 | 82 | ||
81 | public virtual void AddRegion(Scene scene) | 83 | public virtual void AddRegion(Scene scene) |
@@ -171,7 +173,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
171 | return; | 173 | return; |
172 | } | 174 | } |
173 | 175 | ||
174 | DeliverChatToAvatars(ChatSourceType.Agent, c); | 176 | if (FreezeCache.Contains(c.Sender.AgentId.ToString())) |
177 | { | ||
178 | if (c.Type != ChatTypeEnum.StartTyping || c.Type != ChatTypeEnum.StopTyping) | ||
179 | c.Sender.SendAgentAlertMessage("You may not talk as you are frozen.", false); | ||
180 | } | ||
181 | else | ||
182 | { | ||
183 | DeliverChatToAvatars(ChatSourceType.Agent, c); | ||
184 | } | ||
175 | } | 185 | } |
176 | 186 | ||
177 | public virtual void OnChatFromWorld(Object sender, OSChatMessage c) | 187 | public virtual void OnChatFromWorld(Object sender, OSChatMessage c) |
@@ -185,10 +195,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
185 | protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c) | 195 | protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c) |
186 | { | 196 | { |
187 | string fromName = c.From; | 197 | string fromName = c.From; |
198 | string fromNamePrefix = ""; | ||
188 | UUID fromID = UUID.Zero; | 199 | UUID fromID = UUID.Zero; |
189 | UUID targetID = c.TargetUUID; | ||
190 | string message = c.Message; | 200 | string message = c.Message; |
191 | IScene scene = c.Scene; | 201 | IScene scene = c.Scene; |
202 | UUID destination = c.Destination; | ||
192 | Vector3 fromPos = c.Position; | 203 | Vector3 fromPos = c.Position; |
193 | Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, | 204 | Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, |
194 | scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); | 205 | scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); |
@@ -208,7 +219,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
208 | fromPos = avatar.AbsolutePosition; | 219 | fromPos = avatar.AbsolutePosition; |
209 | fromName = avatar.Name; | 220 | fromName = avatar.Name; |
210 | fromID = c.Sender.AgentId; | 221 | fromID = c.Sender.AgentId; |
211 | 222 | if (avatar.GodLevel >= 200) | |
223 | { | ||
224 | fromNamePrefix = m_adminPrefix; | ||
225 | } | ||
226 | destination = UUID.Zero; // Avatars cant "SayTo" | ||
212 | break; | 227 | break; |
213 | 228 | ||
214 | case ChatSourceType.Object: | 229 | case ChatSourceType.Object: |
@@ -222,38 +237,39 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
222 | message = message.Substring(0, 1000); | 237 | message = message.Substring(0, 1000); |
223 | 238 | ||
224 | // m_log.DebugFormat( | 239 | // m_log.DebugFormat( |
225 | // "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}, targetID {5}", | 240 | // "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}", |
226 | // fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType, targetID); | 241 | // fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType); |
227 | 242 | ||
228 | HashSet<UUID> receiverIDs = new HashSet<UUID>(); | 243 | HashSet<UUID> receiverIDs = new HashSet<UUID>(); |
229 | 244 | ||
230 | foreach (Scene s in m_scenes) | 245 | foreach (Scene s in m_scenes) |
231 | { | 246 | { |
232 | if (targetID == UUID.Zero) | 247 | // This should use ForEachClient, but clients don't have a position. |
233 | { | 248 | // If camera is moved into client, then camera position can be used |
234 | // This should use ForEachClient, but clients don't have a position. | 249 | // MT: No, it can't, as chat is heard from the avatar position, not |
235 | // If camera is moved into client, then camera position can be used | 250 | // the camera position. |
236 | s.ForEachRootScenePresence( | 251 | s.ForEachRootScenePresence( |
237 | delegate(ScenePresence presence) | 252 | delegate(ScenePresence presence) |
253 | { | ||
254 | if (destination != UUID.Zero && presence.UUID != destination) | ||
255 | return; | ||
256 | ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y); | ||
257 | if (Presencecheck != null) | ||
238 | { | 258 | { |
239 | if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType, false)) | 259 | // This will pass all chat from objects. Not |
240 | receiverIDs.Add(presence.UUID); | 260 | // perfect, but it will do. For now. Better |
261 | // than the prior behavior of muting all | ||
262 | // objects on a parcel with access restrictions | ||
263 | if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true) | ||
264 | { | ||
265 | if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix + fromName, c.Type, message, sourceType)) | ||
266 | receiverIDs.Add(presence.UUID); | ||
267 | } | ||
241 | } | 268 | } |
242 | ); | ||
243 | } | ||
244 | else | ||
245 | { | ||
246 | // This is a send to a specific client eg from llRegionSayTo | ||
247 | // no need to check distance etc, jand send is as say | ||
248 | ScenePresence presence = s.GetScenePresence(targetID); | ||
249 | if (presence != null && !presence.IsChildAgent) | ||
250 | { | ||
251 | if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, ChatTypeEnum.Say, message, sourceType, true)) | ||
252 | receiverIDs.Add(presence.UUID); | ||
253 | } | 269 | } |
254 | } | 270 | ); |
255 | } | 271 | } |
256 | 272 | ||
257 | (scene as Scene).EventManager.TriggerOnChatToClients( | 273 | (scene as Scene).EventManager.TriggerOnChatToClients( |
258 | fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully); | 274 | fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully); |
259 | } | 275 | } |
@@ -293,26 +309,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
293 | } | 309 | } |
294 | 310 | ||
295 | // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType); | 311 | // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType); |
296 | |||
297 | HashSet<UUID> receiverIDs = new HashSet<UUID>(); | 312 | HashSet<UUID> receiverIDs = new HashSet<UUID>(); |
298 | 313 | ||
299 | ((Scene)c.Scene).ForEachRootClient( | 314 | if (c.Scene != null) |
300 | delegate(IClientAPI client) | 315 | { |
301 | { | 316 | ((Scene)c.Scene).ForEachRootClient |
302 | // don't forward SayOwner chat from objects to | 317 | ( |
303 | // non-owner agents | 318 | delegate(IClientAPI client) |
304 | if ((c.Type == ChatTypeEnum.Owner) && | 319 | { |
305 | (null != c.SenderObject) && | 320 | // don't forward SayOwner chat from objects to |
306 | (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) | 321 | // non-owner agents |
307 | return; | 322 | if ((c.Type == ChatTypeEnum.Owner) && |
308 | 323 | (null != c.SenderObject) && | |
309 | client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, | 324 | (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) |
310 | (byte)sourceType, (byte)ChatAudibleLevel.Fully); | 325 | return; |
311 | receiverIDs.Add(client.AgentId); | 326 | |
312 | }); | 327 | client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, |
313 | 328 | (byte)sourceType, (byte)ChatAudibleLevel.Fully); | |
314 | (c.Scene as Scene).EventManager.TriggerOnChatToClients( | 329 | receiverIDs.Add(client.AgentId); |
315 | fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully); | 330 | } |
331 | ); | ||
332 | (c.Scene as Scene).EventManager.TriggerOnChatToClients( | ||
333 | fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully); | ||
334 | } | ||
316 | } | 335 | } |
317 | 336 | ||
318 | /// <summary> | 337 | /// <summary> |
@@ -330,9 +349,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
330 | /// precondition</returns> | 349 | /// precondition</returns> |
331 | protected virtual bool TrySendChatMessage(ScenePresence presence, Vector3 fromPos, Vector3 regionPos, | 350 | protected virtual bool TrySendChatMessage(ScenePresence presence, Vector3 fromPos, Vector3 regionPos, |
332 | UUID fromAgentID, string fromName, ChatTypeEnum type, | 351 | UUID fromAgentID, string fromName, ChatTypeEnum type, |
333 | string message, ChatSourceType src, bool ignoreDistance) | 352 | string message, ChatSourceType src) |
334 | { | 353 | { |
335 | // don't send stuff to child agents | 354 | // don't send chat to child agents |
336 | if (presence.IsChildAgent) return false; | 355 | if (presence.IsChildAgent) return false; |
337 | 356 | ||
338 | Vector3 fromRegionPos = fromPos + regionPos; | 357 | Vector3 fromRegionPos = fromPos + regionPos; |
@@ -341,15 +360,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
341 | presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); | 360 | presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); |
342 | 361 | ||
343 | int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); | 362 | int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); |
344 | 363 | ||
345 | if (!ignoreDistance) | 364 | if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || |
365 | type == ChatTypeEnum.Say && dis > m_saydistance || | ||
366 | type == ChatTypeEnum.Shout && dis > m_shoutdistance) | ||
346 | { | 367 | { |
347 | if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || | 368 | return false; |
348 | type == ChatTypeEnum.Say && dis > m_saydistance || | ||
349 | type == ChatTypeEnum.Shout && dis > m_shoutdistance) | ||
350 | { | ||
351 | return false; | ||
352 | } | ||
353 | } | 369 | } |
354 | 370 | ||
355 | // TODO: should change so the message is sent through the avatar rather than direct to the ClientView | 371 | // TODO: should change so the message is sent through the avatar rather than direct to the ClientView |
@@ -358,5 +374,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
358 | 374 | ||
359 | return true; | 375 | return true; |
360 | } | 376 | } |
377 | |||
378 | Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>(); | ||
379 | public void ParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) | ||
380 | { | ||
381 | System.Threading.Timer Timer; | ||
382 | if (flags == 0) | ||
383 | { | ||
384 | FreezeCache.Add(target.ToString()); | ||
385 | System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen); | ||
386 | Timer = new System.Threading.Timer(timeCB, target, 30000, 0); | ||
387 | Timers.Add(target, Timer); | ||
388 | } | ||
389 | else | ||
390 | { | ||
391 | FreezeCache.Remove(target.ToString()); | ||
392 | Timers.TryGetValue(target, out Timer); | ||
393 | Timers.Remove(target); | ||
394 | Timer.Dispose(); | ||
395 | } | ||
396 | } | ||
397 | |||
398 | private void OnEndParcelFrozen(object avatar) | ||
399 | { | ||
400 | UUID target = (UUID)avatar; | ||
401 | FreezeCache.Remove(target.ToString()); | ||
402 | System.Threading.Timer Timer; | ||
403 | Timers.TryGetValue(target, out Timer); | ||
404 | Timers.Remove(target); | ||
405 | Timer.Dispose(); | ||
406 | } | ||
361 | } | 407 | } |
362 | } | 408 | } |