diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index 1c5f558b42..18d008c654 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -287,6 +287,12 @@ namespace OpenSim.Framework public Vector3 AtAxis; public Vector3 LeftAxis; public Vector3 UpAxis; + + /// + /// Signal on a V2 teleport that Scene.IncomingChildAgentDataUpdate(AgentData ad) should wait for the + /// scene presence to become root (triggered when the viewer sends a CompleteAgentMovement UDP packet after + /// establishing the connection triggered by it's receipt of a TeleportFinish EQ message). + /// public bool SenderWantsToWaitForRoot; public float Far; diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs index c8e838cadf..7cf1fa7458 100644 --- a/OpenSim/Framework/Monitoring/StatsManager.cs +++ b/OpenSim/Framework/Monitoring/StatsManager.cs @@ -26,10 +26,12 @@ */ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; +using OpenSim.Framework; using OpenMetaverse.StructuredData; namespace OpenSim.Framework.Monitoring @@ -262,6 +264,41 @@ namespace OpenSim.Framework.Monitoring return map; } + public static Hashtable HandleStatsRequest(Hashtable request) + { + Hashtable responsedata = new Hashtable(); + string regpath = request["uri"].ToString(); + int response_code = 200; + string contenttype = "text/json"; + + string pCategoryName = StatsManager.AllSubCommand; + string pContainerName = StatsManager.AllSubCommand; + string pStatName = StatsManager.AllSubCommand; + + if (request.ContainsKey("cat")) pCategoryName = request["cat"].ToString(); + if (request.ContainsKey("cont")) pContainerName = request["cat"].ToString(); + if (request.ContainsKey("stat")) pStatName = request["cat"].ToString(); + + string strOut = StatsManager.GetStatsAsOSDMap(pCategoryName, pContainerName, pStatName).ToString(); + + // If requestor wants it as a callback function, build response as a function rather than just the JSON string. + if (request.ContainsKey("callback")) + { + strOut = request["callback"].ToString() + "(" + strOut + ");"; + } + + // m_log.DebugFormat("{0} StatFetch: uri={1}, cat={2}, cont={3}, stat={4}, resp={5}", + // LogHeader, regpath, pCategoryName, pContainerName, pStatName, strOut); + + responsedata["int_response_code"] = response_code; + responsedata["content_type"] = contenttype; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = strOut; + responsedata["access_control_allow_origin"] = "*"; + + return responsedata; + } + // /// // /// Start collecting statistics related to assets. // /// Should only be called once. diff --git a/OpenSim/Framework/Tests/LocationTest.cs b/OpenSim/Framework/Tests/LocationTest.cs index af5f164d7f..3d5d1d275b 100644 --- a/OpenSim/Framework/Tests/LocationTest.cs +++ b/OpenSim/Framework/Tests/LocationTest.cs @@ -55,11 +55,18 @@ namespace OpenSim.Framework.Tests Location TestLocation2 = new Location(1095216660736000); Assert.That(TestLocation1 == TestLocation2); + Assert.That(TestLocation1.X == 255000 && TestLocation1.Y == 256000, "Test xy location doesn't match position in the constructor"); Assert.That(TestLocation2.X == 255000 && TestLocation2.Y == 256000, "Test xy location doesn't match regionhandle provided"); Assert.That(TestLocation2.RegionHandle == 1095216660736000, "Location RegionHandle Property didn't match regionhandle provided in constructor"); + ulong RegionHandle = TestLocation1.RegionHandle; + Assert.That(RegionHandle.Equals(1095216660736000), "Equals(regionhandle) failed to match the position in the constructor"); + + TestLocation2 = new Location(RegionHandle); + Assert.That(TestLocation2.Equals(255000, 256000), "Decoded regionhandle failed to match the original position in the constructor"); + TestLocation1 = new Location(255001, 256001); TestLocation2 = new Location(1095216660736000); diff --git a/OpenSim/Framework/Tests/UtilTest.cs b/OpenSim/Framework/Tests/UtilTest.cs index 11ca0683d3..3b7f25299f 100644 --- a/OpenSim/Framework/Tests/UtilTest.cs +++ b/OpenSim/Framework/Tests/UtilTest.cs @@ -282,5 +282,87 @@ namespace OpenSim.Framework.Tests String.Format("Incorrect InventoryType mapped from Content-Type {0}", invcontenttypes[i])); } } + + [Test] + public void FakeParcelIDTests() + { + byte[] hexBytes8 = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }; + byte[] hexBytes16 = { + 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, + 0x77, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f }; + UInt64 var64Bit = (UInt64)0xfedcba9876543210; + + //Region handle is for location 255000,256000. + ulong regionHandle1 = 1095216660736000; + uint x1 = 100; + uint y1 = 200; + uint z1 = 22; + ulong regionHandle2; + uint x2, y2, z2; + UUID fakeParcelID1, fakeParcelID2, uuid; + + ulong bigInt64 = Util.BytesToUInt64Big(hexBytes8); + Assert.AreEqual(var64Bit, bigInt64, + "BytesToUint64Bit conversion of 8 bytes to UInt64 failed."); + + //Test building and decoding using some typical input values + fakeParcelID1 = Util.BuildFakeParcelID(regionHandle1, x1, y1); + Util.ParseFakeParcelID(fakeParcelID1, out regionHandle2, out x2, out y2); + Assert.AreEqual(regionHandle1, regionHandle2, + "region handle decoded from FakeParcelID wth X/Y failed."); + Assert.AreEqual(x1, x2, + "X coordinate decoded from FakeParcelID wth X/Y failed."); + Assert.AreEqual(y1, y2, + "Y coordinate decoded from FakeParcelID wth X/Y failed."); + + fakeParcelID1 = Util.BuildFakeParcelID(regionHandle1, x1, y1, z1); + Util.ParseFakeParcelID(fakeParcelID1, out regionHandle2, out x2, out y2, out z2); + Assert.AreEqual(regionHandle1, regionHandle2, + "region handle decoded from FakeParcelID with X/Y/Z failed."); + Assert.AreEqual(x1, x2, + "X coordinate decoded from FakeParcelID with X/Y/Z failed."); + Assert.AreEqual(y1, y2, + "Y coordinate decoded from FakeParcelID with X/Y/Z failed."); + Assert.AreEqual(z1, z2, + "Z coordinate decoded from FakeParcelID with X/Y/Z failed."); + + //Do some more extreme tests to check the encoding and decoding + x1 = 0x55aa; + y1 = 0x9966; + z1 = 0x5a96; + + fakeParcelID1 = Util.BuildFakeParcelID(var64Bit, x1, y1); + Util.ParseFakeParcelID(fakeParcelID1, out regionHandle2, out x2, out y2); + Assert.AreEqual(var64Bit, regionHandle2, + "region handle decoded from FakeParcelID with X/Y/Z failed."); + Assert.AreEqual(x1, x2, + "X coordinate decoded from FakeParcelID with X/Y/Z failed."); + Assert.AreEqual(y1, y2, + "Y coordinate decoded from FakeParcelID with X/Y/Z failed."); + + fakeParcelID1 = Util.BuildFakeParcelID(var64Bit, x1, y1, z1); + Util.ParseFakeParcelID(fakeParcelID1, out regionHandle2, out x2, out y2, out z2); + Assert.AreEqual(var64Bit, regionHandle2, + "region handle decoded from FakeParcelID with X/Y/Z failed."); + Assert.AreEqual(x1, x2, + "X coordinate decoded from FakeParcelID with X/Y/Z failed."); + Assert.AreEqual(y1, y2, + "Y coordinate decoded from FakeParcelID with X/Y/Z failed."); + Assert.AreEqual(z1, z2, + "Z coordinate decoded from FakeParcelID with X/Y/Z failed."); + + + x1 = 64; + y1 = 192; + fakeParcelID1 = Util.BuildFakeParcelID(regionHandle1, x1, y1); + Util.FakeParcelIDToGlobalPosition(fakeParcelID1, out x2, out y2); + Assert.AreEqual(255000+x1, x2, + "Global X coordinate decoded from regionHandle failed."); + Assert.AreEqual(256000+y1, y2, + "Global Y coordinate decoded from regionHandle failed."); + + uuid = new UUID("00dd0700-00d1-0700-3800-000032000000"); + Util.FakeParcelIDToGlobalPosition(uuid, out x2, out y2); + } } } diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 6a15734d5a..f0e5bc1d13 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1247,7 +1247,7 @@ namespace OpenSim.Framework byte[] bytes = { (byte)regionHandle, (byte)(regionHandle >> 8), (byte)(regionHandle >> 16), (byte)(regionHandle >> 24), - (byte)(regionHandle >> 32), (byte)(regionHandle >> 40), (byte)(regionHandle >> 48), (byte)(regionHandle << 56), + (byte)(regionHandle >> 32), (byte)(regionHandle >> 40), (byte)(regionHandle >> 48), (byte)(regionHandle >> 56), (byte)x, (byte)(x >> 8), 0, 0, (byte)y, (byte)(y >> 8), 0, 0 }; return new UUID(bytes, 0); @@ -1258,7 +1258,7 @@ namespace OpenSim.Framework byte[] bytes = { (byte)regionHandle, (byte)(regionHandle >> 8), (byte)(regionHandle >> 16), (byte)(regionHandle >> 24), - (byte)(regionHandle >> 32), (byte)(regionHandle >> 40), (byte)(regionHandle >> 48), (byte)(regionHandle << 56), + (byte)(regionHandle >> 32), (byte)(regionHandle >> 40), (byte)(regionHandle >> 48), (byte)(regionHandle >> 56), (byte)x, (byte)(x >> 8), (byte)z, (byte)(z >> 8), (byte)y, (byte)(y >> 8), 0, 0 }; return new UUID(bytes, 0); diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 9dcc8dac22..1cdd8683c0 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -172,6 +172,13 @@ namespace OpenSim if (userStatsURI != String.Empty) MainServer.Instance.AddStreamHandler(new OpenSim.UXSimStatusHandler(this)); + if (managedStatsURI != String.Empty) + { + string urlBase = String.Format("/{0}/", managedStatsURI); + MainServer.Instance.AddHTTPHandler(urlBase, StatsManager.HandleStatsRequest); + m_log.InfoFormat("[OPENSIM] Enabling remote managed stats fetch. URL = {0}", urlBase); + } + if (m_console is RemoteConsole) { if (m_consolePort == 0) @@ -348,18 +355,6 @@ namespace OpenSim m_console.Commands.AddCommand("Regions", false, "delete-region", "delete-region ", "Delete a region from disk", RunCommand); - - m_console.Commands.AddCommand("General", false, "modules list", - "modules list", - "List modules", HandleModules); - - m_console.Commands.AddCommand("General", false, "modules load", - "modules load ", - "Load a module", HandleModules); - - m_console.Commands.AddCommand("General", false, "modules unload", - "modules unload ", - "Unload a module", HandleModules); } protected override void ShutdownSpecific() @@ -556,34 +551,6 @@ namespace OpenSim regInfo.EstateSettings.Save(); } - /// - /// Load, Unload, and list Region modules in use - /// - /// - /// - private void HandleModules(string module, string[] cmd) - { - List args = new List(cmd); - args.RemoveAt(0); - string[] cmdparams = args.ToArray(); - - if (cmdparams.Length > 0) - { - switch (cmdparams[0].ToLower()) - { - case "list": - //TODO: Convert to new region modules - break; - case "unload": - //TODO: Convert to new region modules - break; - case "load": - //TODO: Convert to new region modules - break; - } - } - } - /// /// Runs commands issued by the server console from the operator /// diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index f0c088a52b..b032e7fe97 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -75,6 +75,7 @@ namespace OpenSim protected int proxyOffset = 0; public string userStatsURI = String.Empty; + public string managedStatsURI = String.Empty; protected bool m_autoCreateClientStack = true; @@ -188,6 +189,7 @@ namespace OpenSim CreatePIDFile(pidFile); userStatsURI = startupConfig.GetString("Stats_URI", String.Empty); + managedStatsURI = startupConfig.GetString("ManagedStatsRemoteFetchURI", String.Empty); } // Load the simulation data service diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 8b2440a63f..0dbce2fdd5 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -327,7 +327,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private PriorityQueue m_entityProps; private Prioritizer m_prioritizer; private bool m_disableFacelights = false; - + private volatile bool m_justEditedTerrain = false; /// /// List used in construction of data blocks for an object update packet. This is to stop us having to /// continually recreate it. @@ -1239,9 +1239,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP LLHeightFieldMoronize(map); LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); - layerpack.Header.Reliable = true; + + // When a user edits the terrain, so much data is sent, the data queues up fast and presents a sub optimal editing experience. + // To alleviate this issue, when the user edits the terrain, we start skipping the queues until they're done editing the terrain. + // We also make them unreliable because it's extremely likely that multiple packets will be sent for a terrain patch area + // invalidating previous packets for that area. - OutPacket(layerpack, ThrottleOutPacketType.Land); + // It's possible for an editing user to flood themselves with edited packets but the majority of use cases are such that only a + // tiny percentage of users will be editing the terrain. Other, non-editing users will see the edits much slower. + + // 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 + // have rezzed already and therefore this is not likely going to cause any additional issues with lost packets, objects or terrain + // patches. + + // m_justEditedTerrain is volatile, so test once and duplicate two affected statements so we only have one cache miss. + if (m_justEditedTerrain) + { + layerpack.Header.Reliable = false; + OutPacket(layerpack, + ThrottleOutPacketType.Unknown ); + } + else + { + layerpack.Header.Reliable = true; + OutPacket(layerpack, + ThrottleOutPacketType.Land); + } } catch (Exception e) { @@ -6263,6 +6286,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP //m_log.Info("[LAND]: LAND:" + modify.ToString()); if (modify.ParcelData.Length > 0) { + // Note: the ModifyTerrain event handler sends out updated packets before the end of this event. Therefore, + // a simple boolean value should work and perhaps queue up just a few terrain patch packets at the end of the edit. + m_justEditedTerrain = true; // Prevent terrain packet (Land layer) from being queued, make it unreliable if (OnModifyTerrain != null) { for (int i = 0; i < modify.ParcelData.Length; i++) @@ -6278,6 +6304,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } } + m_justEditedTerrain = false; // Queue terrain packet (Land layer) if necessary, make it reliable again } return true; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 96cd6b9e6c..01ef710387 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -688,8 +688,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (version.Equals("SIMULATION/0.2")) TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason); else - TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason); - + TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason); } private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination, @@ -698,7 +697,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer ulong destinationHandle = finalDestination.RegionHandle; AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Using TP V1"); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Using TP V1 for {0} going from {1} to {2}", + sp.Name, Scene.Name, finalDestination.RegionName); + // Let's create an agent there if one doesn't exist yet. // NOTE: logout will always be false for a non-HG teleport. bool logout = false; @@ -956,6 +958,27 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } + if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling) + { + m_interRegionTeleportCancels.Value++; + + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", + sp.Name, finalDestination.RegionName, sp.Scene.Name); + + return; + } + else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) + { + m_interRegionTeleportAborts.Value++; + + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.", + sp.Name, finalDestination.RegionName, sp.Scene.Name); + + return; + } + // Past this point we have to attempt clean up if the teleport fails, so update transfer state. m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); @@ -1058,20 +1081,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!sp.DoNotCloseAfterTeleport) { // OK, it got this agent. Let's close everything - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing in agent {0} in region {1}", sp.Name, Scene.RegionInfo.RegionName); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing in agent {0} in region {1}", sp.Name, Scene.Name); sp.CloseChildAgents(newRegionX, newRegionY); sp.Scene.IncomingCloseAgent(sp.UUID, false); } else { - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {0}", sp.Name, Scene.RegionInfo.RegionName); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {0}", sp.Name, Scene.Name); sp.DoNotCloseAfterTeleport = false; } } else + { // now we have a child agent in this region. sp.Reset(); + } } /// diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index a515346260..6da22228d9 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 { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static string LogHeader = "[MODULE COMMS]"; private Dictionary m_constants = new Dictionary(); @@ -148,7 +149,7 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms MethodInfo mi = GetMethodInfoFromType(target.GetType(), meth, true); if (mi == null) { - m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}", meth); + m_log.WarnFormat("{0} Failed to register method {1}", LogHeader, meth); return; } @@ -165,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms { // m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, (target is Type) ? ((Type)target).Name : target.GetType().Name); - Type delegateType; + Type delegateType = typeof(void); List typeArgs = mi.GetParameters() .Select(p => p.ParameterType) .ToList(); @@ -176,8 +177,16 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms } else { - typeArgs.Add(mi.ReturnType); - delegateType = Expression.GetFuncType(typeArgs.ToArray()); + try + { + typeArgs.Add(mi.ReturnType); + delegateType = Expression.GetFuncType(typeArgs.ToArray()); + } + catch (Exception e) + { + m_log.ErrorFormat("{0} Failed to create function signature. Most likely more than 5 parameters. Method={1}. Error={2}", + LogHeader, mi.Name, e); + } } Delegate fcall; diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs index 4d49794347..173b603fe5 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 " that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3, all corners = -1.", consoleSetTerrainHeights); + m_module.Scene.AddCommand("Regions", m_module, "set water height", + "set water height [] []", + "Sets the water height in meters. If and are specified, it will only set it on regions with a matching coordinate. " + + "Specify -1 in or to wildcard that coordinate.", + consoleSetWaterHeight); + + m_module.Scene.AddCommand( "Estates", m_module, "estate show", "estate show", "Shows all estates on the simulator.", ShowEstatesCommand); } @@ -121,7 +128,29 @@ namespace OpenSim.Region.CoreModules.World.Estate } } } - + protected void consoleSetWaterHeight(string module, string[] args) + { + string heightstring = args[3]; + + int x = (args.Length > 4 ? int.Parse(args[4]) : -1); + int y = (args.Length > 5 ? int.Parse(args[5]) : -1); + + if (x == -1 || m_module.Scene.RegionInfo.RegionLocX == x) + { + if (y == -1 || m_module.Scene.RegionInfo.RegionLocY == y) + { + double selectedheight = double.Parse(heightstring); + + m_log.Debug("[ESTATEMODULE]: Setting water height in " + m_module.Scene.RegionInfo.RegionName + " to " + + string.Format(" {0}", selectedheight)); + m_module.Scene.RegionInfo.RegionSettings.WaterHeight = selectedheight; + + m_module.Scene.RegionInfo.RegionSettings.Save(); + m_module.TriggerRegionInfoChange(); + m_module.sendRegionHandshakeToAll(); + } + } + } protected void consoleSetTerrainHeights(string module, string[] args) { string num = args[3]; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 1633e07d0e..b97a0f6eab 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4222,36 +4222,42 @@ namespace OpenSim.Region.Framework.Scenes } // We have to wait until the viewer contacts this region - // after receiving the EnableSimulator HTTP Event Queue message. This triggers the viewer to send + // after receiving the EnableSimulator HTTP Event Queue message (for the v1 teleport protocol) + // or TeleportFinish (for the v2 teleport protocol). This triggers the viewer to send // a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence. - ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); + ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID); - if (childAgentUpdate != null) + if (sp != null) { - if (cAgentData.SessionID != childAgentUpdate.ControllingClient.SessionId) + if (cAgentData.SessionID != sp.ControllingClient.SessionId) { - m_log.WarnFormat("[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).", childAgentUpdate.UUID, cAgentData.SessionID); + m_log.WarnFormat( + "[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).", + sp.UUID, cAgentData.SessionID); + Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}", - childAgentUpdate.UUID, childAgentUpdate.ControllingClient.SessionId, cAgentData.SessionID)); + sp.UUID, sp.ControllingClient.SessionId, cAgentData.SessionID)); } - childAgentUpdate.ChildAgentDataUpdate(cAgentData); + sp.ChildAgentDataUpdate(cAgentData); int ntimes = 20; if (cAgentData.SenderWantsToWaitForRoot) { - while (childAgentUpdate.IsChildAgent && ntimes-- > 0) + while (sp.IsChildAgent && ntimes-- > 0) Thread.Sleep(1000); m_log.DebugFormat( "[SCENE]: Found presence {0} {1} {2} in {3} after {4} waits", - childAgentUpdate.Name, childAgentUpdate.UUID, childAgentUpdate.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 20 - ntimes); + sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", Name, 20 - ntimes); - if (childAgentUpdate.IsChildAgent) + if (sp.IsChildAgent) return false; } + return true; } + return false; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0ba2dabe5e..1b8c2760ca 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -285,9 +285,23 @@ namespace OpenSim.Region.Framework.Scenes /// private Vector3 posLastSignificantMove; - // For teleports and crossings callbacks - string m_callbackURI; - UUID m_originRegionID; + #region For teleports and crossings callbacks + + /// + /// In the V1 teleport protocol, the destination simulator sends ReleaseAgent to this address. + /// + private string m_callbackURI; + + public UUID m_originRegionID; + + /// + /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent + /// teleport is reusing the connection. + /// + /// May be refactored or move somewhere else soon. + public bool DoNotCloseAfterTeleport { get; set; } + + #endregion /// /// Script engines present in the scene @@ -717,13 +731,6 @@ namespace OpenSim.Region.Framework.Scenes } } - /// - /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent - /// teleport is reusing the connection. - /// - /// May be refactored or move somewhere else soon. - public bool DoNotCloseAfterTeleport { get; set; } - private float m_speedModifier = 1.0f; public float SpeedModifier @@ -1325,14 +1332,14 @@ namespace OpenSim.Region.Framework.Scenes int count = 20; while (m_originRegionID.Equals(UUID.Zero) && count-- > 0) { - m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.RegionInfo.RegionName); + m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name); Thread.Sleep(200); } if (m_originRegionID.Equals(UUID.Zero)) { // Movement into region will fail - m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived", client.Name); + m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived in {1}", client.Name, Scene.Name); return false; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 58a417ed8f..9af3dcea48 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -96,8 +96,8 @@ public sealed class BSCharacter : BSPhysObject m_moveActor = new BSActorAvatarMove(PhysScene, this, AvatarMoveActorName); PhysicalActors.Add(AvatarMoveActorName, m_moveActor); - DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", - LocalID, _size, Scale, Density, _avatarVolume, RawMass); + DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6}", + LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos); // do actual creation in taint time PhysScene.TaintedObject("BSCharacter.create", delegate() @@ -190,6 +190,10 @@ public sealed class BSCharacter : BSPhysObject } set { + // This is how much the avatar size is changing. Positive means getting bigger. + // The avatar altitude must be adjusted for this change. + float heightChange = value.Z - _size.Z; + _size = value; // Old versions of ScenePresence passed only the height. If width and/or depth are zero, // replace with the default values. @@ -207,6 +211,10 @@ public sealed class BSCharacter : BSPhysObject { PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale); UpdatePhysicalMassProperties(RawMass, true); + + // Adjust the avatar's position to account for the increase/decrease in size + ForcePosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, RawPosition.Z + heightChange / 2f); + // Make sure this change appears as a property update event PhysScene.PE.PushUpdate(PhysBody); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 452017177f..fcb892a4f1 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -570,9 +570,9 @@ public static class BSParam new ParameterDefn("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground", -0.2f ), new ParameterDefn("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground", - 0.1f ), + 0.2f ), new ParameterDefn("AvatarHeightHighFudge", "A fudge factor to make tall avatars stand on the ground", - 0.1f ), + 0.2f ), new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", 0.1f ), new ParameterDefn("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground", diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index d5d29ec674..0a85085872 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -264,8 +264,15 @@ ; Simulator Stats URI ; Enable JSON simulator data by setting a URI name (case sensitive) + ; Returns regular sim stats (SimFPS, ...) ; Stats_URI = "jsonSimStats" + ; Simulator StatsManager URI + ; Enable fetch of StatsManager registered stats. Fetch is query which can optionally + ; specify category, container and stat to fetch. If not selected, returns all of that type. + ; http://simulatorHTTPport/ManagedStats/?cat=Category&cont=Container&stat=Statistic + ; ManagedStatsRemoteFetchURI = "ManagedStats" + ; Make OpenSim start all regions woth logins disabled. They will need ; to be enabled from the console if this is set ; StartDisabled = false