aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Chat
diff options
context:
space:
mode:
authorDavid Walter Seikel2016-11-03 21:44:39 +1000
committerDavid Walter Seikel2016-11-03 21:44:39 +1000
commit134f86e8d5c414409631b25b8c6f0ee45fbd8631 (patch)
tree216b89d3fb89acfb81be1e440c25c41ab09fa96d /OpenSim/Region/CoreModules/Avatar/Chat
parentMore changing to production grid. Double oops. (diff)
downloadopensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.zip
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.gz
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.bz2
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.xz
Initial update to OpenSim 0.8.2.1 source code.
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Chat')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs168
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs285
2 files changed, 375 insertions, 78 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index 6d62ff0..f0b1e67 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -32,6 +32,7 @@ using log4net;
32using Nini.Config; 32using Nini.Config;
33using Mono.Addins; 33using Mono.Addins;
34using OpenMetaverse; 34using OpenMetaverse;
35using OpenMetaverse.StructuredData;
35using OpenSim.Framework; 36using OpenSim.Framework;
36using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 38using OpenSim.Region.Framework.Scenes;
@@ -50,7 +51,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
50 private int m_saydistance = 20; 51 private int m_saydistance = 20;
51 private int m_shoutdistance = 100; 52 private int m_shoutdistance = 100;
52 private int m_whisperdistance = 10; 53 private int m_whisperdistance = 10;
53 private List<Scene> m_scenes = new List<Scene>();
54 54
55 internal object m_syncy = new object(); 55 internal object m_syncy = new object();
56 56
@@ -61,18 +61,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
61 { 61 {
62 m_config = config.Configs["Chat"]; 62 m_config = config.Configs["Chat"];
63 63
64 if (null == m_config) 64 if (m_config != null)
65 { 65 {
66 m_log.Info("[CHAT]: no config found, plugin disabled"); 66 if (!m_config.GetBoolean("enabled", true))
67 m_enabled = false; 67 {
68 return; 68 m_log.Info("[CHAT]: plugin disabled by configuration");
69 } 69 m_enabled = false;
70 70 return;
71 if (!m_config.GetBoolean("enabled", true)) 71 }
72 {
73 m_log.Info("[CHAT]: plugin disabled by configuration");
74 m_enabled = false;
75 return;
76 } 72 }
77 73
78 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); 74 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance);
@@ -82,18 +78,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
82 78
83 public virtual void AddRegion(Scene scene) 79 public virtual void AddRegion(Scene scene)
84 { 80 {
85 if (!m_enabled) return; 81 if (!m_enabled)
82 return;
86 83
87 lock (m_syncy) 84 scene.EventManager.OnNewClient += OnNewClient;
88 { 85 scene.EventManager.OnChatFromWorld += OnChatFromWorld;
89 if (!m_scenes.Contains(scene)) 86 scene.EventManager.OnChatBroadcast += OnChatBroadcast;
90 {
91 m_scenes.Add(scene);
92 scene.EventManager.OnNewClient += OnNewClient;
93 scene.EventManager.OnChatFromWorld += OnChatFromWorld;
94 scene.EventManager.OnChatBroadcast += OnChatBroadcast;
95 }
96 }
97 87
98 m_log.InfoFormat("[CHAT]: Initialized for {0} w:{1} s:{2} S:{3}", scene.RegionInfo.RegionName, 88 m_log.InfoFormat("[CHAT]: Initialized for {0} w:{1} s:{2} S:{3}", scene.RegionInfo.RegionName,
99 m_whisperdistance, m_saydistance, m_shoutdistance); 89 m_whisperdistance, m_saydistance, m_shoutdistance);
@@ -101,22 +91,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
101 91
102 public virtual void RegionLoaded(Scene scene) 92 public virtual void RegionLoaded(Scene scene)
103 { 93 {
94 if (!m_enabled)
95 return;
96
97 ISimulatorFeaturesModule featuresModule = scene.RequestModuleInterface<ISimulatorFeaturesModule>();
98
99 if (featuresModule != null)
100 featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest;
101
104 } 102 }
105 103
106 public virtual void RemoveRegion(Scene scene) 104 public virtual void RemoveRegion(Scene scene)
107 { 105 {
108 if (!m_enabled) return; 106 if (!m_enabled)
107 return;
109 108
110 lock (m_syncy) 109 scene.EventManager.OnNewClient -= OnNewClient;
111 { 110 scene.EventManager.OnChatFromWorld -= OnChatFromWorld;
112 if (m_scenes.Contains(scene)) 111 scene.EventManager.OnChatBroadcast -= OnChatBroadcast;
113 {
114 scene.EventManager.OnNewClient -= OnNewClient;
115 scene.EventManager.OnChatFromWorld -= OnChatFromWorld;
116 scene.EventManager.OnChatBroadcast -= OnChatBroadcast;
117 m_scenes.Remove(scene);
118 }
119 }
120 } 112 }
121 113
122 public virtual void Close() 114 public virtual void Close()
@@ -191,23 +183,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
191 UUID ownerID = UUID.Zero; 183 UUID ownerID = UUID.Zero;
192 UUID targetID = c.TargetUUID; 184 UUID targetID = c.TargetUUID;
193 string message = c.Message; 185 string message = c.Message;
194 IScene scene = c.Scene; 186 Scene scene = (Scene)c.Scene;
195 Vector3 fromPos = c.Position; 187 Vector3 fromPos = c.Position;
196 Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, 188 Vector3 regionPos = new Vector3(scene.RegionInfo.WorldLocX, scene.RegionInfo.WorldLocY, 0);
197 scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
198 189
199 if (c.Channel == DEBUG_CHANNEL) c.Type = ChatTypeEnum.DebugChannel; 190 if (c.Channel == DEBUG_CHANNEL) c.Type = ChatTypeEnum.DebugChannel;
200 191
201 switch (sourceType) 192 switch (sourceType)
202 { 193 {
203 case ChatSourceType.Agent: 194 case ChatSourceType.Agent:
204 if (!(scene is Scene)) 195 ScenePresence avatar = scene.GetScenePresence(c.Sender.AgentId);
205 {
206 m_log.WarnFormat("[CHAT]: scene {0} is not a Scene object, cannot obtain scene presence for {1}",
207 scene.RegionInfo.RegionName, c.Sender.AgentId);
208 return;
209 }
210 ScenePresence avatar = (scene as Scene).GetScenePresence(c.Sender.AgentId);
211 fromPos = avatar.AbsolutePosition; 196 fromPos = avatar.AbsolutePosition;
212 fromName = avatar.Name; 197 fromName = avatar.Name;
213 fromID = c.Sender.AgentId; 198 fromID = c.Sender.AgentId;
@@ -234,36 +219,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
234 219
235 HashSet<UUID> receiverIDs = new HashSet<UUID>(); 220 HashSet<UUID> receiverIDs = new HashSet<UUID>();
236 221
237 foreach (Scene s in m_scenes) 222 if (targetID == UUID.Zero)
238 { 223 {
239 if (targetID == UUID.Zero) 224 // This should use ForEachClient, but clients don't have a position.
240 { 225 // If camera is moved into client, then camera position can be used
241 // This should use ForEachClient, but clients don't have a position. 226 scene.ForEachScenePresence(
242 // If camera is moved into client, then camera position can be used 227 delegate(ScenePresence presence)
243 s.ForEachRootScenePresence(
244 delegate(ScenePresence presence)
245 {
246 if (TrySendChatMessage(
247 presence, fromPos, regionPos, fromID, ownerID, fromName, c.Type, message, sourceType, false))
248 receiverIDs.Add(presence.UUID);
249 }
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 { 228 {
259 if (TrySendChatMessage( 229 if (TrySendChatMessage(
260 presence, fromPos, regionPos, fromID, ownerID, fromName, ChatTypeEnum.Say, message, sourceType, true)) 230 presence, fromPos, regionPos, fromID, ownerID, fromName, c.Type, message, sourceType, false))
261 receiverIDs.Add(presence.UUID); 231 receiverIDs.Add(presence.UUID);
262 } 232 }
233 );
234 }
235 else
236 {
237 // This is a send to a specific client eg from llRegionSayTo
238 // no need to check distance etc, jand send is as say
239 ScenePresence presence = scene.GetScenePresence(targetID);
240 if (presence != null && !presence.IsChildAgent)
241 {
242 if (TrySendChatMessage(
243 presence, fromPos, regionPos, fromID, ownerID, fromName, ChatTypeEnum.Say, message, sourceType, true))
244 receiverIDs.Add(presence.UUID);
263 } 245 }
264 } 246 }
265 247
266 (scene as Scene).EventManager.TriggerOnChatToClients( 248 scene.EventManager.TriggerOnChatToClients(
267 fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully); 249 fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully);
268 } 250 }
269 251
@@ -288,17 +270,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
288 string fromName = c.From; 270 string fromName = c.From;
289 271
290 UUID fromID = UUID.Zero; 272 UUID fromID = UUID.Zero;
273 UUID ownerID = UUID.Zero;
291 ChatSourceType sourceType = ChatSourceType.Object; 274 ChatSourceType sourceType = ChatSourceType.Object;
292 if (null != c.Sender) 275 if (null != c.Sender)
293 { 276 {
294 ScenePresence avatar = (c.Scene as Scene).GetScenePresence(c.Sender.AgentId); 277 ScenePresence avatar = (c.Scene as Scene).GetScenePresence(c.Sender.AgentId);
295 fromID = c.Sender.AgentId; 278 fromID = c.Sender.AgentId;
296 fromName = avatar.Name; 279 fromName = avatar.Name;
280 ownerID = c.Sender.AgentId;
297 sourceType = ChatSourceType.Agent; 281 sourceType = ChatSourceType.Agent;
298 } 282 }
299 else if (c.SenderUUID != UUID.Zero) 283 else if (c.SenderUUID != UUID.Zero)
300 { 284 {
301 fromID = c.SenderUUID; 285 fromID = c.SenderUUID;
286 ownerID = ((SceneObjectPart)c.SenderObject).OwnerID;
302 } 287 }
303 288
304 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType); 289 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType);
@@ -316,7 +301,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
316 return; 301 return;
317 302
318 client.SendChatMessage( 303 client.SendChatMessage(
319 c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID, 304 c.Message, (byte)cType, CenterOfRegion, fromName, fromID, ownerID,
320 (byte)sourceType, (byte)ChatAudibleLevel.Fully); 305 (byte)sourceType, (byte)ChatAudibleLevel.Fully);
321 306
322 receiverIDs.Add(client.AgentId); 307 receiverIDs.Add(client.AgentId);
@@ -348,18 +333,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
348 UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type, 333 UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type,
349 string message, ChatSourceType src, bool ignoreDistance) 334 string message, ChatSourceType src, bool ignoreDistance)
350 { 335 {
351 // don't send stuff to child agents 336 if (presence.LifecycleState != ScenePresenceState.Running)
352 if (presence.IsChildAgent) return false; 337 return false;
353
354 Vector3 fromRegionPos = fromPos + regionPos;
355 Vector3 toRegionPos = presence.AbsolutePosition +
356 new Vector3(presence.Scene.RegionInfo.RegionLocX * Constants.RegionSize,
357 presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
358
359 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos);
360 338
361 if (!ignoreDistance) 339 if (!ignoreDistance)
362 { 340 {
341 Vector3 fromRegionPos = fromPos + regionPos;
342 Vector3 toRegionPos = presence.AbsolutePosition +
343 new Vector3(presence.Scene.RegionInfo.WorldLocX, presence.Scene.RegionInfo.WorldLocY, 0);
344
345 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos);
346
363 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || 347 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance ||
364 type == ChatTypeEnum.Say && dis > m_saydistance || 348 type == ChatTypeEnum.Say && dis > m_saydistance ||
365 type == ChatTypeEnum.Shout && dis > m_shoutdistance) 349 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
@@ -375,5 +359,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
375 359
376 return true; 360 return true;
377 } 361 }
362
363 #region SimulatorFeaturesRequest
364
365 static OSDInteger m_SayRange, m_WhisperRange, m_ShoutRange;
366
367 private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features)
368 {
369 OSD extras = new OSDMap();
370 if (features.ContainsKey("OpenSimExtras"))
371 extras = features["OpenSimExtras"];
372 else
373 features["OpenSimExtras"] = extras;
374
375 if (m_SayRange == null)
376 {
377 // Do this only once
378 m_SayRange = new OSDInteger(m_saydistance);
379 m_WhisperRange = new OSDInteger(m_whisperdistance);
380 m_ShoutRange = new OSDInteger(m_shoutdistance);
381 }
382
383 ((OSDMap)extras)["say-range"] = m_SayRange;
384 ((OSDMap)extras)["whisper-range"] = m_WhisperRange;
385 ((OSDMap)extras)["shout-range"] = m_ShoutRange;
386
387 }
388
389 #endregion
378 } 390 }
379} \ No newline at end of file 391}
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs
new file mode 100644
index 0000000..3018d94
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs
@@ -0,0 +1,285 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using log4net.Config;
31using Nini.Config;
32using NUnit.Framework;
33using OpenMetaverse;
34using OpenSim.Framework;
35using OpenSim.Framework.Servers;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Region.CoreModules.Avatar.Chat;
38using OpenSim.Region.CoreModules.Framework;
39using OpenSim.Region.CoreModules.Framework.EntityTransfer;
40using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Services.Interfaces;
43using OpenSim.Tests.Common;
44
45namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests
46{
47 [TestFixture]
48 public class ChatModuleTests : OpenSimTestCase
49 {
50 [TestFixtureSetUp]
51 public void FixtureInit()
52 {
53 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
54 // We must do this here so that child agent positions are updated in a predictable manner.
55 Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
56 }
57
58 [TestFixtureTearDown]
59 public void TearDown()
60 {
61 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
62 // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
63 // tests really shouldn't).
64 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
65 }
66
67 private void SetupNeighbourRegions(TestScene sceneA, TestScene sceneB)
68 {
69 // XXX: HTTP server is not (and should not be) necessary for this test, though it's absence makes the
70 // CapabilitiesModule complain when it can't set up HTTP endpoints.
71 // BaseHttpServer httpServer = new BaseHttpServer(99999);
72 // MainServer.AddHttpServer(httpServer);
73 // MainServer.Instance = httpServer;
74
75 // We need entity transfer modules so that when sp2 logs into the east region, the region calls
76 // EntityTransferModuleto set up a child agent on the west region.
77 // XXX: However, this is not an entity transfer so is misleading.
78 EntityTransferModule etmA = new EntityTransferModule();
79 EntityTransferModule etmB = new EntityTransferModule();
80 LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
81
82 IConfigSource config = new IniConfigSource();
83 config.AddConfig("Chat");
84 IConfig modulesConfig = config.AddConfig("Modules");
85 modulesConfig.Set("EntityTransferModule", etmA.Name);
86 modulesConfig.Set("SimulationServices", lscm.Name);
87
88 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
89 SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA, new ChatModule());
90 SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB, new ChatModule());
91 }
92
93 /// <summary>
94 /// Tests chat between neighbour regions on the east-west axis
95 /// </summary>
96 /// <remarks>
97 /// Really, this is a combination of a child agent position update test and a chat range test. These need
98 /// to be separated later on.
99 /// </remarks>
100 [Test]
101 public void TestInterRegionChatDistanceEastWest()
102 {
103 TestHelpers.InMethod();
104// TestHelpers.EnableLogging();
105
106 UUID sp1Uuid = TestHelpers.ParseTail(0x11);
107 UUID sp2Uuid = TestHelpers.ParseTail(0x12);
108
109 Vector3 sp1Position = new Vector3(6, 128, 20);
110 Vector3 sp2Position = new Vector3(250, 128, 20);
111
112 SceneHelpers sh = new SceneHelpers();
113 TestScene sceneWest = sh.SetupScene("sceneWest", TestHelpers.ParseTail(0x1), 1000, 1000);
114 TestScene sceneEast = sh.SetupScene("sceneEast", TestHelpers.ParseTail(0x2), 1001, 1000);
115
116 SetupNeighbourRegions(sceneWest, sceneEast);
117
118 ScenePresence sp1 = SceneHelpers.AddScenePresence(sceneEast, sp1Uuid);
119 TestClient sp1Client = (TestClient)sp1.ControllingClient;
120
121 // If we don't set agents to flying, test will go wrong as they instantly fall to z = 0.
122 // TODO: May need to create special complete no-op test physics module rather than basic physics, since
123 // physics is irrelevant to this test.
124 sp1.Flying = true;
125
126 // When sp1 logs in to sceneEast, it sets up a child agent in sceneWest and informs the sp2 client to
127 // make the connection. For this test, will simplify this chain by making the connection directly.
128 ScenePresence sp1Child = SceneHelpers.AddChildScenePresence(sceneWest, sp1Uuid);
129 TestClient sp1ChildClient = (TestClient)sp1Child.ControllingClient;
130
131 sp1.AbsolutePosition = sp1Position;
132
133 ScenePresence sp2 = SceneHelpers.AddScenePresence(sceneWest, sp2Uuid);
134 TestClient sp2Client = (TestClient)sp2.ControllingClient;
135 sp2.Flying = true;
136
137 ScenePresence sp2Child = SceneHelpers.AddChildScenePresence(sceneEast, sp2Uuid);
138 TestClient sp2ChildClient = (TestClient)sp2Child.ControllingClient;
139
140 sp2.AbsolutePosition = sp2Position;
141
142 // We must update the scenes in order to make the root new root agents trigger position updates in their
143 // children.
144 sceneWest.Update(1);
145 sceneEast.Update(1);
146
147 // Check child positions are correct.
148 Assert.AreEqual(
149 new Vector3(sp1Position.X + sceneEast.RegionInfo.RegionSizeX, sp1Position.Y, sp1Position.Z),
150 sp1ChildClient.SceneAgent.AbsolutePosition);
151
152 Assert.AreEqual(
153 new Vector3(sp2Position.X - sceneWest.RegionInfo.RegionSizeX, sp2Position.Y, sp2Position.Z),
154 sp2ChildClient.SceneAgent.AbsolutePosition);
155
156 string receivedSp1ChatMessage = "";
157 string receivedSp2ChatMessage = "";
158
159 sp1ChildClient.OnReceivedChatMessage
160 += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp1ChatMessage = message;
161 sp2ChildClient.OnReceivedChatMessage
162 += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp2ChatMessage = message;
163
164 TestUserInRange(sp1Client, "ello darling", ref receivedSp2ChatMessage);
165 TestUserInRange(sp2Client, "fantastic cats", ref receivedSp1ChatMessage);
166
167 sp1Position = new Vector3(30, 128, 20);
168 sp1.AbsolutePosition = sp1Position;
169 sceneEast.Update(1);
170
171 // Check child position is correct.
172 Assert.AreEqual(
173 new Vector3(sp1Position.X + sceneEast.RegionInfo.RegionSizeX, sp1Position.Y, sp1Position.Z),
174 sp1ChildClient.SceneAgent.AbsolutePosition);
175
176 TestUserOutOfRange(sp1Client, "beef", ref receivedSp2ChatMessage);
177 TestUserOutOfRange(sp2Client, "lentils", ref receivedSp1ChatMessage);
178 }
179
180 /// <summary>
181 /// Tests chat between neighbour regions on the north-south axis
182 /// </summary>
183 /// <remarks>
184 /// Really, this is a combination of a child agent position update test and a chat range test. These need
185 /// to be separated later on.
186 /// </remarks>
187 [Test]
188 public void TestInterRegionChatDistanceNorthSouth()
189 {
190 TestHelpers.InMethod();
191 // TestHelpers.EnableLogging();
192
193 UUID sp1Uuid = TestHelpers.ParseTail(0x11);
194 UUID sp2Uuid = TestHelpers.ParseTail(0x12);
195
196 Vector3 sp1Position = new Vector3(128, 250, 20);
197 Vector3 sp2Position = new Vector3(128, 6, 20);
198
199 SceneHelpers sh = new SceneHelpers();
200 TestScene sceneNorth = sh.SetupScene("sceneNorth", TestHelpers.ParseTail(0x1), 1000, 1000);
201 TestScene sceneSouth = sh.SetupScene("sceneSouth", TestHelpers.ParseTail(0x2), 1000, 1001);
202
203 SetupNeighbourRegions(sceneNorth, sceneSouth);
204
205 ScenePresence sp1 = SceneHelpers.AddScenePresence(sceneNorth, sp1Uuid);
206 TestClient sp1Client = (TestClient)sp1.ControllingClient;
207
208 // If we don't set agents to flying, test will go wrong as they instantly fall to z = 0.
209 // TODO: May need to create special complete no-op test physics module rather than basic physics, since
210 // physics is irrelevant to this test.
211 sp1.Flying = true;
212
213 // When sp1 logs in to sceneEast, it sets up a child agent in sceneNorth and informs the sp2 client to
214 // make the connection. For this test, will simplify this chain by making the connection directly.
215 ScenePresence sp1Child = SceneHelpers.AddChildScenePresence(sceneSouth, sp1Uuid);
216 TestClient sp1ChildClient = (TestClient)sp1Child.ControllingClient;
217
218 sp1.AbsolutePosition = sp1Position;
219
220 ScenePresence sp2 = SceneHelpers.AddScenePresence(sceneSouth, sp2Uuid);
221 TestClient sp2Client = (TestClient)sp2.ControllingClient;
222 sp2.Flying = true;
223
224 ScenePresence sp2Child = SceneHelpers.AddChildScenePresence(sceneNorth, sp2Uuid);
225 TestClient sp2ChildClient = (TestClient)sp2Child.ControllingClient;
226
227 sp2.AbsolutePosition = sp2Position;
228
229 // We must update the scenes in order to make the root new root agents trigger position updates in their
230 // children.
231 sceneNorth.Update(1);
232 sceneSouth.Update(1);
233
234 // Check child positions are correct.
235 Assert.AreEqual(
236 new Vector3(sp1Position.X, sp1Position.Y - sceneNorth.RegionInfo.RegionSizeY, sp1Position.Z),
237 sp1ChildClient.SceneAgent.AbsolutePosition);
238
239 Assert.AreEqual(
240 new Vector3(sp2Position.X, sp2Position.Y + sceneSouth.RegionInfo.RegionSizeY, sp2Position.Z),
241 sp2ChildClient.SceneAgent.AbsolutePosition);
242
243 string receivedSp1ChatMessage = "";
244 string receivedSp2ChatMessage = "";
245
246 sp1ChildClient.OnReceivedChatMessage
247 += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp1ChatMessage = message;
248 sp2ChildClient.OnReceivedChatMessage
249 += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp2ChatMessage = message;
250
251 TestUserInRange(sp1Client, "ello darling", ref receivedSp2ChatMessage);
252 TestUserInRange(sp2Client, "fantastic cats", ref receivedSp1ChatMessage);
253
254 sp1Position = new Vector3(30, 128, 20);
255 sp1.AbsolutePosition = sp1Position;
256 sceneNorth.Update(1);
257
258 // Check child position is correct.
259 Assert.AreEqual(
260 new Vector3(sp1Position.X, sp1Position.Y - sceneNorth.RegionInfo.RegionSizeY, sp1Position.Z),
261 sp1ChildClient.SceneAgent.AbsolutePosition);
262
263 TestUserOutOfRange(sp1Client, "beef", ref receivedSp2ChatMessage);
264 TestUserOutOfRange(sp2Client, "lentils", ref receivedSp1ChatMessage);
265 }
266
267 private void TestUserInRange(TestClient speakClient, string testMessage, ref string receivedMessage)
268 {
269 receivedMessage = "";
270
271 speakClient.Chat(0, ChatTypeEnum.Say, testMessage);
272
273 Assert.AreEqual(testMessage, receivedMessage);
274 }
275
276 private void TestUserOutOfRange(TestClient speakClient, string testMessage, ref string receivedMessage)
277 {
278 receivedMessage = "";
279
280 speakClient.Chat(0, ChatTypeEnum.Say, testMessage);
281
282 Assert.AreNotEqual(testMessage, receivedMessage);
283 }
284 }
285} \ No newline at end of file