diff options
Diffstat (limited to 'OpenSim/Region')
16 files changed, 499 insertions, 210 deletions
diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs index 2e155ec..3a4e5df 100644 --- a/OpenSim/Region/Application/Application.cs +++ b/OpenSim/Region/Application/Application.cs | |||
@@ -142,19 +142,19 @@ namespace OpenSim | |||
142 | if (iocpThreads < iocpThreadsMin) | 142 | if (iocpThreads < iocpThreadsMin) |
143 | { | 143 | { |
144 | iocpThreads = iocpThreadsMin; | 144 | iocpThreads = iocpThreadsMin; |
145 | m_log.InfoFormat("[OPENSIM MAIN]: Bumping up max IO completion threads to {0}",iocpThreads); | 145 | m_log.InfoFormat("[OPENSIM MAIN]: Bumping up max IOCP threads to {0}",iocpThreads); |
146 | } | 146 | } |
147 | // Make sure we don't overallocate IOCP threads and thrash system resources | 147 | // Make sure we don't overallocate IOCP threads and thrash system resources |
148 | if ( iocpThreads > iocpThreadsMax ) | 148 | if ( iocpThreads > iocpThreadsMax ) |
149 | { | 149 | { |
150 | iocpThreads = iocpThreadsMax; | 150 | iocpThreads = iocpThreadsMax; |
151 | m_log.InfoFormat("[OPENSIM MAIN]: Limiting max IO completion threads to {0}",iocpThreads); | 151 | m_log.InfoFormat("[OPENSIM MAIN]: Limiting max IOCP completion threads to {0}",iocpThreads); |
152 | } | 152 | } |
153 | // set the resulting worker and IO completion thread counts back to ThreadPool | 153 | // set the resulting worker and IO completion thread counts back to ThreadPool |
154 | if ( System.Threading.ThreadPool.SetMaxThreads(workerThreads, iocpThreads) ) | 154 | if ( System.Threading.ThreadPool.SetMaxThreads(workerThreads, iocpThreads) ) |
155 | { | 155 | { |
156 | m_log.InfoFormat( | 156 | m_log.InfoFormat( |
157 | "[OPENSIM MAIN]: Threadpool set to {0} max worker threads and {1} max IO completion threads", | 157 | "[OPENSIM MAIN]: Threadpool set to {0} max worker threads and {1} max IOCP threads", |
158 | workerThreads, iocpThreads); | 158 | workerThreads, iocpThreads); |
159 | } | 159 | } |
160 | else | 160 | else |
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 6dd1f5b..a18a6fe 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs | |||
@@ -172,6 +172,13 @@ namespace OpenSim | |||
172 | if (userStatsURI != String.Empty) | 172 | if (userStatsURI != String.Empty) |
173 | MainServer.Instance.AddStreamHandler(new OpenSim.UXSimStatusHandler(this)); | 173 | MainServer.Instance.AddStreamHandler(new OpenSim.UXSimStatusHandler(this)); |
174 | 174 | ||
175 | if (managedStatsURI != String.Empty) | ||
176 | { | ||
177 | string urlBase = String.Format("/{0}/", managedStatsURI); | ||
178 | MainServer.Instance.AddHTTPHandler(urlBase, StatsManager.HandleStatsRequest); | ||
179 | m_log.InfoFormat("[OPENSIM] Enabling remote managed stats fetch. URL = {0}", urlBase); | ||
180 | } | ||
181 | |||
175 | if (m_console is RemoteConsole) | 182 | if (m_console is RemoteConsole) |
176 | { | 183 | { |
177 | if (m_consolePort == 0) | 184 | if (m_consolePort == 0) |
@@ -348,18 +355,6 @@ namespace OpenSim | |||
348 | m_console.Commands.AddCommand("Regions", false, "delete-region", | 355 | m_console.Commands.AddCommand("Regions", false, "delete-region", |
349 | "delete-region <name>", | 356 | "delete-region <name>", |
350 | "Delete a region from disk", RunCommand); | 357 | "Delete a region from disk", RunCommand); |
351 | |||
352 | m_console.Commands.AddCommand("General", false, "modules list", | ||
353 | "modules list", | ||
354 | "List modules", HandleModules); | ||
355 | |||
356 | m_console.Commands.AddCommand("General", false, "modules load", | ||
357 | "modules load <name>", | ||
358 | "Load a module", HandleModules); | ||
359 | |||
360 | m_console.Commands.AddCommand("General", false, "modules unload", | ||
361 | "modules unload <name>", | ||
362 | "Unload a module", HandleModules); | ||
363 | } | 358 | } |
364 | 359 | ||
365 | protected override void ShutdownSpecific() | 360 | protected override void ShutdownSpecific() |
@@ -557,34 +552,6 @@ namespace OpenSim | |||
557 | } | 552 | } |
558 | 553 | ||
559 | /// <summary> | 554 | /// <summary> |
560 | /// Load, Unload, and list Region modules in use | ||
561 | /// </summary> | ||
562 | /// <param name="module"></param> | ||
563 | /// <param name="cmd"></param> | ||
564 | private void HandleModules(string module, string[] cmd) | ||
565 | { | ||
566 | List<string> args = new List<string>(cmd); | ||
567 | args.RemoveAt(0); | ||
568 | string[] cmdparams = args.ToArray(); | ||
569 | |||
570 | if (cmdparams.Length > 0) | ||
571 | { | ||
572 | switch (cmdparams[0].ToLower()) | ||
573 | { | ||
574 | case "list": | ||
575 | //TODO: Convert to new region modules | ||
576 | break; | ||
577 | case "unload": | ||
578 | //TODO: Convert to new region modules | ||
579 | break; | ||
580 | case "load": | ||
581 | //TODO: Convert to new region modules | ||
582 | break; | ||
583 | } | ||
584 | } | ||
585 | } | ||
586 | |||
587 | /// <summary> | ||
588 | /// Runs commands issued by the server console from the operator | 555 | /// Runs commands issued by the server console from the operator |
589 | /// </summary> | 556 | /// </summary> |
590 | /// <param name="command">The first argument of the parameter (the command)</param> | 557 | /// <param name="command">The first argument of the parameter (the command)</param> |
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index db76529..0f3bac4 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs | |||
@@ -75,6 +75,7 @@ namespace OpenSim | |||
75 | protected int proxyOffset = 0; | 75 | protected int proxyOffset = 0; |
76 | 76 | ||
77 | public string userStatsURI = String.Empty; | 77 | public string userStatsURI = String.Empty; |
78 | public string managedStatsURI = String.Empty; | ||
78 | 79 | ||
79 | protected bool m_autoCreateClientStack = true; | 80 | protected bool m_autoCreateClientStack = true; |
80 | 81 | ||
@@ -197,6 +198,8 @@ namespace OpenSim | |||
197 | 198 | ||
198 | string permissionModules = startupConfig.GetString("permissionmodules", "DefaultPermissionsModule"); | 199 | string permissionModules = startupConfig.GetString("permissionmodules", "DefaultPermissionsModule"); |
199 | m_permsModules = new List<string>(permissionModules.Split(',')); | 200 | m_permsModules = new List<string>(permissionModules.Split(',')); |
201 | |||
202 | managedStatsURI = startupConfig.GetString("ManagedStatsRemoteFetchURI", String.Empty); | ||
200 | } | 203 | } |
201 | 204 | ||
202 | // Load the simulation data service | 205 | // Load the simulation data service |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs index 141af8a..626932f 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs | |||
@@ -91,7 +91,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests | |||
91 | public void RemoveForClient() | 91 | public void RemoveForClient() |
92 | { | 92 | { |
93 | TestHelpers.InMethod(); | 93 | TestHelpers.InMethod(); |
94 | // log4net.Config.XmlConfigurator.Configure(); | 94 | // TestHelpers.EnableLogging(); |
95 | 95 | ||
96 | UUID spId = TestHelpers.ParseTail(0x1); | 96 | UUID spId = TestHelpers.ParseTail(0x1); |
97 | 97 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 0e20e38..8cbbfd9 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -337,6 +337,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
337 | private bool m_VelocityInterpolate = false; | 337 | private bool m_VelocityInterpolate = false; |
338 | private const uint MaxTransferBytesPerPacket = 600; | 338 | private const uint MaxTransferBytesPerPacket = 600; |
339 | 339 | ||
340 | private volatile bool m_justEditedTerrain = false; | ||
340 | 341 | ||
341 | /// <value> | 342 | /// <value> |
342 | /// List used in construction of data blocks for an object update packet. This is to stop us having to | 343 | /// List used in construction of data blocks for an object update packet. This is to stop us having to |
@@ -536,7 +537,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
536 | // We still perform a force close inside the sync lock since this is intended to attempt close where | 537 | // We still perform a force close inside the sync lock since this is intended to attempt close where |
537 | // there is some unidentified connection problem, not where we have issues due to deadlock | 538 | // there is some unidentified connection problem, not where we have issues due to deadlock |
538 | if (!IsActive && !force) | 539 | if (!IsActive && !force) |
540 | { | ||
541 | m_log.DebugFormat( | ||
542 | "[CLIENT]: Not attempting to close inactive client {0} in {1} since force flag is not set", | ||
543 | Name, m_scene.Name); | ||
544 | |||
539 | return; | 545 | return; |
546 | } | ||
540 | 547 | ||
541 | IsActive = false; | 548 | IsActive = false; |
542 | CloseWithoutChecks(sendStop); | 549 | CloseWithoutChecks(sendStop); |
@@ -1231,9 +1238,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1231 | LLHeightFieldMoronize(map); | 1238 | LLHeightFieldMoronize(map); |
1232 | 1239 | ||
1233 | LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); | 1240 | LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); |
1234 | layerpack.Header.Reliable = true; | 1241 | |
1242 | // When a user edits the terrain, so much data is sent, the data queues up fast and presents a sub optimal editing experience. | ||
1243 | // To alleviate this issue, when the user edits the terrain, we start skipping the queues until they're done editing the terrain. | ||
1244 | // We also make them unreliable because it's extremely likely that multiple packets will be sent for a terrain patch area | ||
1245 | // invalidating previous packets for that area. | ||
1246 | |||
1247 | // It's possible for an editing user to flood themselves with edited packets but the majority of use cases are such that only a | ||
1248 | // tiny percentage of users will be editing the terrain. Other, non-editing users will see the edits much slower. | ||
1249 | |||
1250 | // One last note on this topic, by the time users are going to be editing the terrain, it's extremely likely that the sim will | ||
1251 | // have rezzed already and therefore this is not likely going to cause any additional issues with lost packets, objects or terrain | ||
1252 | // patches. | ||
1235 | 1253 | ||
1236 | OutPacket(layerpack, ThrottleOutPacketType.Task); | 1254 | // m_justEditedTerrain is volatile, so test once and duplicate two affected statements so we only have one cache miss. |
1255 | if (m_justEditedTerrain) | ||
1256 | { | ||
1257 | layerpack.Header.Reliable = false; | ||
1258 | OutPacket(layerpack, | ||
1259 | ThrottleOutPacketType.Unknown ); | ||
1260 | } | ||
1261 | else | ||
1262 | { | ||
1263 | layerpack.Header.Reliable = true; | ||
1264 | OutPacket(layerpack, | ||
1265 | ThrottleOutPacketType.Task); | ||
1266 | } | ||
1237 | } | 1267 | } |
1238 | catch (Exception e) | 1268 | catch (Exception e) |
1239 | { | 1269 | { |
@@ -6367,6 +6397,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6367 | //m_log.Info("[LAND]: LAND:" + modify.ToString()); | 6397 | //m_log.Info("[LAND]: LAND:" + modify.ToString()); |
6368 | if (modify.ParcelData.Length > 0) | 6398 | if (modify.ParcelData.Length > 0) |
6369 | { | 6399 | { |
6400 | // Note: the ModifyTerrain event handler sends out updated packets before the end of this event. Therefore, | ||
6401 | // a simple boolean value should work and perhaps queue up just a few terrain patch packets at the end of the edit. | ||
6402 | m_justEditedTerrain = true; // Prevent terrain packet (Land layer) from being queued, make it unreliable | ||
6370 | if (OnModifyTerrain != null) | 6403 | if (OnModifyTerrain != null) |
6371 | { | 6404 | { |
6372 | for (int i = 0; i < modify.ParcelData.Length; i++) | 6405 | for (int i = 0; i < modify.ParcelData.Length; i++) |
@@ -6382,6 +6415,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6382 | } | 6415 | } |
6383 | } | 6416 | } |
6384 | } | 6417 | } |
6418 | m_justEditedTerrain = false; // Queue terrain packet (Land layer) if necessary, make it reliable again | ||
6385 | } | 6419 | } |
6386 | 6420 | ||
6387 | return true; | 6421 | return true; |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 71b464b..0431b53 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -1871,9 +1871,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1871 | 1871 | ||
1872 | if (!client.SceneAgent.IsChildAgent) | 1872 | if (!client.SceneAgent.IsChildAgent) |
1873 | client.Kick("Simulator logged you out due to connection timeout."); | 1873 | client.Kick("Simulator logged you out due to connection timeout."); |
1874 | |||
1875 | client.CloseWithoutChecks(true); | ||
1876 | } | 1874 | } |
1875 | |||
1876 | m_scene.IncomingCloseAgent(client.AgentId, true); | ||
1877 | } | 1877 | } |
1878 | 1878 | ||
1879 | private void IncomingPacketHandler() | 1879 | private void IncomingPacketHandler() |
@@ -2216,7 +2216,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2216 | if (!client.IsLoggingOut) | 2216 | if (!client.IsLoggingOut) |
2217 | { | 2217 | { |
2218 | client.IsLoggingOut = true; | 2218 | client.IsLoggingOut = true; |
2219 | client.Close(false, false); | 2219 | m_scene.IncomingCloseAgent(client.AgentId, false); |
2220 | } | 2220 | } |
2221 | } | 2221 | } |
2222 | } | 2222 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs index b47ff54..9700224 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs | |||
@@ -200,7 +200,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
200 | public void TestLogoutClientDueToAck() | 200 | public void TestLogoutClientDueToAck() |
201 | { | 201 | { |
202 | TestHelpers.InMethod(); | 202 | TestHelpers.InMethod(); |
203 | // TestHelpers.EnableLogging(); | 203 | TestHelpers.EnableLogging(); |
204 | 204 | ||
205 | IniConfigSource ics = new IniConfigSource(); | 205 | IniConfigSource ics = new IniConfigSource(); |
206 | IConfig config = ics.AddConfig("ClientStack.LindenUDP"); | 206 | IConfig config = ics.AddConfig("ClientStack.LindenUDP"); |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 4286eef..711167f 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -1069,8 +1069,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1069 | // Now let's make it officially a child agent | 1069 | // Now let's make it officially a child agent |
1070 | sp.MakeChildAgent(); | 1070 | sp.MakeChildAgent(); |
1071 | 1071 | ||
1072 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | 1072 | // May still need to signal neighbours whether child agents may need closing irrespective of whether this |
1073 | // one needed closing. Neighbour regions also contain logic to prevent a close if a subsequent move or | ||
1074 | // teleport re-established the child connection. | ||
1075 | // | ||
1076 | // It may be possible to also close child agents after a pause but one needs to be very careful about | ||
1077 | // race conditions between different regions on rapid teleporting (e.g. from A1 to a non-neighbour B, back | ||
1078 | // to a neighbour A2 then off to a non-neighbour C. Also, closing child agents early may be more compatible | ||
1079 | // with complicated scenarios where there a mixture of V1 and V2 teleports, though this is conjecture. It's | ||
1080 | // easier to close immediately and greatly reduce the scope of race conditions if possible. | ||
1081 | sp.CloseChildAgents(newRegionX, newRegionY); | ||
1073 | 1082 | ||
1083 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | ||
1074 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 1084 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) |
1075 | { | 1085 | { |
1076 | sp.DoNotCloseAfterTeleport = false; | 1086 | sp.DoNotCloseAfterTeleport = false; |
@@ -1086,14 +1096,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1086 | if (!sp.DoNotCloseAfterTeleport) | 1096 | if (!sp.DoNotCloseAfterTeleport) |
1087 | { | 1097 | { |
1088 | // OK, it got this agent. Let's close everything | 1098 | // OK, it got this agent. Let's close everything |
1089 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing in agent {0} in region {1}", sp.Name, Scene.Name); | 1099 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing agent {0} in {1}", sp.Name, Scene.Name); |
1090 | sp.CloseChildAgents(newRegionX, newRegionY); | ||
1091 | sp.Scene.IncomingCloseAgent(sp.UUID, false); | 1100 | sp.Scene.IncomingCloseAgent(sp.UUID, false); |
1092 | |||
1093 | } | 1101 | } |
1094 | else | 1102 | else |
1095 | { | 1103 | { |
1096 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {0}", sp.Name, Scene.Name); | 1104 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {1}", sp.Name, Scene.Name); |
1097 | sp.DoNotCloseAfterTeleport = false; | 1105 | sp.DoNotCloseAfterTeleport = false; |
1098 | } | 1106 | } |
1099 | } | 1107 | } |
@@ -1836,10 +1844,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1836 | List<ulong> newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles); | 1844 | List<ulong> newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles); |
1837 | List<ulong> oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles); | 1845 | List<ulong> oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles); |
1838 | 1846 | ||
1839 | //Dump("Current Neighbors", neighbourHandles); | 1847 | // Dump("Current Neighbors", neighbourHandles); |
1840 | //Dump("Previous Neighbours", previousRegionNeighbourHandles); | 1848 | // Dump("Previous Neighbours", previousRegionNeighbourHandles); |
1841 | //Dump("New Neighbours", newRegions); | 1849 | // Dump("New Neighbours", newRegions); |
1842 | //Dump("Old Neighbours", oldRegions); | 1850 | // Dump("Old Neighbours", oldRegions); |
1843 | 1851 | ||
1844 | /// Update the scene presence's known regions here on this region | 1852 | /// Update the scene presence's known regions here on this region |
1845 | sp.DropOldNeighbours(oldRegions); | 1853 | sp.DropOldNeighbours(oldRegions); |
@@ -1847,8 +1855,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1847 | /// Collect as many seeds as possible | 1855 | /// Collect as many seeds as possible |
1848 | Dictionary<ulong, string> seeds; | 1856 | Dictionary<ulong, string> seeds; |
1849 | if (sp.Scene.CapsModule != null) | 1857 | if (sp.Scene.CapsModule != null) |
1850 | seeds | 1858 | seeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID)); |
1851 | = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID)); | ||
1852 | else | 1859 | else |
1853 | seeds = new Dictionary<ulong, string>(); | 1860 | seeds = new Dictionary<ulong, string>(); |
1854 | 1861 | ||
@@ -1918,6 +1925,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1918 | newAgent = true; | 1925 | newAgent = true; |
1919 | else | 1926 | else |
1920 | newAgent = false; | 1927 | newAgent = false; |
1928 | // continue; | ||
1921 | 1929 | ||
1922 | if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) | 1930 | if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) |
1923 | { | 1931 | { |
diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index bb304df..ad33f23 100644 --- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs | |||
@@ -45,6 +45,7 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms | |||
45 | { | 45 | { |
46 | private static readonly ILog m_log = | 46 | private static readonly ILog m_log = |
47 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | private static string LogHeader = "[MODULE COMMS]"; | ||
48 | 49 | ||
49 | private Dictionary<string,object> m_constants = new Dictionary<string,object>(); | 50 | private Dictionary<string,object> m_constants = new Dictionary<string,object>(); |
50 | 51 | ||
@@ -148,7 +149,7 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms | |||
148 | MethodInfo mi = GetMethodInfoFromType(target.GetType(), meth, true); | 149 | MethodInfo mi = GetMethodInfoFromType(target.GetType(), meth, true); |
149 | if (mi == null) | 150 | if (mi == null) |
150 | { | 151 | { |
151 | m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}", meth); | 152 | m_log.WarnFormat("{0} Failed to register method {1}", LogHeader, meth); |
152 | return; | 153 | return; |
153 | } | 154 | } |
154 | 155 | ||
@@ -165,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms | |||
165 | { | 166 | { |
166 | // m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, (target is Type) ? ((Type)target).Name : target.GetType().Name); | 167 | // m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, (target is Type) ? ((Type)target).Name : target.GetType().Name); |
167 | 168 | ||
168 | Type delegateType; | 169 | Type delegateType = typeof(void); |
169 | List<Type> typeArgs = mi.GetParameters() | 170 | List<Type> typeArgs = mi.GetParameters() |
170 | .Select(p => p.ParameterType) | 171 | .Select(p => p.ParameterType) |
171 | .ToList(); | 172 | .ToList(); |
@@ -176,8 +177,16 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms | |||
176 | } | 177 | } |
177 | else | 178 | else |
178 | { | 179 | { |
179 | typeArgs.Add(mi.ReturnType); | 180 | try |
180 | delegateType = Expression.GetFuncType(typeArgs.ToArray()); | 181 | { |
182 | typeArgs.Add(mi.ReturnType); | ||
183 | delegateType = Expression.GetFuncType(typeArgs.ToArray()); | ||
184 | } | ||
185 | catch (Exception e) | ||
186 | { | ||
187 | m_log.ErrorFormat("{0} Failed to create function signature. Most likely more than 5 parameters. Method={1}. Error={2}", | ||
188 | LogHeader, mi.Name, e); | ||
189 | } | ||
181 | } | 190 | } |
182 | 191 | ||
183 | Delegate fcall; | 192 | Delegate fcall; |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs index 4d49794..173b603 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs | |||
@@ -76,6 +76,13 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
76 | " that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3, all corners = -1.", | 76 | " that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3, all corners = -1.", |
77 | consoleSetTerrainHeights); | 77 | consoleSetTerrainHeights); |
78 | 78 | ||
79 | m_module.Scene.AddCommand("Regions", m_module, "set water height", | ||
80 | "set water height <height> [<x>] [<y>]", | ||
81 | "Sets the water height in meters. If <x> and <y> are specified, it will only set it on regions with a matching coordinate. " + | ||
82 | "Specify -1 in <x> or <y> to wildcard that coordinate.", | ||
83 | consoleSetWaterHeight); | ||
84 | |||
85 | |||
79 | m_module.Scene.AddCommand( | 86 | m_module.Scene.AddCommand( |
80 | "Estates", m_module, "estate show", "estate show", "Shows all estates on the simulator.", ShowEstatesCommand); | 87 | "Estates", m_module, "estate show", "estate show", "Shows all estates on the simulator.", ShowEstatesCommand); |
81 | } | 88 | } |
@@ -121,7 +128,29 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
121 | } | 128 | } |
122 | } | 129 | } |
123 | } | 130 | } |
124 | 131 | protected void consoleSetWaterHeight(string module, string[] args) | |
132 | { | ||
133 | string heightstring = args[3]; | ||
134 | |||
135 | int x = (args.Length > 4 ? int.Parse(args[4]) : -1); | ||
136 | int y = (args.Length > 5 ? int.Parse(args[5]) : -1); | ||
137 | |||
138 | if (x == -1 || m_module.Scene.RegionInfo.RegionLocX == x) | ||
139 | { | ||
140 | if (y == -1 || m_module.Scene.RegionInfo.RegionLocY == y) | ||
141 | { | ||
142 | double selectedheight = double.Parse(heightstring); | ||
143 | |||
144 | m_log.Debug("[ESTATEMODULE]: Setting water height in " + m_module.Scene.RegionInfo.RegionName + " to " + | ||
145 | string.Format(" {0}", selectedheight)); | ||
146 | m_module.Scene.RegionInfo.RegionSettings.WaterHeight = selectedheight; | ||
147 | |||
148 | m_module.Scene.RegionInfo.RegionSettings.Save(); | ||
149 | m_module.TriggerRegionInfoChange(); | ||
150 | m_module.sendRegionHandshakeToAll(); | ||
151 | } | ||
152 | } | ||
153 | } | ||
125 | protected void consoleSetTerrainHeights(string module, string[] args) | 154 | protected void consoleSetTerrainHeights(string module, string[] args) |
126 | { | 155 | { |
127 | string num = args[3]; | 156 | string num = args[3]; |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index a5f5749..1808fdd 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | |||
@@ -572,7 +572,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
572 | if (!Scene.TeleportClientHome(user, s.ControllingClient)) | 572 | if (!Scene.TeleportClientHome(user, s.ControllingClient)) |
573 | { | 573 | { |
574 | s.ControllingClient.Kick("Your access to the region was revoked and TP home failed - you have been logged out."); | 574 | s.ControllingClient.Kick("Your access to the region was revoked and TP home failed - you have been logged out."); |
575 | s.ControllingClient.Close(); | 575 | Scene.IncomingCloseAgent(s.UUID, false); |
576 | } | 576 | } |
577 | } | 577 | } |
578 | } | 578 | } |
@@ -807,7 +807,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
807 | if (!Scene.TeleportClientHome(prey, s.ControllingClient)) | 807 | if (!Scene.TeleportClientHome(prey, s.ControllingClient)) |
808 | { | 808 | { |
809 | s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); | 809 | s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); |
810 | s.ControllingClient.Close(); | 810 | Scene.IncomingCloseAgent(s.UUID, false); |
811 | } | 811 | } |
812 | } | 812 | } |
813 | } | 813 | } |
@@ -830,7 +830,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
830 | if (!Scene.TeleportClientHome(p.UUID, p.ControllingClient)) | 830 | if (!Scene.TeleportClientHome(p.UUID, p.ControllingClient)) |
831 | { | 831 | { |
832 | p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); | 832 | p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); |
833 | p.ControllingClient.Close(); | 833 | Scene.IncomingCloseAgent(p.UUID, false); |
834 | } | 834 | } |
835 | } | 835 | } |
836 | } | 836 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index aa09092..6323a88 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -151,7 +151,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
151 | public SynchronizeSceneHandler SynchronizeScene; | 151 | public SynchronizeSceneHandler SynchronizeScene; |
152 | 152 | ||
153 | /// <summary> | 153 | /// <summary> |
154 | /// Used to prevent simultaneous calls to RemoveClient() for the same agent from interfering with each other. | 154 | /// Used to prevent simultaneous calls to code that adds and removes agents. |
155 | /// </summary> | 155 | /// </summary> |
156 | private object m_removeClientLock = new object(); | 156 | private object m_removeClientLock = new object(); |
157 | 157 | ||
@@ -1338,7 +1338,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1338 | Thread.Sleep(500); | 1338 | Thread.Sleep(500); |
1339 | 1339 | ||
1340 | // Stop all client threads. | 1340 | // Stop all client threads. |
1341 | ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); }); | 1341 | ForEachScenePresence(delegate(ScenePresence avatar) { IncomingCloseAgent(avatar.UUID, false); }); |
1342 | 1342 | ||
1343 | m_log.Debug("[SCENE]: TriggerSceneShuttingDown"); | 1343 | m_log.Debug("[SCENE]: TriggerSceneShuttingDown"); |
1344 | EventManager.TriggerSceneShuttingDown(this); | 1344 | EventManager.TriggerSceneShuttingDown(this); |
@@ -3127,7 +3127,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3127 | if (sp != null) | 3127 | if (sp != null) |
3128 | { | 3128 | { |
3129 | PresenceService.LogoutAgent(sp.ControllingClient.SessionId); | 3129 | PresenceService.LogoutAgent(sp.ControllingClient.SessionId); |
3130 | sp.ControllingClient.Close(); | 3130 | |
3131 | IncomingCloseAgent(sp.UUID, false); | ||
3131 | } | 3132 | } |
3132 | 3133 | ||
3133 | // BANG! SLASH! | 3134 | // BANG! SLASH! |
@@ -3541,47 +3542,48 @@ namespace OpenSim.Region.Framework.Scenes | |||
3541 | 3542 | ||
3542 | public override void RemoveClient(UUID agentID, bool closeChildAgents) | 3543 | public override void RemoveClient(UUID agentID, bool closeChildAgents) |
3543 | { | 3544 | { |
3544 | // CheckHeartbeat(); | 3545 | AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID); |
3545 | bool isChildAgent = false; | ||
3546 | AgentCircuitData acd; | ||
3547 | 3546 | ||
3548 | lock (m_removeClientLock) | 3547 | // Shouldn't be necessary since RemoveClient() is currently only called by IClientAPI.Close() which |
3548 | // in turn is only called by Scene.IncomingCloseAgent() which checks whether the presence exists or not | ||
3549 | // However, will keep for now just in case. | ||
3550 | if (acd == null) | ||
3549 | { | 3551 | { |
3550 | acd = m_authenticateHandler.GetAgentCircuitData(agentID); | 3552 | m_log.ErrorFormat( |
3553 | "[SCENE]: No agent circuit found for {0} in {1}, aborting Scene.RemoveClient", agentID, Name); | ||
3551 | 3554 | ||
3552 | if (acd == null) | 3555 | return; |
3553 | { | 3556 | } |
3554 | m_log.ErrorFormat("[SCENE]: No agent circuit found for {0}, aborting Scene.RemoveClient", agentID); | 3557 | else |
3555 | return; | 3558 | { |
3556 | } | 3559 | m_authenticateHandler.RemoveCircuit(agentID); |
3557 | else | ||
3558 | { | ||
3559 | // We remove the acd up here to avoid later race conditions if two RemoveClient() calls occurred | ||
3560 | // simultaneously. | ||
3561 | // We also need to remove by agent ID since NPCs will have no circuit code. | ||
3562 | m_authenticateHandler.RemoveCircuit(agentID); | ||
3563 | } | ||
3564 | } | 3560 | } |
3565 | 3561 | ||
3562 | // TODO: Can we now remove this lock? | ||
3566 | lock (acd) | 3563 | lock (acd) |
3567 | { | 3564 | { |
3565 | bool isChildAgent = false; | ||
3566 | |||
3568 | ScenePresence avatar = GetScenePresence(agentID); | 3567 | ScenePresence avatar = GetScenePresence(agentID); |
3569 | 3568 | ||
3569 | // Shouldn't be necessary since RemoveClient() is currently only called by IClientAPI.Close() which | ||
3570 | // in turn is only called by Scene.IncomingCloseAgent() which checks whether the presence exists or not | ||
3571 | // However, will keep for now just in case. | ||
3570 | if (avatar == null) | 3572 | if (avatar == null) |
3571 | { | 3573 | { |
3572 | m_log.WarnFormat( | 3574 | m_log.ErrorFormat( |
3573 | "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID); | 3575 | "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID); |
3574 | 3576 | ||
3575 | return; | 3577 | return; |
3576 | } | 3578 | } |
3577 | 3579 | ||
3578 | try | 3580 | try |
3579 | { | 3581 | { |
3580 | isChildAgent = avatar.IsChildAgent; | 3582 | isChildAgent = avatar.IsChildAgent; |
3581 | 3583 | ||
3582 | m_log.DebugFormat( | 3584 | m_log.DebugFormat( |
3583 | "[SCENE]: Removing {0} agent {1} {2} from {3}", | 3585 | "[SCENE]: Removing {0} agent {1} {2} from {3}", |
3584 | (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName); | 3586 | isChildAgent ? "child" : "root", avatar.Name, agentID, Name); |
3585 | 3587 | ||
3586 | // Don't do this to root agents, it's not nice for the viewer | 3588 | // Don't do this to root agents, it's not nice for the viewer |
3587 | if (closeChildAgents && isChildAgent) | 3589 | if (closeChildAgents && isChildAgent) |
@@ -3745,13 +3747,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
3745 | /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of | 3747 | /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of |
3746 | /// the LLUDP stack). | 3748 | /// the LLUDP stack). |
3747 | /// </remarks> | 3749 | /// </remarks> |
3748 | /// <param name="agent">CircuitData of the agent who is connecting</param> | 3750 | /// <param name="acd">CircuitData of the agent who is connecting</param> |
3749 | /// <param name="reason">Outputs the reason for the false response on this string</param> | 3751 | /// <param name="reason">Outputs the reason for the false response on this string</param> |
3750 | /// <param name="requirePresenceLookup">True for normal presence. False for NPC | 3752 | /// <param name="requirePresenceLookup">True for normal presence. False for NPC |
3751 | /// or other applications where a full grid/Hypergrid presence may not be required.</param> | 3753 | /// or other applications where a full grid/Hypergrid presence may not be required.</param> |
3752 | /// <returns>True if the region accepts this agent. False if it does not. False will | 3754 | /// <returns>True if the region accepts this agent. False if it does not. False will |
3753 | /// also return a reason.</returns> | 3755 | /// also return a reason.</returns> |
3754 | public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason, bool requirePresenceLookup) | 3756 | public bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, out string reason, bool requirePresenceLookup) |
3755 | { | 3757 | { |
3756 | bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || | 3758 | bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || |
3757 | (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); | 3759 | (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); |
@@ -3771,15 +3773,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
3771 | m_log.DebugFormat( | 3773 | m_log.DebugFormat( |
3772 | "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9})", | 3774 | "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9})", |
3773 | RegionInfo.RegionName, | 3775 | RegionInfo.RegionName, |
3774 | (agent.child ? "child" : "root"), | 3776 | (acd.child ? "child" : "root"), |
3775 | agent.firstname, | 3777 | acd.firstname, |
3776 | agent.lastname, | 3778 | acd.lastname, |
3777 | agent.AgentID, | 3779 | acd.AgentID, |
3778 | agent.circuitcode, | 3780 | acd.circuitcode, |
3779 | agent.IPAddress, | 3781 | acd.IPAddress, |
3780 | agent.Viewer, | 3782 | acd.Viewer, |
3781 | ((TPFlags)teleportFlags).ToString(), | 3783 | ((TPFlags)teleportFlags).ToString(), |
3782 | agent.startpos | 3784 | acd.startpos |
3783 | ); | 3785 | ); |
3784 | 3786 | ||
3785 | if (!LoginsEnabled) | 3787 | if (!LoginsEnabled) |
@@ -3797,7 +3799,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3797 | { | 3799 | { |
3798 | foreach (string viewer in m_AllowedViewers) | 3800 | foreach (string viewer in m_AllowedViewers) |
3799 | { | 3801 | { |
3800 | if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower()) | 3802 | if (viewer == acd.Viewer.Substring(0, viewer.Length).Trim().ToLower()) |
3801 | { | 3803 | { |
3802 | ViewerDenied = false; | 3804 | ViewerDenied = false; |
3803 | break; | 3805 | break; |
@@ -3814,7 +3816,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3814 | { | 3816 | { |
3815 | foreach (string viewer in m_BannedViewers) | 3817 | foreach (string viewer in m_BannedViewers) |
3816 | { | 3818 | { |
3817 | if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower()) | 3819 | if (viewer == acd.Viewer.Substring(0, viewer.Length).Trim().ToLower()) |
3818 | { | 3820 | { |
3819 | ViewerDenied = true; | 3821 | ViewerDenied = true; |
3820 | break; | 3822 | break; |
@@ -3826,61 +3828,115 @@ namespace OpenSim.Region.Framework.Scenes | |||
3826 | { | 3828 | { |
3827 | m_log.DebugFormat( | 3829 | m_log.DebugFormat( |
3828 | "[SCENE]: Access denied for {0} {1} using {2}", | 3830 | "[SCENE]: Access denied for {0} {1} using {2}", |
3829 | agent.firstname, agent.lastname, agent.Viewer); | 3831 | acd.firstname, acd.lastname, acd.Viewer); |
3830 | reason = "Access denied, your viewer is banned by the region owner"; | 3832 | reason = "Access denied, your viewer is banned by the region owner"; |
3831 | return false; | 3833 | return false; |
3832 | } | 3834 | } |
3835 | |||
3836 | ILandObject land; | ||
3837 | ScenePresence sp; | ||
3833 | 3838 | ||
3834 | lock (agent) | 3839 | lock (m_removeClientLock) |
3835 | { | 3840 | { |
3836 | ScenePresence sp = GetScenePresence(agent.AgentID); | 3841 | sp = GetScenePresence(acd.AgentID); |
3837 | 3842 | ||
3838 | if (sp != null) | 3843 | // We need to ensure that we are not already removing the scene presence before we ask it not to be |
3844 | // closed. | ||
3845 | if (sp != null && sp.IsChildAgent && sp.LifecycleState == ScenePresenceState.Running) | ||
3839 | { | 3846 | { |
3840 | if (!sp.IsChildAgent) | 3847 | m_log.DebugFormat( |
3841 | { | 3848 | "[SCENE]: Reusing existing child scene presence for {0} in {1}", sp.Name, Name); |
3842 | // We have a root agent. Is it in transit? | ||
3843 | if (!EntityTransferModule.IsInTransit(sp.UUID)) | ||
3844 | { | ||
3845 | // We have a zombie from a crashed session. | ||
3846 | // Or the same user is trying to be root twice here, won't work. | ||
3847 | // Kill it. | ||
3848 | m_log.WarnFormat( | ||
3849 | "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", | ||
3850 | sp.Name, sp.UUID, RegionInfo.RegionName); | ||
3851 | 3849 | ||
3852 | if (sp.ControllingClient != null) | 3850 | // In the case where, for example, an A B C D region layout, an avatar may |
3853 | sp.ControllingClient.Close(true, true); | 3851 | // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C |
3852 | // renews the lease on the child agent at B, we must make sure that the close from A does not succeed. | ||
3853 | if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle)) | ||
3854 | { | ||
3855 | m_log.DebugFormat( | ||
3856 | "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.", | ||
3857 | sp.Name, Name); | ||
3854 | 3858 | ||
3855 | sp = null; | 3859 | sp.DoNotCloseAfterTeleport = true; |
3856 | } | ||
3857 | //else | ||
3858 | // m_log.WarnFormat("[SCENE]: Existing root scene presence for {0} {1} in {2}, but agent is in trasit", sp.Name, sp.UUID, RegionInfo.RegionName); | ||
3859 | } | 3860 | } |
3860 | else | 3861 | else if (EntityTransferModule.IsInTransit(sp.UUID)) |
3861 | { | 3862 | { |
3862 | // We have a child agent here | 3863 | m_log.DebugFormat( |
3864 | "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt previous end-of-teleport close.", | ||
3865 | sp.Name, Name); | ||
3866 | |||
3863 | sp.DoNotCloseAfterTeleport = true; | 3867 | sp.DoNotCloseAfterTeleport = true; |
3864 | //m_log.WarnFormat("[SCENE]: Existing child scene presence for {0} {1} in {2}", sp.Name, sp.UUID, RegionInfo.RegionName); | ||
3865 | } | 3868 | } |
3866 | } | 3869 | } |
3870 | } | ||
3871 | |||
3872 | // Need to poll here in case we are currently deleting an sp. Letting threads run over each other will | ||
3873 | // allow unpredictable things to happen. | ||
3874 | if (sp != null) | ||
3875 | { | ||
3876 | const int polls = 10; | ||
3877 | const int pollInterval = 1000; | ||
3878 | int pollsLeft = polls; | ||
3879 | |||
3880 | while (sp.LifecycleState == ScenePresenceState.Removing && pollsLeft-- > 0) | ||
3881 | Thread.Sleep(pollInterval); | ||
3882 | |||
3883 | if (sp.LifecycleState == ScenePresenceState.Removing) | ||
3884 | { | ||
3885 | m_log.WarnFormat( | ||
3886 | "[SCENE]: Agent {0} in {1} was still being removed after {2}s. Aborting NewUserConnection.", | ||
3887 | sp.Name, Name, polls * pollInterval / 1000); | ||
3888 | |||
3889 | return false; | ||
3890 | } | ||
3891 | else if (polls != pollsLeft) | ||
3892 | { | ||
3893 | m_log.DebugFormat( | ||
3894 | "[SCENE]: NewUserConnection for agent {0} in {1} had to wait {2}s for in-progress removal to complete on an old presence.", | ||
3895 | sp.Name, Name, polls * pollInterval / 1000); | ||
3896 | } | ||
3897 | } | ||
3898 | |||
3899 | // TODO: can we remove this lock? | ||
3900 | lock (acd) | ||
3901 | { | ||
3902 | if (sp != null && !sp.IsChildAgent) | ||
3903 | { | ||
3904 | // We have a root agent. Is it in transit? | ||
3905 | if (!EntityTransferModule.IsInTransit(sp.UUID)) | ||
3906 | { | ||
3907 | // We have a zombie from a crashed session. | ||
3908 | // Or the same user is trying to be root twice here, won't work. | ||
3909 | // Kill it. | ||
3910 | m_log.WarnFormat( | ||
3911 | "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", | ||
3912 | sp.Name, sp.UUID, RegionInfo.RegionName); | ||
3913 | |||
3914 | if (sp.ControllingClient != null) | ||
3915 | IncomingCloseAgent(sp.UUID, true); | ||
3916 | |||
3917 | sp = null; | ||
3918 | } | ||
3919 | //else | ||
3920 | // m_log.WarnFormat("[SCENE]: Existing root scene presence for {0} {1} in {2}, but agent is in trasit", sp.Name, sp.UUID, RegionInfo.RegionName); | ||
3921 | } | ||
3867 | 3922 | ||
3868 | // Optimistic: add or update the circuit data with the new agent circuit data and teleport flags. | 3923 | // Optimistic: add or update the circuit data with the new agent circuit data and teleport flags. |
3869 | // We need the circuit data here for some of the subsequent checks. (groups, for example) | 3924 | // We need the circuit data here for some of the subsequent checks. (groups, for example) |
3870 | // If the checks fail, we remove the circuit. | 3925 | // If the checks fail, we remove the circuit. |
3871 | agent.teleportFlags = teleportFlags; | 3926 | acd.teleportFlags = teleportFlags; |
3872 | m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); | 3927 | m_authenticateHandler.AddNewCircuit(acd.circuitcode, acd); |
3873 | 3928 | ||
3929 | land = LandChannel.GetLandObject(acd.startpos.X, acd.startpos.Y); | ||
3930 | |||
3874 | // On login test land permisions | 3931 | // On login test land permisions |
3875 | if (vialogin) | 3932 | if (vialogin) |
3876 | { | 3933 | { |
3877 | IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); | 3934 | IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); |
3878 | if (cache != null) | 3935 | if (cache != null) |
3879 | cache.Remove(agent.firstname + " " + agent.lastname); | 3936 | cache.Remove(acd.firstname + " " + acd.lastname); |
3880 | if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y)) | 3937 | if (land != null && !TestLandRestrictions(acd.AgentID, out reason, ref acd.startpos.X, ref acd.startpos.Y)) |
3881 | { | 3938 | { |
3882 | m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString()); | 3939 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); |
3883 | m_authenticateHandler.RemoveCircuit(agent.circuitcode); | ||
3884 | return false; | 3940 | return false; |
3885 | } | 3941 | } |
3886 | } | 3942 | } |
@@ -3891,9 +3947,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3891 | { | 3947 | { |
3892 | try | 3948 | try |
3893 | { | 3949 | { |
3894 | if (!VerifyUserPresence(agent, out reason)) | 3950 | if (!VerifyUserPresence(acd, out reason)) |
3895 | { | 3951 | { |
3896 | m_authenticateHandler.RemoveCircuit(agent.circuitcode); | 3952 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); |
3897 | return false; | 3953 | return false; |
3898 | } | 3954 | } |
3899 | } | 3955 | } |
@@ -3902,16 +3958,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
3902 | m_log.ErrorFormat( | 3958 | m_log.ErrorFormat( |
3903 | "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); | 3959 | "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); |
3904 | 3960 | ||
3905 | m_authenticateHandler.RemoveCircuit(agent.circuitcode); | 3961 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); |
3906 | return false; | 3962 | return false; |
3907 | } | 3963 | } |
3908 | } | 3964 | } |
3909 | 3965 | ||
3910 | try | 3966 | try |
3911 | { | 3967 | { |
3912 | if (!AuthorizeUser(agent, SeeIntoRegion, out reason)) | 3968 | if (!AuthorizeUser(acd, SeeIntoRegion, out reason)) |
3913 | { | 3969 | { |
3914 | m_authenticateHandler.RemoveCircuit(agent.circuitcode); | 3970 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); |
3915 | return false; | 3971 | return false; |
3916 | } | 3972 | } |
3917 | } | 3973 | } |
@@ -3920,15 +3976,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
3920 | m_log.ErrorFormat( | 3976 | m_log.ErrorFormat( |
3921 | "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); | 3977 | "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); |
3922 | 3978 | ||
3923 | m_authenticateHandler.RemoveCircuit(agent.circuitcode); | 3979 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); |
3924 | return false; | 3980 | return false; |
3925 | } | 3981 | } |
3926 | 3982 | ||
3927 | m_log.InfoFormat( | 3983 | m_log.InfoFormat( |
3928 | "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})", | 3984 | "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})", |
3929 | RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname, | 3985 | Name, (acd.child ? "child" : "root"), acd.firstname, acd.lastname, |
3930 | agent.AgentID, agent.circuitcode); | 3986 | acd.AgentID, acd.circuitcode); |
3931 | 3987 | ||
3988 | if (CapsModule != null) | ||
3989 | { | ||
3990 | CapsModule.SetAgentCapsSeeds(acd); | ||
3991 | CapsModule.CreateCaps(acd.AgentID, acd.circuitcode); | ||
3992 | } | ||
3932 | } | 3993 | } |
3933 | else | 3994 | else |
3934 | { | 3995 | { |
@@ -3940,14 +4001,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
3940 | { | 4001 | { |
3941 | m_log.DebugFormat( | 4002 | m_log.DebugFormat( |
3942 | "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", | 4003 | "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", |
3943 | agent.AgentID, RegionInfo.RegionName); | 4004 | acd.AgentID, RegionInfo.RegionName); |
3944 | 4005 | ||
3945 | sp.AdjustKnownSeeds(); | 4006 | sp.AdjustKnownSeeds(); |
3946 | 4007 | ||
3947 | if (CapsModule != null) | 4008 | if (CapsModule != null) |
3948 | { | 4009 | { |
3949 | CapsModule.SetAgentCapsSeeds(agent); | 4010 | CapsModule.SetAgentCapsSeeds(acd); |
3950 | CapsModule.CreateCaps(agent.AgentID, agent.circuitcode); | 4011 | CapsModule.CreateCaps(acd.AgentID, acd.circuitcode); |
3951 | } | 4012 | } |
3952 | } | 4013 | } |
3953 | } | 4014 | } |
@@ -3955,28 +4016,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
3955 | // Try caching an incoming user name much earlier on to see if this helps with an issue | 4016 | // Try caching an incoming user name much earlier on to see if this helps with an issue |
3956 | // where HG users are occasionally seen by others as "Unknown User" because their UUIDName | 4017 | // where HG users are occasionally seen by others as "Unknown User" because their UUIDName |
3957 | // request for the HG avatar appears to trigger before the user name is cached. | 4018 | // request for the HG avatar appears to trigger before the user name is cached. |
3958 | CacheUserName(null, agent); | 4019 | CacheUserName(null, acd); |
3959 | } | 4020 | } |
3960 | 4021 | ||
3961 | if (CapsModule != null) | 4022 | if (CapsModule != null) |
3962 | { | 4023 | { |
3963 | CapsModule.ActivateCaps(agent.circuitcode); | 4024 | CapsModule.ActivateCaps(acd.circuitcode); |
3964 | } | 4025 | } |
3965 | 4026 | ||
3966 | if (vialogin) | 4027 | if (vialogin) |
3967 | { | 4028 | { |
3968 | // CleanDroppedAttachments(); | 4029 | // CleanDroppedAttachments(); |
3969 | 4030 | ||
3970 | if (TestBorderCross(agent.startpos, Cardinals.E)) | 4031 | if (TestBorderCross(acd.startpos, Cardinals.E)) |
3971 | { | 4032 | { |
3972 | Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.E); | 4033 | Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.E); |
3973 | agent.startpos.X = crossedBorder.BorderLine.Z - 1; | 4034 | acd.startpos.X = crossedBorder.BorderLine.Z - 1; |
3974 | } | 4035 | } |
3975 | 4036 | ||
3976 | if (TestBorderCross(agent.startpos, Cardinals.N)) | 4037 | if (TestBorderCross(acd.startpos, Cardinals.N)) |
3977 | { | 4038 | { |
3978 | Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.N); | 4039 | Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.N); |
3979 | agent.startpos.Y = crossedBorder.BorderLine.Z - 1; | 4040 | acd.startpos.Y = crossedBorder.BorderLine.Z - 1; |
3980 | } | 4041 | } |
3981 | 4042 | ||
3982 | //Mitigate http://opensimulator.org/mantis/view.php?id=3522 | 4043 | //Mitigate http://opensimulator.org/mantis/view.php?id=3522 |
@@ -3986,39 +4047,39 @@ namespace OpenSim.Region.Framework.Scenes | |||
3986 | { | 4047 | { |
3987 | lock (EastBorders) | 4048 | lock (EastBorders) |
3988 | { | 4049 | { |
3989 | if (agent.startpos.X > EastBorders[0].BorderLine.Z) | 4050 | if (acd.startpos.X > EastBorders[0].BorderLine.Z) |
3990 | { | 4051 | { |
3991 | m_log.Warn("FIX AGENT POSITION"); | 4052 | m_log.Warn("FIX AGENT POSITION"); |
3992 | agent.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; | 4053 | acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; |
3993 | if (agent.startpos.Z > 720) | 4054 | if (acd.startpos.Z > 720) |
3994 | agent.startpos.Z = 720; | 4055 | acd.startpos.Z = 720; |
3995 | } | 4056 | } |
3996 | } | 4057 | } |
3997 | lock (NorthBorders) | 4058 | lock (NorthBorders) |
3998 | { | 4059 | { |
3999 | if (agent.startpos.Y > NorthBorders[0].BorderLine.Z) | 4060 | if (acd.startpos.Y > NorthBorders[0].BorderLine.Z) |
4000 | { | 4061 | { |
4001 | m_log.Warn("FIX Agent POSITION"); | 4062 | m_log.Warn("FIX Agent POSITION"); |
4002 | agent.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; | 4063 | acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; |
4003 | if (agent.startpos.Z > 720) | 4064 | if (acd.startpos.Z > 720) |
4004 | agent.startpos.Z = 720; | 4065 | acd.startpos.Z = 720; |
4005 | } | 4066 | } |
4006 | } | 4067 | } |
4007 | } else | 4068 | } else |
4008 | { | 4069 | { |
4009 | if (agent.startpos.X > EastBorders[0].BorderLine.Z) | 4070 | if (acd.startpos.X > EastBorders[0].BorderLine.Z) |
4010 | { | 4071 | { |
4011 | m_log.Warn("FIX AGENT POSITION"); | 4072 | m_log.Warn("FIX AGENT POSITION"); |
4012 | agent.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; | 4073 | acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; |
4013 | if (agent.startpos.Z > 720) | 4074 | if (acd.startpos.Z > 720) |
4014 | agent.startpos.Z = 720; | 4075 | acd.startpos.Z = 720; |
4015 | } | 4076 | } |
4016 | if (agent.startpos.Y > NorthBorders[0].BorderLine.Z) | 4077 | if (acd.startpos.Y > NorthBorders[0].BorderLine.Z) |
4017 | { | 4078 | { |
4018 | m_log.Warn("FIX Agent POSITION"); | 4079 | m_log.Warn("FIX Agent POSITION"); |
4019 | agent.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; | 4080 | acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; |
4020 | if (agent.startpos.Z > 720) | 4081 | if (acd.startpos.Z > 720) |
4021 | agent.startpos.Z = 720; | 4082 | acd.startpos.Z = 720; |
4022 | } | 4083 | } |
4023 | } | 4084 | } |
4024 | 4085 | ||
@@ -4034,12 +4095,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
4034 | { | 4095 | { |
4035 | // We have multiple SpawnPoints, Route the agent to a random or sequential one | 4096 | // We have multiple SpawnPoints, Route the agent to a random or sequential one |
4036 | if (SpawnPointRouting == "random") | 4097 | if (SpawnPointRouting == "random") |
4037 | agent.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation( | 4098 | acd.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation( |
4038 | telehub.AbsolutePosition, | 4099 | telehub.AbsolutePosition, |
4039 | telehub.GroupRotation | 4100 | telehub.GroupRotation |
4040 | ); | 4101 | ); |
4041 | else | 4102 | else |
4042 | agent.startpos = spawnpoints[SpawnPoint()].GetLocation( | 4103 | acd.startpos = spawnpoints[SpawnPoint()].GetLocation( |
4043 | telehub.AbsolutePosition, | 4104 | telehub.AbsolutePosition, |
4044 | telehub.GroupRotation | 4105 | telehub.GroupRotation |
4045 | ); | 4106 | ); |
@@ -4047,7 +4108,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4047 | else | 4108 | else |
4048 | { | 4109 | { |
4049 | // We have a single SpawnPoint and will route the agent to it | 4110 | // We have a single SpawnPoint and will route the agent to it |
4050 | agent.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); | 4111 | acd.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); |
4051 | } | 4112 | } |
4052 | 4113 | ||
4053 | return true; | 4114 | return true; |
@@ -4060,7 +4121,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4060 | { | 4121 | { |
4061 | if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) | 4122 | if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) |
4062 | { | 4123 | { |
4063 | agent.startpos = land.LandData.UserLocation; | 4124 | acd.startpos = land.LandData.UserLocation; |
4064 | } | 4125 | } |
4065 | } | 4126 | } |
4066 | */// This is now handled properly in ScenePresence.MakeRootAgent | 4127 | */// This is now handled properly in ScenePresence.MakeRootAgent |
@@ -4444,24 +4505,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
4444 | ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); | 4505 | ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); |
4445 | if (childAgentUpdate != null) | 4506 | if (childAgentUpdate != null) |
4446 | { | 4507 | { |
4447 | if (childAgentUpdate.ControllingClient.SessionId == cAgentData.SessionID) | 4508 | if (childAgentUpdate.ControllingClient.SessionId != cAgentData.SessionID) |
4509 | // Only warn for now | ||
4510 | m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}. Neighbor running older version?", | ||
4511 | childAgentUpdate.UUID, cAgentData.SessionID); | ||
4512 | |||
4513 | // I can't imagine *yet* why we would get an update if the agent is a root agent.. | ||
4514 | // however to avoid a race condition crossing borders.. | ||
4515 | if (childAgentUpdate.IsChildAgent) | ||
4448 | { | 4516 | { |
4449 | // I can't imagine *yet* why we would get an update if the agent is a root agent.. | 4517 | uint rRegionX = (uint)(cAgentData.RegionHandle >> 40); |
4450 | // however to avoid a race condition crossing borders.. | 4518 | uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8); |
4451 | if (childAgentUpdate.IsChildAgent) | 4519 | uint tRegionX = RegionInfo.RegionLocX; |
4452 | { | 4520 | uint tRegionY = RegionInfo.RegionLocY; |
4453 | uint rRegionX = (uint)(cAgentData.RegionHandle >> 40); | 4521 | //Send Data to ScenePresence |
4454 | uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8); | 4522 | childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); |
4455 | uint tRegionX = RegionInfo.RegionLocX; | 4523 | // Not Implemented: |
4456 | uint tRegionY = RegionInfo.RegionLocY; | 4524 | //TODO: Do we need to pass the message on to one of our neighbors? |
4457 | //Send Data to ScenePresence | ||
4458 | childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); | ||
4459 | // Not Implemented: | ||
4460 | //TODO: Do we need to pass the message on to one of our neighbors? | ||
4461 | } | ||
4462 | } | 4525 | } |
4463 | else | 4526 | |
4464 | m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}", childAgentUpdate.UUID, cAgentData.SessionID); | ||
4465 | return true; | 4527 | return true; |
4466 | } | 4528 | } |
4467 | 4529 | ||
@@ -4540,11 +4602,51 @@ namespace OpenSim.Region.Framework.Scenes | |||
4540 | /// </param> | 4602 | /// </param> |
4541 | public bool IncomingCloseAgent(UUID agentID, bool force) | 4603 | public bool IncomingCloseAgent(UUID agentID, bool force) |
4542 | { | 4604 | { |
4543 | //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); | 4605 | ScenePresence sp; |
4544 | ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); | 4606 | |
4545 | if (presence != null) | 4607 | lock (m_removeClientLock) |
4608 | { | ||
4609 | sp = GetScenePresence(agentID); | ||
4610 | |||
4611 | if (sp == null) | ||
4612 | { | ||
4613 | m_log.DebugFormat( | ||
4614 | "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in {1}", | ||
4615 | agentID, Name); | ||
4616 | |||
4617 | return false; | ||
4618 | } | ||
4619 | |||
4620 | if (sp.LifecycleState != ScenePresenceState.Running) | ||
4621 | { | ||
4622 | m_log.DebugFormat( | ||
4623 | "[SCENE]: Called RemoveClient() for {0} in {1} but presence is already in state {2}", | ||
4624 | sp.Name, Name, sp.LifecycleState); | ||
4625 | |||
4626 | return false; | ||
4627 | } | ||
4628 | |||
4629 | // We need to avoid a race condition where in, for example, an A B C D region layout, an avatar may | ||
4630 | // teleport from A -> D, but then -> C before A has asked B to close its old child agent. We do not | ||
4631 | // want to obey this close since C may have renewed the child agent lease on B. | ||
4632 | if (sp.DoNotCloseAfterTeleport) | ||
4633 | { | ||
4634 | m_log.DebugFormat( | ||
4635 | "[SCENE]: Not closing {0} agent {1} in {2} since another simulator has re-established the child connection", | ||
4636 | sp.IsChildAgent ? "child" : "root", sp.Name, Name); | ||
4637 | |||
4638 | // Need to reset the flag so that a subsequent close after another teleport can succeed. | ||
4639 | sp.DoNotCloseAfterTeleport = false; | ||
4640 | |||
4641 | return false; | ||
4642 | } | ||
4643 | |||
4644 | sp.LifecycleState = ScenePresenceState.Removing; | ||
4645 | } | ||
4646 | |||
4647 | if (sp != null) | ||
4546 | { | 4648 | { |
4547 | presence.ControllingClient.Close(force, force); | 4649 | sp.ControllingClient.Close(force, force); |
4548 | return true; | 4650 | return true; |
4549 | } | 4651 | } |
4550 | 4652 | ||
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 48bf6f3..5301a82 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -75,6 +75,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
75 | 75 | ||
76 | public class ScenePresence : EntityBase, IScenePresence | 76 | public class ScenePresence : EntityBase, IScenePresence |
77 | { | 77 | { |
78 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
79 | |||
78 | // ~ScenePresence() | 80 | // ~ScenePresence() |
79 | // { | 81 | // { |
80 | // m_log.DebugFormat("[SCENE PRESENCE]: Destructor called on {0}", Name); | 82 | // m_log.DebugFormat("[SCENE PRESENCE]: Destructor called on {0}", Name); |
@@ -86,10 +88,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
86 | m_scene.EventManager.TriggerScenePresenceUpdated(this); | 88 | m_scene.EventManager.TriggerScenePresenceUpdated(this); |
87 | } | 89 | } |
88 | 90 | ||
89 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
90 | |||
91 | public PresenceType PresenceType { get; private set; } | 91 | public PresenceType PresenceType { get; private set; } |
92 | 92 | ||
93 | private ScenePresenceStateMachine m_stateMachine; | ||
94 | |||
95 | /// <summary> | ||
96 | /// The current state of this presence. Governs only the existence lifecycle. See ScenePresenceStateMachine | ||
97 | /// for more details. | ||
98 | /// </summary> | ||
99 | public ScenePresenceState LifecycleState | ||
100 | { | ||
101 | get | ||
102 | { | ||
103 | return m_stateMachine.GetState(); | ||
104 | } | ||
105 | |||
106 | set | ||
107 | { | ||
108 | m_stateMachine.SetState(value); | ||
109 | } | ||
110 | } | ||
111 | |||
93 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); | 112 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); |
94 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); | 113 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); |
95 | private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); | 114 | private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); |
@@ -299,9 +318,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
299 | /// <summary> | 318 | /// <summary> |
300 | /// In the V1 teleport protocol, the destination simulator sends ReleaseAgent to this address. | 319 | /// In the V1 teleport protocol, the destination simulator sends ReleaseAgent to this address. |
301 | /// </summary> | 320 | /// </summary> |
302 | string m_callbackURI; | 321 | private string m_callbackURI; |
303 | 322 | ||
304 | UUID m_originRegionID; | 323 | public UUID m_originRegionID; |
305 | 324 | ||
306 | /// <summary> | 325 | /// <summary> |
307 | /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent | 326 | /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent |
@@ -813,7 +832,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
813 | 832 | ||
814 | public ScenePresence( | 833 | public ScenePresence( |
815 | IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type) | 834 | IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type) |
816 | { | 835 | { |
817 | AttachmentsSyncLock = new Object(); | 836 | AttachmentsSyncLock = new Object(); |
818 | AllowMovement = true; | 837 | AllowMovement = true; |
819 | IsChildAgent = true; | 838 | IsChildAgent = true; |
@@ -859,6 +878,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
859 | SetDirectionVectors(); | 878 | SetDirectionVectors(); |
860 | 879 | ||
861 | Appearance = appearance; | 880 | Appearance = appearance; |
881 | |||
882 | m_stateMachine = new ScenePresenceStateMachine(this); | ||
862 | } | 883 | } |
863 | 884 | ||
864 | private void RegionHeartbeatEnd(Scene scene) | 885 | private void RegionHeartbeatEnd(Scene scene) |
@@ -956,7 +977,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
956 | /// </summary> | 977 | /// </summary> |
957 | public void MakeRootAgent(Vector3 pos, bool isFlying) | 978 | public void MakeRootAgent(Vector3 pos, bool isFlying) |
958 | { | 979 | { |
959 | m_log.DebugFormat( | 980 | m_log.InfoFormat( |
960 | "[SCENE]: Upgrading child to root agent for {0} in {1}", | 981 | "[SCENE]: Upgrading child to root agent for {0} in {1}", |
961 | Name, m_scene.RegionInfo.RegionName); | 982 | Name, m_scene.RegionInfo.RegionName); |
962 | 983 | ||
@@ -996,6 +1017,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
996 | 1017 | ||
997 | IsChildAgent = false; | 1018 | IsChildAgent = false; |
998 | 1019 | ||
1020 | // Must reset this here so that a teleport to a region next to an existing region does not keep the flag | ||
1021 | // set and prevent the close of the connection on a subsequent re-teleport. | ||
1022 | // Should not be needed if we are not trying to tell this region to close | ||
1023 | // DoNotCloseAfterTeleport = false; | ||
1024 | |||
999 | IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); | 1025 | IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); |
1000 | if (gm != null) | 1026 | if (gm != null) |
1001 | Grouptitle = gm.GetGroupTitle(m_uuid); | 1027 | Grouptitle = gm.GetGroupTitle(m_uuid); |
@@ -1520,7 +1546,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1520 | private bool WaitForUpdateAgent(IClientAPI client) | 1546 | private bool WaitForUpdateAgent(IClientAPI client) |
1521 | { | 1547 | { |
1522 | // Before UpdateAgent, m_originRegionID is UUID.Zero; after, it's non-Zero | 1548 | // Before UpdateAgent, m_originRegionID is UUID.Zero; after, it's non-Zero |
1523 | int count = 20; | 1549 | int count = 50; |
1524 | while (m_originRegionID.Equals(UUID.Zero) && count-- > 0) | 1550 | while (m_originRegionID.Equals(UUID.Zero) && count-- > 0) |
1525 | { | 1551 | { |
1526 | m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name); | 1552 | m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name); |
@@ -3994,6 +4020,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3994 | // Animator.Close(); | 4020 | // Animator.Close(); |
3995 | Animator = null; | 4021 | Animator = null; |
3996 | 4022 | ||
4023 | LifecycleState = ScenePresenceState.Removed; | ||
3997 | } | 4024 | } |
3998 | 4025 | ||
3999 | public void AddAttachment(SceneObjectGroup gobj) | 4026 | public void AddAttachment(SceneObjectGroup gobj) |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresenceStateMachine.cs b/OpenSim/Region/Framework/Scenes/ScenePresenceStateMachine.cs new file mode 100644 index 0000000..dc3a212 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/ScenePresenceStateMachine.cs | |||
@@ -0,0 +1,102 @@ | |||
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 | |||
28 | using System; | ||
29 | |||
30 | namespace OpenSim.Region.Framework.Scenes | ||
31 | { | ||
32 | /// <summary> | ||
33 | /// The possible states that a scene presence can be in. This is currently orthagonal to whether a scene presence | ||
34 | /// is root or child. | ||
35 | /// </summary> | ||
36 | /// <remarks> | ||
37 | /// This is a state machine. | ||
38 | /// | ||
39 | /// [Entry] => Running | ||
40 | /// Running => Removing | ||
41 | /// Removing => Removed | ||
42 | /// | ||
43 | /// All other methods should only see the scene presence in running state - this is the normal operational state | ||
44 | /// Removed state occurs when the presence has been removed. This is the end state with no exit. | ||
45 | /// </remarks> | ||
46 | public enum ScenePresenceState | ||
47 | { | ||
48 | Running, // Normal operation state. The scene presence is available. | ||
49 | Removing, // The presence is in the process of being removed from the scene via Scene.RemoveClient. | ||
50 | Removed, // The presence has been removed from the scene and is effectively dead. | ||
51 | // There is no exit from this state. | ||
52 | } | ||
53 | |||
54 | internal class ScenePresenceStateMachine | ||
55 | { | ||
56 | private ScenePresence m_sp; | ||
57 | private ScenePresenceState m_state; | ||
58 | |||
59 | internal ScenePresenceStateMachine(ScenePresence sp) | ||
60 | { | ||
61 | m_sp = sp; | ||
62 | m_state = ScenePresenceState.Running; | ||
63 | } | ||
64 | |||
65 | internal ScenePresenceState GetState() | ||
66 | { | ||
67 | return m_state; | ||
68 | } | ||
69 | |||
70 | /// <summary> | ||
71 | /// Updates the state of an agent that is already in transit. | ||
72 | /// </summary> | ||
73 | /// <param name='id'></param> | ||
74 | /// <param name='newState'></param> | ||
75 | /// <returns></returns> | ||
76 | /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception> | ||
77 | internal void SetState(ScenePresenceState newState) | ||
78 | { | ||
79 | bool transitionOkay = false; | ||
80 | |||
81 | lock (this) | ||
82 | { | ||
83 | if (newState == ScenePresenceState.Removing && m_state == ScenePresenceState.Running) | ||
84 | transitionOkay = true; | ||
85 | else if (newState == ScenePresenceState.Removed && m_state == ScenePresenceState.Removing) | ||
86 | transitionOkay = true; | ||
87 | } | ||
88 | |||
89 | if (!transitionOkay) | ||
90 | { | ||
91 | throw new Exception( | ||
92 | string.Format( | ||
93 | "Scene presence {0} is not allowed to move from state {1} to new state {2} in {3}", | ||
94 | m_sp.Name, m_state, newState, m_sp.Scene.Name)); | ||
95 | } | ||
96 | else | ||
97 | { | ||
98 | m_state = newState; | ||
99 | } | ||
100 | } | ||
101 | } | ||
102 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 58a417e..9af3dce 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -96,8 +96,8 @@ public sealed class BSCharacter : BSPhysObject | |||
96 | m_moveActor = new BSActorAvatarMove(PhysScene, this, AvatarMoveActorName); | 96 | m_moveActor = new BSActorAvatarMove(PhysScene, this, AvatarMoveActorName); |
97 | PhysicalActors.Add(AvatarMoveActorName, m_moveActor); | 97 | PhysicalActors.Add(AvatarMoveActorName, m_moveActor); |
98 | 98 | ||
99 | DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", | 99 | DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6}", |
100 | LocalID, _size, Scale, Density, _avatarVolume, RawMass); | 100 | LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos); |
101 | 101 | ||
102 | // do actual creation in taint time | 102 | // do actual creation in taint time |
103 | PhysScene.TaintedObject("BSCharacter.create", delegate() | 103 | PhysScene.TaintedObject("BSCharacter.create", delegate() |
@@ -190,6 +190,10 @@ public sealed class BSCharacter : BSPhysObject | |||
190 | } | 190 | } |
191 | 191 | ||
192 | set { | 192 | set { |
193 | // This is how much the avatar size is changing. Positive means getting bigger. | ||
194 | // The avatar altitude must be adjusted for this change. | ||
195 | float heightChange = value.Z - _size.Z; | ||
196 | |||
193 | _size = value; | 197 | _size = value; |
194 | // Old versions of ScenePresence passed only the height. If width and/or depth are zero, | 198 | // Old versions of ScenePresence passed only the height. If width and/or depth are zero, |
195 | // replace with the default values. | 199 | // replace with the default values. |
@@ -207,6 +211,10 @@ public sealed class BSCharacter : BSPhysObject | |||
207 | { | 211 | { |
208 | PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale); | 212 | PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale); |
209 | UpdatePhysicalMassProperties(RawMass, true); | 213 | UpdatePhysicalMassProperties(RawMass, true); |
214 | |||
215 | // Adjust the avatar's position to account for the increase/decrease in size | ||
216 | ForcePosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, RawPosition.Z + heightChange / 2f); | ||
217 | |||
210 | // Make sure this change appears as a property update event | 218 | // Make sure this change appears as a property update event |
211 | PhysScene.PE.PushUpdate(PhysBody); | 219 | PhysScene.PE.PushUpdate(PhysBody); |
212 | } | 220 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 4520171..fcb892a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | |||
@@ -570,9 +570,9 @@ public static class BSParam | |||
570 | new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground", | 570 | new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground", |
571 | -0.2f ), | 571 | -0.2f ), |
572 | new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground", | 572 | new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground", |
573 | 0.1f ), | 573 | 0.2f ), |
574 | new ParameterDefn<float>("AvatarHeightHighFudge", "A fudge factor to make tall avatars stand on the ground", | 574 | new ParameterDefn<float>("AvatarHeightHighFudge", "A fudge factor to make tall avatars stand on the ground", |
575 | 0.1f ), | 575 | 0.2f ), |
576 | new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", | 576 | new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", |
577 | 0.1f ), | 577 | 0.1f ), |
578 | new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground", | 578 | new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground", |