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 ddf92c3..4407e40 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,11 +195,12 @@ 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 ownerID = UUID.Zero; | 200 | UUID ownerID = UUID.Zero; |
190 | UUID targetID = c.TargetUUID; | ||
191 | string message = c.Message; | 201 | string message = c.Message; |
192 | IScene scene = c.Scene; | 202 | IScene scene = c.Scene; |
203 | UUID destination = c.Destination; | ||
193 | Vector3 fromPos = c.Position; | 204 | Vector3 fromPos = c.Position; |
194 | Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, | 205 | Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, |
195 | scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); | 206 | scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); |
@@ -209,6 +220,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
209 | fromPos = avatar.AbsolutePosition; | 220 | fromPos = avatar.AbsolutePosition; |
210 | fromName = avatar.Name; | 221 | fromName = avatar.Name; |
211 | fromID = c.Sender.AgentId; | 222 | fromID = c.Sender.AgentId; |
223 | if (avatar.GodLevel >= 200) | ||
224 | { | ||
225 | fromNamePrefix = m_adminPrefix; | ||
226 | } | ||
227 | destination = UUID.Zero; // Avatars cant "SayTo" | ||
212 | ownerID = c.Sender.AgentId; | 228 | ownerID = c.Sender.AgentId; |
213 | 229 | ||
214 | break; | 230 | break; |
@@ -227,40 +243,47 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
227 | message = message.Substring(0, 1000); | 243 | message = message.Substring(0, 1000); |
228 | 244 | ||
229 | // m_log.DebugFormat( | 245 | // m_log.DebugFormat( |
230 | // "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}, targetID {5}", | 246 | // "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}", |
231 | // fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType, targetID); | 247 | // fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType); |
232 | 248 | ||
233 | HashSet<UUID> receiverIDs = new HashSet<UUID>(); | 249 | HashSet<UUID> receiverIDs = new HashSet<UUID>(); |
234 | 250 | ||
235 | foreach (Scene s in m_scenes) | 251 | foreach (Scene s in m_scenes) |
236 | { | 252 | { |
237 | if (targetID == UUID.Zero) | 253 | // This should use ForEachClient, but clients don't have a position. |
238 | { | 254 | // If camera is moved into client, then camera position can be used |
239 | // This should use ForEachClient, but clients don't have a position. | 255 | // MT: No, it can't, as chat is heard from the avatar position, not |
240 | // If camera is moved into client, then camera position can be used | 256 | // the camera position. |
241 | s.ForEachRootScenePresence( | 257 | s.ForEachRootScenePresence( |
242 | delegate(ScenePresence presence) | 258 | delegate(ScenePresence presence) |
259 | { | ||
260 | if (destination != UUID.Zero && presence.UUID != destination) | ||
261 | return; | ||
262 | ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y); | ||
263 | if (Presencecheck != null) | ||
243 | { | 264 | { |
244 | if (TrySendChatMessage( | 265 | // This will pass all chat from objects. Not |
245 | presence, fromPos, regionPos, fromID, ownerID, fromName, c.Type, message, sourceType, false)) | 266 | // perfect, but it will do. For now. Better |
246 | receiverIDs.Add(presence.UUID); | 267 | // than the prior behavior of muting all |
268 | // objects on a parcel with access restrictions | ||
269 | if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true) | ||
270 | { | ||
271 | if (destination != UUID.Zero) | ||
272 | { | ||
273 | if (TrySendChatMessage(presence, fromPos, regionPos, fromID, ownerID, fromNamePrefix + fromName, c.Type, message, sourceType, true)) | ||
274 | receiverIDs.Add(presence.UUID); | ||
275 | } | ||
276 | else | ||
277 | { | ||
278 | if (TrySendChatMessage(presence, fromPos, regionPos, fromID, ownerID, fromNamePrefix + fromName, c.Type, message, sourceType, false)) | ||
279 | receiverIDs.Add(presence.UUID); | ||
280 | } | ||
281 | } | ||
247 | } | 282 | } |
248 | ); | ||
249 | } | ||
250 | else | ||
251 | { | ||
252 | // This is a send to a specific client eg from llRegionSayTo | ||
253 | // no need to check distance etc, jand send is as say | ||
254 | ScenePresence presence = s.GetScenePresence(targetID); | ||
255 | if (presence != null && !presence.IsChildAgent) | ||
256 | { | ||
257 | if (TrySendChatMessage( | ||
258 | presence, fromPos, regionPos, fromID, ownerID, fromName, ChatTypeEnum.Say, message, sourceType, true)) | ||
259 | receiverIDs.Add(presence.UUID); | ||
260 | } | 283 | } |
261 | } | 284 | ); |
262 | } | 285 | } |
263 | 286 | ||
264 | (scene as Scene).EventManager.TriggerOnChatToClients( | 287 | (scene as Scene).EventManager.TriggerOnChatToClients( |
265 | fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully); | 288 | fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully); |
266 | } | 289 | } |
@@ -300,28 +323,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
300 | } | 323 | } |
301 | 324 | ||
302 | // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType); | 325 | // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType); |
303 | |||
304 | HashSet<UUID> receiverIDs = new HashSet<UUID>(); | 326 | HashSet<UUID> receiverIDs = new HashSet<UUID>(); |
305 | 327 | ||
306 | ((Scene)c.Scene).ForEachRootClient( | 328 | if (c.Scene != null) |
307 | delegate(IClientAPI client) | 329 | { |
308 | { | 330 | ((Scene)c.Scene).ForEachRootClient |
309 | // don't forward SayOwner chat from objects to | 331 | ( |
310 | // non-owner agents | 332 | delegate(IClientAPI client) |
311 | if ((c.Type == ChatTypeEnum.Owner) && | 333 | { |
312 | (null != c.SenderObject) && | 334 | // don't forward SayOwner chat from objects to |
313 | (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) | 335 | // non-owner agents |
314 | return; | 336 | if ((c.Type == ChatTypeEnum.Owner) && |
315 | 337 | (null != c.SenderObject) && | |
316 | client.SendChatMessage( | 338 | (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) |
317 | c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID, | 339 | return; |
318 | (byte)sourceType, (byte)ChatAudibleLevel.Fully); | 340 | |
319 | 341 | client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID, | |
320 | receiverIDs.Add(client.AgentId); | 342 | (byte)sourceType, (byte)ChatAudibleLevel.Fully); |
321 | }); | 343 | receiverIDs.Add(client.AgentId); |
322 | 344 | } | |
323 | (c.Scene as Scene).EventManager.TriggerOnChatToClients( | 345 | ); |
324 | fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully); | 346 | (c.Scene as Scene).EventManager.TriggerOnChatToClients( |
347 | fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully); | ||
348 | } | ||
325 | } | 349 | } |
326 | 350 | ||
327 | /// <summary> | 351 | /// <summary> |
@@ -346,7 +370,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
346 | UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type, | 370 | UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type, |
347 | string message, ChatSourceType src, bool ignoreDistance) | 371 | string message, ChatSourceType src, bool ignoreDistance) |
348 | { | 372 | { |
349 | // don't send stuff to child agents | 373 | // don't send chat to child agents |
350 | if (presence.IsChildAgent) return false; | 374 | if (presence.IsChildAgent) return false; |
351 | 375 | ||
352 | Vector3 fromRegionPos = fromPos + regionPos; | 376 | Vector3 fromRegionPos = fromPos + regionPos; |
@@ -355,15 +379,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
355 | presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); | 379 | presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); |
356 | 380 | ||
357 | int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); | 381 | int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); |
358 | 382 | ||
359 | if (!ignoreDistance) | 383 | if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || |
384 | type == ChatTypeEnum.Say && dis > m_saydistance || | ||
385 | type == ChatTypeEnum.Shout && dis > m_shoutdistance) | ||
360 | { | 386 | { |
361 | if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || | 387 | return false; |
362 | type == ChatTypeEnum.Say && dis > m_saydistance || | ||
363 | type == ChatTypeEnum.Shout && dis > m_shoutdistance) | ||
364 | { | ||
365 | return false; | ||
366 | } | ||
367 | } | 388 | } |
368 | 389 | ||
369 | // TODO: should change so the message is sent through the avatar rather than direct to the ClientView | 390 | // TODO: should change so the message is sent through the avatar rather than direct to the ClientView |
@@ -373,5 +394,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
373 | 394 | ||
374 | return true; | 395 | return true; |
375 | } | 396 | } |
397 | |||
398 | Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>(); | ||
399 | public void ParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) | ||
400 | { | ||
401 | System.Threading.Timer Timer; | ||
402 | if (flags == 0) | ||
403 | { | ||
404 | FreezeCache.Add(target.ToString()); | ||
405 | System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen); | ||
406 | Timer = new System.Threading.Timer(timeCB, target, 30000, 0); | ||
407 | Timers.Add(target, Timer); | ||
408 | } | ||
409 | else | ||
410 | { | ||
411 | FreezeCache.Remove(target.ToString()); | ||
412 | Timers.TryGetValue(target, out Timer); | ||
413 | Timers.Remove(target); | ||
414 | Timer.Dispose(); | ||
415 | } | ||
416 | } | ||
417 | |||
418 | private void OnEndParcelFrozen(object avatar) | ||
419 | { | ||
420 | UUID target = (UUID)avatar; | ||
421 | FreezeCache.Remove(target.ToString()); | ||
422 | System.Threading.Timer Timer; | ||
423 | Timers.TryGetValue(target, out Timer); | ||
424 | Timers.Remove(target); | ||
425 | Timer.Dispose(); | ||
426 | } | ||
376 | } | 427 | } |
377 | } \ No newline at end of file | 428 | } |