aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs191
1 files changed, 133 insertions, 58 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index 27ace68..5cbfec6 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -51,7 +51,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
51 private int m_saydistance = 20; 51 private int m_saydistance = 20;
52 private int m_shoutdistance = 100; 52 private int m_shoutdistance = 100;
53 private int m_whisperdistance = 10; 53 private int m_whisperdistance = 10;
54 54 private List<Scene> m_scenes = new List<Scene>();
55 private List<string> FreezeCache = new List<string>();
56 private string m_adminPrefix = "";
55 internal object m_syncy = new object(); 57 internal object m_syncy = new object();
56 58
57 internal IConfig m_config; 59 internal IConfig m_config;
@@ -78,16 +80,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
78 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); 80 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance);
79 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); 81 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance);
80 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); 82 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance);
83 m_adminPrefix = config.Configs["Chat"].GetString("admin_prefix", "");
81 } 84 }
82 85
83 public virtual void AddRegion(Scene scene) 86 public virtual void AddRegion(Scene scene)
84 { 87 {
85 if (!m_enabled) 88 if (!m_enabled) return;
86 return;
87 89
88 scene.EventManager.OnNewClient += OnNewClient; 90 lock (m_syncy)
89 scene.EventManager.OnChatFromWorld += OnChatFromWorld; 91 {
90 scene.EventManager.OnChatBroadcast += OnChatBroadcast; 92 if (!m_scenes.Contains(scene))
93 {
94 m_scenes.Add(scene);
95 scene.EventManager.OnNewClient += OnNewClient;
96 scene.EventManager.OnChatFromWorld += OnChatFromWorld;
97 scene.EventManager.OnChatBroadcast += OnChatBroadcast;
98 }
99 }
91 100
92 m_log.InfoFormat("[CHAT]: Initialized for {0} w:{1} s:{2} S:{3}", scene.RegionInfo.RegionName, 101 m_log.InfoFormat("[CHAT]: Initialized for {0} w:{1} s:{2} S:{3}", scene.RegionInfo.RegionName,
93 m_whisperdistance, m_saydistance, m_shoutdistance); 102 m_whisperdistance, m_saydistance, m_shoutdistance);
@@ -107,12 +116,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
107 116
108 public virtual void RemoveRegion(Scene scene) 117 public virtual void RemoveRegion(Scene scene)
109 { 118 {
110 if (!m_enabled) 119 if (!m_enabled) return;
111 return;
112 120
113 scene.EventManager.OnNewClient -= OnNewClient; 121 lock (m_syncy)
114 scene.EventManager.OnChatFromWorld -= OnChatFromWorld; 122 {
115 scene.EventManager.OnChatBroadcast -= OnChatBroadcast; 123 if (m_scenes.Contains(scene))
124 {
125 scene.EventManager.OnNewClient -= OnNewClient;
126 scene.EventManager.OnChatFromWorld -= OnChatFromWorld;
127 scene.EventManager.OnChatBroadcast -= OnChatBroadcast;
128 m_scenes.Remove(scene);
129 }
130 }
116 } 131 }
117 132
118 public virtual void Close() 133 public virtual void Close()
@@ -169,7 +184,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
169 return; 184 return;
170 } 185 }
171 186
172 DeliverChatToAvatars(ChatSourceType.Agent, c); 187 if (FreezeCache.Contains(c.Sender.AgentId.ToString()))
188 {
189 if (c.Type != ChatTypeEnum.StartTyping || c.Type != ChatTypeEnum.StopTyping)
190 c.Sender.SendAgentAlertMessage("You may not talk as you are frozen.", false);
191 }
192 else
193 {
194 DeliverChatToAvatars(ChatSourceType.Agent, c);
195 }
173 } 196 }
174 197
175 public virtual void OnChatFromWorld(Object sender, OSChatMessage c) 198 public virtual void OnChatFromWorld(Object sender, OSChatMessage c)
@@ -183,11 +206,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
183 protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c) 206 protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c)
184 { 207 {
185 string fromName = c.From; 208 string fromName = c.From;
209 string fromNamePrefix = "";
186 UUID fromID = UUID.Zero; 210 UUID fromID = UUID.Zero;
187 UUID ownerID = UUID.Zero; 211 UUID ownerID = UUID.Zero;
188 UUID targetID = c.TargetUUID;
189 string message = c.Message; 212 string message = c.Message;
190 Scene scene = (Scene)c.Scene; 213 IScene scene = c.Scene;
214 UUID destination = c.Destination;
191 Vector3 fromPos = c.Position; 215 Vector3 fromPos = c.Position;
192 Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, 216 Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize,
193 scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 217 scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
@@ -197,10 +221,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
197 switch (sourceType) 221 switch (sourceType)
198 { 222 {
199 case ChatSourceType.Agent: 223 case ChatSourceType.Agent:
200 ScenePresence avatar = scene.GetScenePresence(c.Sender.AgentId); 224 if (!(scene is Scene))
225 {
226 m_log.WarnFormat("[CHAT]: scene {0} is not a Scene object, cannot obtain scene presence for {1}",
227 scene.RegionInfo.RegionName, c.Sender.AgentId);
228 return;
229 }
230 ScenePresence avatar = (scene as Scene).GetScenePresence(c.Sender.AgentId);
201 fromPos = avatar.AbsolutePosition; 231 fromPos = avatar.AbsolutePosition;
202 fromName = avatar.Name; 232 fromName = avatar.Name;
203 fromID = c.Sender.AgentId; 233 fromID = c.Sender.AgentId;
234 if (avatar.GodLevel >= 200)
235 {
236 fromNamePrefix = m_adminPrefix;
237 }
238 destination = UUID.Zero; // Avatars cant "SayTo"
204 ownerID = c.Sender.AgentId; 239 ownerID = c.Sender.AgentId;
205 240
206 break; 241 break;
@@ -219,38 +254,48 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
219 message = message.Substring(0, 1000); 254 message = message.Substring(0, 1000);
220 255
221// m_log.DebugFormat( 256// m_log.DebugFormat(
222// "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}, targetID {5}", 257// "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}",
223// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType, targetID); 258// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType);
224 259
225 HashSet<UUID> receiverIDs = new HashSet<UUID>(); 260 HashSet<UUID> receiverIDs = new HashSet<UUID>();
226 261
227 if (targetID == UUID.Zero) 262 foreach (Scene s in m_scenes)
228 { 263 {
229 // This should use ForEachClient, but clients don't have a position. 264 // This should use ForEachClient, but clients don't have a position.
230 // If camera is moved into client, then camera position can be used 265 // If camera is moved into client, then camera position can be used
231 scene.ForEachScenePresence( 266 // MT: No, it can't, as chat is heard from the avatar position, not
267 // the camera position.
268 s.ForEachScenePresence(
232 delegate(ScenePresence presence) 269 delegate(ScenePresence presence)
233 { 270 {
234 if (TrySendChatMessage( 271 if (destination != UUID.Zero && presence.UUID != destination)
235 presence, fromPos, regionPos, fromID, ownerID, fromName, c.Type, message, sourceType, false)) 272 return;
236 receiverIDs.Add(presence.UUID); 273 ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
274 if (Presencecheck != null)
275 {
276 // This will pass all chat from objects. Not
277 // perfect, but it will do. For now. Better
278 // than the prior behavior of muting all
279 // objects on a parcel with access restrictions
280 if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true)
281 {
282 if (destination != UUID.Zero)
283 {
284 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, ownerID, fromNamePrefix + fromName, c.Type, message, sourceType, true))
285 receiverIDs.Add(presence.UUID);
286 }
287 else
288 {
289 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, ownerID, fromNamePrefix + fromName, c.Type, message, sourceType, false))
290 receiverIDs.Add(presence.UUID);
291 }
292 }
293 }
237 } 294 }
238 ); 295 );
239 } 296 }
240 else 297
241 { 298 (scene as Scene).EventManager.TriggerOnChatToClients(
242 // This is a send to a specific client eg from llRegionSayTo
243 // no need to check distance etc, jand send is as say
244 ScenePresence presence = scene.GetScenePresence(targetID);
245 if (presence != null && !presence.IsChildAgent)
246 {
247 if (TrySendChatMessage(
248 presence, fromPos, regionPos, fromID, ownerID, fromName, ChatTypeEnum.Say, message, sourceType, true))
249 receiverIDs.Add(presence.UUID);
250 }
251 }
252
253 scene.EventManager.TriggerOnChatToClients(
254 fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully); 299 fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully);
255 } 300 }
256 301
@@ -289,28 +334,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
289 } 334 }
290 335
291 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType); 336 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType);
292
293 HashSet<UUID> receiverIDs = new HashSet<UUID>(); 337 HashSet<UUID> receiverIDs = new HashSet<UUID>();
294 338
295 ((Scene)c.Scene).ForEachRootClient( 339 if (c.Scene != null)
296 delegate(IClientAPI client) 340 {
297 { 341 ((Scene)c.Scene).ForEachRootClient
298 // don't forward SayOwner chat from objects to 342 (
299 // non-owner agents 343 delegate(IClientAPI client)
300 if ((c.Type == ChatTypeEnum.Owner) && 344 {
301 (null != c.SenderObject) && 345 // don't forward SayOwner chat from objects to
302 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) 346 // non-owner agents
303 return; 347 if ((c.Type == ChatTypeEnum.Owner) &&
304 348 (null != c.SenderObject) &&
305 client.SendChatMessage( 349 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
306 c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID, 350 return;
307 (byte)sourceType, (byte)ChatAudibleLevel.Fully); 351
308 352 client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID,
309 receiverIDs.Add(client.AgentId); 353 (byte)sourceType, (byte)ChatAudibleLevel.Fully);
310 }); 354 receiverIDs.Add(client.AgentId);
311 355 }
312 (c.Scene as Scene).EventManager.TriggerOnChatToClients( 356 );
313 fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully); 357 (c.Scene as Scene).EventManager.TriggerOnChatToClients(
358 fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully);
359 }
314 } 360 }
315 361
316 /// <summary> 362 /// <summary>
@@ -363,6 +409,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
363 return true; 409 return true;
364 } 410 }
365 411
412 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
413 public void ParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
414 {
415 System.Threading.Timer Timer;
416 if (flags == 0)
417 {
418 FreezeCache.Add(target.ToString());
419 System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen);
420 Timer = new System.Threading.Timer(timeCB, target, 30000, 0);
421 Timers.Add(target, Timer);
422 }
423 else
424 {
425 FreezeCache.Remove(target.ToString());
426 Timers.TryGetValue(target, out Timer);
427 Timers.Remove(target);
428 Timer.Dispose();
429 }
430 }
431
432 private void OnEndParcelFrozen(object avatar)
433 {
434 UUID target = (UUID)avatar;
435 FreezeCache.Remove(target.ToString());
436 System.Threading.Timer Timer;
437 Timers.TryGetValue(target, out Timer);
438 Timers.Remove(target);
439 Timer.Dispose();
440 }
366 #region SimulatorFeaturesRequest 441 #region SimulatorFeaturesRequest
367 442
368 static OSDInteger m_SayRange, m_WhisperRange, m_ShoutRange; 443 static OSDInteger m_SayRange, m_WhisperRange, m_ShoutRange;
@@ -391,4 +466,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
391 466
392 #endregion 467 #endregion
393 } 468 }
394} \ No newline at end of file 469}