aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Chat
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Chat')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs169
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}