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