diff --git a/OpenSim/Data/IXAssetDataPlugin.cs b/OpenSim/Data/IXAssetDataPlugin.cs new file mode 100644 index 0000000000..74ad6f497d --- /dev/null +++ b/OpenSim/Data/IXAssetDataPlugin.cs @@ -0,0 +1,47 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System.Collections.Generic; +using OpenMetaverse; +using OpenSim.Framework; + +namespace OpenSim.Data +{ + /// + /// This interface exists to distinguish between the normal IAssetDataPlugin and the one used by XAssetService + /// for now. + /// + public interface IXAssetDataPlugin : IPlugin + { + AssetBase GetAsset(UUID uuid); + void StoreAsset(AssetBase asset); + bool ExistsAsset(UUID uuid); + List FetchAssetMetadataSet(int start, int count); + void Initialise(string connect); + bool Delete(string id); + } +} \ No newline at end of file diff --git a/OpenSim/Data/MySQL/MySQLXAssetData.cs b/OpenSim/Data/MySQL/MySQLXAssetData.cs index 06fe55a9b3..e6ac22e09c 100644 --- a/OpenSim/Data/MySQL/MySQLXAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLXAssetData.cs @@ -41,7 +41,7 @@ using OpenSim.Data; namespace OpenSim.Data.MySQL { - public class MySQLXAssetData : AssetDataBase + public class MySQLXAssetData : IXAssetDataPlugin { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -61,7 +61,7 @@ namespace OpenSim.Data.MySQL #region IPlugin Members - public override string Version { get { return "1.0.0.0"; } } + public string Version { get { return "1.0.0.0"; } } /// /// Initialises Asset interface @@ -74,7 +74,7 @@ namespace OpenSim.Data.MySQL /// /// /// connect string - public override void Initialise(string connect) + public void Initialise(string connect) { m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************"); m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************"); @@ -96,17 +96,17 @@ namespace OpenSim.Data.MySQL } } - public override void Initialise() + public void Initialise() { throw new NotImplementedException(); } - public override void Dispose() { } + public void Dispose() { } /// /// The name of this DB provider /// - override public string Name + public string Name { get { return "MySQL XAsset storage engine"; } } @@ -121,7 +121,7 @@ namespace OpenSim.Data.MySQL /// Asset UUID to fetch /// Return the asset /// On failure : throw an exception and attempt to reconnect to database - override public AssetBase GetAsset(UUID assetID) + public AssetBase GetAsset(UUID assetID) { // m_log.DebugFormat("[MYSQL XASSET DATA]: Looking for asset {0}", assetID); @@ -190,7 +190,7 @@ namespace OpenSim.Data.MySQL /// /// Asset UUID to create /// On failure : Throw an exception and attempt to reconnect to database - override public void StoreAsset(AssetBase asset) + public void StoreAsset(AssetBase asset) { lock (m_dbLock) { @@ -380,7 +380,7 @@ namespace OpenSim.Data.MySQL /// /// The asset UUID /// true if it exists, false otherwise. - override public bool ExistsAsset(UUID uuid) + public bool ExistsAsset(UUID uuid) { // m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid); @@ -426,7 +426,7 @@ namespace OpenSim.Data.MySQL /// The number of results to discard from the total data set. /// The number of rows the returned list should contain. /// A list of AssetMetadata objects. - public override List FetchAssetMetadataSet(int start, int count) + public List FetchAssetMetadataSet(int start, int count) { List retList = new List(count); @@ -471,7 +471,7 @@ namespace OpenSim.Data.MySQL return retList; } - public override bool Delete(string id) + public bool Delete(string id) { // m_log.DebugFormat("[XASSETS DB]: Deleting asset {0}", id); diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 0b9e0e7bea..26b70708c5 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1758,13 +1758,26 @@ namespace OpenSim.Framework /// and negative every 24.9 days. Subtracts the passed value (previously fetched by /// 'EnvironmentTickCount()') and accounts for any wrapping. /// + /// + /// /// subtraction of passed prevValue from current Environment.TickCount - public static Int32 EnvironmentTickCountSubtract(Int32 prevValue) + public static Int32 EnvironmentTickCountSubtract(Int32 newValue, Int32 prevValue) { - Int32 diff = EnvironmentTickCount() - prevValue; + Int32 diff = newValue - prevValue; return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); } + /// + /// Environment.TickCount is an int but it counts all 32 bits so it goes positive + /// and negative every 24.9 days. Subtracts the passed value (previously fetched by + /// 'EnvironmentTickCount()') and accounts for any wrapping. + /// + /// subtraction of passed prevValue from current Environment.TickCount + public static Int32 EnvironmentTickCountSubtract(Int32 prevValue) + { + return EnvironmentTickCountSubtract(EnvironmentTickCount(), prevValue); + } + // Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount // Assumes both tcA and tcB came from previous calls to Util.EnvironmentTickCount(). // A positive return value indicates A occured later than B @@ -1927,12 +1940,12 @@ namespace OpenSim.Framework #region Universal User Identifiers /// /// - /// uuid[;endpoint[;first last[;secret]]] - /// the uuid part - /// the endpoint part (e.g. http://foo.com) - /// the first name part (e.g. Test) - /// the last name part (e.g User) - /// the secret part + /// uuid[;endpoint[;first last[;secret]]] + /// the uuid part + /// the endpoint part (e.g. http://foo.com) + /// the first name part (e.g. Test) + /// the last name part (e.g User) + /// the secret part public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret) { uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty; @@ -1961,64 +1974,79 @@ namespace OpenSim.Framework } /// - /// Produces a universal (HG) system-facing identifier given the information + /// Produces a universal (HG) system-facing identifier given the information /// /// - /// uuid[;homeURI[;first last]] + /// uuid[;homeURI[;first last]] public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit) { if (acircuit.ServiceURLs.ContainsKey("HomeURI")) - return UniversalIdentifier(acircuit.AgentID, acircuit.firstname, acircuit.lastname, acircuit.ServiceURLs["HomeURI"].ToString()); - else - return acircuit.AgentID.ToString(); - } - - /// - /// Produces a universal (HG) system-facing identifier given the information - /// - /// UUID of the user - /// first name (e.g Test) - /// last name (e.g. User) - /// homeURI (e.g. http://foo.com) - /// a string of the form uuid[;homeURI[;first last]] - public static string UniversalIdentifier(UUID id, String firstName, String lastName, String homeURI) - { - string agentsURI = homeURI; - if (!agentsURI.EndsWith("/")) - agentsURI += "/"; - - // This is ugly, but there's no other way, given that the name is changed - // in the agent circuit data for foreigners - if (lastName.Contains("@")) + return UniversalIdentifier(acircuit.AgentID, acircuit.firstname, acircuit.lastname, acircuit.ServiceURLs["HomeURI"].ToString()); + else + return acircuit.AgentID.ToString(); + } + + /// + /// Produces a universal (HG) system-facing identifier given the information + /// + /// UUID of the user + /// first name (e.g Test) + /// last name (e.g. User) + /// homeURI (e.g. http://foo.com) + /// a string of the form uuid[;homeURI[;first last]] + public static string UniversalIdentifier(UUID id, String firstName, String lastName, String homeURI) + { + string agentsURI = homeURI; + if (!agentsURI.EndsWith("/")) + agentsURI += "/"; + + // This is ugly, but there's no other way, given that the name is changed + // in the agent circuit data for foreigners + if (lastName.Contains("@")) { - string[] parts = firstName.Split(new char[] { '.' }); - if (parts.Length == 2) - return id.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1]; - } - return id.ToString() + ";" + agentsURI + ";" + firstName + " " + lastName; - - } + string agentsURI = acircuit.ServiceURLs["HomeURI"].ToString(); + if (!agentsURI.EndsWith("/")) + agentsURI += "/"; + string[] parts = firstName.Split(new char[] { '.' }); + if (parts.Length == 2) + return id.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1]; + } + return id.ToString() + ";" + agentsURI + ";" + firstName + " " + lastName; + + } - /// - /// Produces a universal (HG) user-facing name given the information - /// - /// - /// - /// - /// string of the form first.last @foo.com or first last - public static string UniversalName(String firstName, String lastName, String homeURI) - { - Uri uri = null; - try - { - uri = new Uri(homeURI); + // This is ugly, but there's no other way, given that the name is changed + // in the agent circuit data for foreigners + if (acircuit.lastname.Contains("@")) + { + string[] parts = acircuit.firstname.Split(new char[] { '.' }); + if (parts.Length == 2) + return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1]; + } + return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + acircuit.firstname + " " + acircuit.lastname; + /// + /// Produces a universal (HG) user-facing name given the information + /// + /// + /// + /// + /// string of the form first.last @foo.com or first last + public static string UniversalName(String firstName, String lastName, String homeURI) + { + Uri uri = null; + try + { + uri = new Uri(homeURI); } - catch (UriFormatException) - { - return firstName + " " + lastName; - } - return firstName + "." + lastName + " " + "@" + uri.Authority; - } + else + return acircuit.AgentID.ToString(); + } + catch (UriFormatException) + { + return firstName + " " + lastName; + } + return firstName + "." + lastName + " " + "@" + uri.Authority; + } #endregion } } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 35cb575c2f..ed3430a319 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -761,7 +761,7 @@ namespace OpenSim.Region.ClientStack.Linden SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID); if (part != null) { - TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID); +// TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID); if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, m_HostCapsObj.AgentID)) { return LLSDHelpers.SerialiseLLSDReply(response); diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs index fb94355df6..d76927be9f 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests m_regStatus = RegionStatus.Up; } - public override void Update() {} + public override void Update(int frames) {} public override void LoadWorldMap() {} public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs index c982db61fc..267fb9ead9 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs @@ -93,8 +93,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization scene.RegisterModuleInterface(this); m_Scene = scene; - - scene.EventManager.OnLoginsEnabled += new EventManager.LoginsEnabled(OnLoginsEnabled); } public void RemoveRegion(Scene scene) @@ -106,16 +104,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization if (!m_Enabled) return; + m_AuthorizationService = new AuthorizationService(m_AuthorizationConfig, m_Scene); + m_log.InfoFormat( "[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}", scene.RegionInfo.RegionName); } - private void OnLoginsEnabled(string regionName) - { - m_AuthorizationService = new AuthorizationService(m_AuthorizationConfig, m_Scene); - } - public bool IsAuthorizedForRegion( string userID, string firstName, string lastName, string regionID, out string message) { diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 61d604ff3d..4c6f73eec3 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -604,7 +604,6 @@ namespace OpenSim.Region.CoreModules.World.Estate public void handleOnEstateManageTelehub (IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1) { - uint ObjectLocalID; SceneObjectPart part; switch (cmd) @@ -877,7 +876,6 @@ namespace OpenSim.Region.CoreModules.World.Estate return; Dictionary sceneData = null; - List uuidNameLookupList = new List(); if (reportType == 1) { diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 6ff2a6f39c..1e1fcb7a5e 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -481,6 +481,13 @@ namespace OpenSim.Region.Framework.Scenes public event RegionHeartbeatEnd OnRegionHeartbeatEnd; public delegate void LoginsEnabled(string regionName); + + /// + /// This should only fire in all circumstances if the RegionReady module is active. + /// + /// + /// TODO: Fire this even when the RegionReady module is not active. + /// public event LoginsEnabled OnLoginsEnabled; public delegate void PrimsLoaded(Scene s); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 0706905689..790ec637b8 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -190,7 +190,11 @@ namespace OpenSim.Region.Framework.Scenes private int backupMS; private int terrainMS; private int landMS; - private int lastCompletedFrame; + + /// + /// Tick at which the last frame was processed. + /// + private int m_lastFrameTick; /// /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched @@ -464,7 +468,7 @@ namespace OpenSim.Region.Framework.Scenes public int MonitorBackupTime { get { return backupMS; } } public int MonitorTerrainTime { get { return terrainMS; } } public int MonitorLandTime { get { return landMS; } } - public int MonitorLastFrameTick { get { return lastCompletedFrame; } } + public int MonitorLastFrameTick { get { return m_lastFrameTick; } } public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } } public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } } @@ -1175,18 +1179,15 @@ namespace OpenSim.Region.Framework.Scenes // The first frame can take a very long time due to physics actors being added on startup. Therefore, // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false // alarms for scenes with many objects. - Update(); + Update(1); Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; while (!shuttingdown) - Update(); + Update(-1); m_lastUpdate = Util.EnvironmentTickCount(); m_firstHeartbeat = false; } - catch (ThreadAbortException) - { - } finally { Monitor.Pulse(m_heartbeatLock); @@ -1196,188 +1197,207 @@ namespace OpenSim.Region.Framework.Scenes Watchdog.RemoveThread(); } - public override void Update() + public override void Update(int frames) { + long? endFrame = null; + + if (frames >= 0) + endFrame = Frame + frames; + float physicsFPS = 0f; + int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS; + int previousFrameTick; + int maintc; + List coarseLocations; + List avatarUUIDs; - int maintc = Util.EnvironmentTickCount(); - int tmpFrameMS = maintc; - agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0; - - ++Frame; + while (!shuttingdown && (endFrame == null || Frame < endFrame)) + { + maintc = Util.EnvironmentTickCount(); + ++Frame; // m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName); - try - { - int tmpPhysicsMS2 = Util.EnvironmentTickCount(); - if ((Frame % m_update_physics == 0) && m_physics_enabled) - m_sceneGraph.UpdatePreparePhysics(); - physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2); + agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0; - // Apply any pending avatar force input to the avatar's velocity - int tmpAgentMS = Util.EnvironmentTickCount(); - if (Frame % m_update_entitymovement == 0) - m_sceneGraph.UpdateScenePresenceMovement(); - agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS); - - // Perform the main physics update. This will do the actual work of moving objects and avatars according to their - // velocity - int tmpPhysicsMS = Util.EnvironmentTickCount(); - if (Frame % m_update_physics == 0) + try { - if (m_physics_enabled) - physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime); - - if (SynchronizeScene != null) - SynchronizeScene(this); - } - physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS); - - tmpAgentMS = Util.EnvironmentTickCount(); - - // Check if any objects have reached their targets - CheckAtTargets(); - - // Update SceneObjectGroups that have scheduled themselves for updates - // Objects queue their updates onto all scene presences - if (Frame % m_update_objects == 0) - m_sceneGraph.UpdateObjectGroups(); - - // Run through all ScenePresences looking for updates - // Presence updates and queued object updates for each presence are sent to clients - if (Frame % m_update_presences == 0) - m_sceneGraph.UpdatePresences(); - - // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) - if (Frame % m_update_coarse_locations == 0) - { - List coarseLocations; - List avatarUUIDs; - SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60); - // Send coarse locations to clients - ForEachScenePresence(delegate(ScenePresence presence) + tmpPhysicsMS2 = Util.EnvironmentTickCount(); + if ((Frame % m_update_physics == 0) && m_physics_enabled) + m_sceneGraph.UpdatePreparePhysics(); + physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2); + + // Apply any pending avatar force input to the avatar's velocity + tmpAgentMS = Util.EnvironmentTickCount(); + if (Frame % m_update_entitymovement == 0) + m_sceneGraph.UpdateScenePresenceMovement(); + agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS); + + // Perform the main physics update. This will do the actual work of moving objects and avatars according to their + // velocity + tmpPhysicsMS = Util.EnvironmentTickCount(); + if (Frame % m_update_physics == 0) { - presence.SendCoarseLocations(coarseLocations, avatarUUIDs); - }); - } - - agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS); - - // Delete temp-on-rez stuff - if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps) - { - int tmpTempOnRezMS = Util.EnvironmentTickCount(); - m_cleaningTemps = true; - Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; }); - tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS); - } - - if (Frame % m_update_events == 0) - { - int evMS = Util.EnvironmentTickCount(); - UpdateEvents(); - eventMS = Util.EnvironmentTickCountSubtract(evMS); ; - } - - if (Frame % m_update_backup == 0) - { - int backMS = Util.EnvironmentTickCount(); - UpdateStorageBackup(); - backupMS = Util.EnvironmentTickCountSubtract(backMS); - } - - if (Frame % m_update_terrain == 0) - { - int terMS = Util.EnvironmentTickCount(); - UpdateTerrain(); - terrainMS = Util.EnvironmentTickCountSubtract(terMS); - } - - //if (Frame % m_update_land == 0) - //{ - // int ldMS = Util.EnvironmentTickCount(); - // UpdateLand(); - // landMS = Util.EnvironmentTickCountSubtract(ldMS); - //} - - frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS); - otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS; - lastCompletedFrame = Util.EnvironmentTickCount(); - - // if (Frame%m_update_avatars == 0) - // UpdateInWorldTime(); - StatsReporter.AddPhysicsFPS(physicsFPS); - StatsReporter.AddTimeDilation(TimeDilation); - StatsReporter.AddFPS(1); - StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount()); - StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount()); - StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount()); - StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount()); - StatsReporter.addFrameMS(frameMS); - StatsReporter.addAgentMS(agentMS); - StatsReporter.addPhysicsMS(physicsMS + physicsMS2); - StatsReporter.addOtherMS(otherMS); - StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount()); - StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); - - if (LoginsDisabled && Frame == 20) - { -// m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock); - - // In 99.9% of cases it is a bad idea to manually force garbage collection. However, - // this is a rare case where we know we have just went through a long cycle of heap - // allocations, and there is no more work to be done until someone logs in - GC.Collect(); - - IConfig startupConfig = m_config.Configs["Startup"]; - if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) - { - // This handles a case of a region having no scripts for the RegionReady module - if (m_sceneGraph.GetActiveScriptsCount() == 0) - { - // need to be able to tell these have changed in RegionReady - LoginLock = false; - EventManager.TriggerLoginsEnabled(RegionInfo.RegionName); - } - m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); - - // For RegionReady lockouts - if(LoginLock == false) - { - LoginsDisabled = false; - } - - m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface(), RegionInfo); + if (m_physics_enabled) + physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime); + + if (SynchronizeScene != null) + SynchronizeScene(this); } - else + physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS); + + tmpAgentMS = Util.EnvironmentTickCount(); + + // Check if any objects have reached their targets + CheckAtTargets(); + + // Update SceneObjectGroups that have scheduled themselves for updates + // Objects queue their updates onto all scene presences + if (Frame % m_update_objects == 0) + m_sceneGraph.UpdateObjectGroups(); + + // Run through all ScenePresences looking for updates + // Presence updates and queued object updates for each presence are sent to clients + if (Frame % m_update_presences == 0) + m_sceneGraph.UpdatePresences(); + + // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) + if (Frame % m_update_coarse_locations == 0) { - StartDisabled = true; - LoginsDisabled = true; + SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60); + // Send coarse locations to clients + ForEachScenePresence(delegate(ScenePresence presence) + { + presence.SendCoarseLocations(coarseLocations, avatarUUIDs); + }); + } + + agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS); + + // Delete temp-on-rez stuff + if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps) + { + tmpTempOnRezMS = Util.EnvironmentTickCount(); + m_cleaningTemps = true; + Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; }); + tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS); + } + + if (Frame % m_update_events == 0) + { + evMS = Util.EnvironmentTickCount(); + UpdateEvents(); + eventMS = Util.EnvironmentTickCountSubtract(evMS); + } + + if (Frame % m_update_backup == 0) + { + backMS = Util.EnvironmentTickCount(); + UpdateStorageBackup(); + backupMS = Util.EnvironmentTickCountSubtract(backMS); + } + + if (Frame % m_update_terrain == 0) + { + terMS = Util.EnvironmentTickCount(); + UpdateTerrain(); + terrainMS = Util.EnvironmentTickCountSubtract(terMS); + } + + //if (Frame % m_update_land == 0) + //{ + // int ldMS = Util.EnvironmentTickCount(); + // UpdateLand(); + // landMS = Util.EnvironmentTickCountSubtract(ldMS); + //} + + frameMS = Util.EnvironmentTickCountSubtract(maintc); + otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS; + + // if (Frame%m_update_avatars == 0) + // UpdateInWorldTime(); + StatsReporter.AddPhysicsFPS(physicsFPS); + StatsReporter.AddTimeDilation(TimeDilation); + StatsReporter.AddFPS(1); + StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount()); + StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount()); + StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount()); + StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount()); + + // frameMS currently records work frame times, not total frame times (work + any required sleep to + // reach min frame time. + StatsReporter.addFrameMS(frameMS); + + StatsReporter.addAgentMS(agentMS); + StatsReporter.addPhysicsMS(physicsMS + physicsMS2); + StatsReporter.addOtherMS(otherMS); + StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount()); + StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); + + if (LoginsDisabled && Frame == 20) + { + // m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock); + + // In 99.9% of cases it is a bad idea to manually force garbage collection. However, + // this is a rare case where we know we have just went through a long cycle of heap + // allocations, and there is no more work to be done until someone logs in + GC.Collect(); + + IConfig startupConfig = m_config.Configs["Startup"]; + if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) + { + // This handles a case of a region having no scripts for the RegionReady module + if (m_sceneGraph.GetActiveScriptsCount() == 0) + { + // need to be able to tell these have changed in RegionReady + LoginLock = false; + EventManager.TriggerLoginsEnabled(RegionInfo.RegionName); + } + m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); + + // For RegionReady lockouts + if(LoginLock == false) + { + LoginsDisabled = false; + } + + m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface(), RegionInfo); + } + else + { + StartDisabled = true; + LoginsDisabled = true; + } } } + catch (Exception e) + { + m_log.ErrorFormat( + "[SCENE]: Failed on region {0} with exception {1}{2}", + RegionInfo.RegionName, e.Message, e.StackTrace); + } + + EventManager.TriggerRegionHeartbeatEnd(this); + + // Tell the watchdog that this thread is still alive + Watchdog.UpdateThread(); + +// previousFrameTick = m_lastFrameTick; + m_lastFrameTick = Util.EnvironmentTickCount(); + maintc = Util.EnvironmentTickCountSubtract(m_lastFrameTick, maintc); + maintc = (int)(MinFrameTime * 1000) - maintc; + + if (maintc > 0) + Thread.Sleep(maintc); + + // Optionally warn if a frame takes double the amount of time that it should. +// if (Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2)) +// m_log.WarnFormat( +// "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}", +// Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick), +// MinFrameTime * 1000, +// RegionInfo.RegionName); } - catch (NotImplementedException) - { - throw; - } - catch (Exception e) - { - m_log.ErrorFormat( - "[SCENE]: Failed on region {0} with exception {1}{2}", - RegionInfo.RegionName, e.Message, e.StackTrace); - } - - EventManager.TriggerRegionHeartbeatEnd(this); - - maintc = Util.EnvironmentTickCountSubtract(maintc); - maintc = (int)(MinFrameTime * 1000) - maintc; - - if (maintc > 0) - Thread.Sleep(maintc); - - // Tell the watchdog that this thread is still alive - Watchdog.UpdateThread(); } public void AddGroupTarget(SceneObjectGroup grp) diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index 495cede3d2..9c6b8842f9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs @@ -149,9 +149,13 @@ namespace OpenSim.Region.Framework.Scenes #region Update Methods /// - /// Normally called once every frame/tick to let the world preform anything required (like running the physics simulation) + /// Called to update the scene loop by a number of frames and until shutdown. /// - public abstract void Update(); + /// + /// Number of frames to update. Exits on shutdown even if there are frames remaining. + /// If -1 then updates until shutdown. + /// + public abstract void Update(int frames); #endregion diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b84660a1be..704d12d58d 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2293,7 +2293,7 @@ namespace OpenSim.Region.Framework.Scenes { if (direc.Z > 2.0f) { - direc.Z *= 3.0f; + direc.Z *= 2.6f; // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. Animator.TrySetMovementAnimation("PREJUMP"); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs index 442cb8b54a..cfea10d710 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs @@ -81,7 +81,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests // For now, we'll make the scene presence fly to simplify this test, but this needs to change. sp.Flying = true; - m_scene.Update(); + m_scene.Update(1); Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos)); Vector3 targetPos = startPos + new Vector3(0, 10, 0); @@ -91,7 +91,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That( sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001)); - m_scene.Update(); + m_scene.Update(1); // We should really check the exact figure. Assert.That(sp.AbsolutePosition.X, Is.EqualTo(startPos.X)); @@ -99,8 +99,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); Assert.That(sp.AbsolutePosition.Z, Is.LessThan(targetPos.X)); - for (int i = 0; i < 10; i++) - m_scene.Update(); + m_scene.Update(10); double distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos); Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on first move"); @@ -116,7 +115,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That( sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001)); - m_scene.Update(); + m_scene.Update(1); // We should really check the exact figure. Assert.That(sp.AbsolutePosition.X, Is.GreaterThan(startPos.X)); @@ -124,8 +123,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(sp.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); - for (int i = 0; i < 10; i++) - m_scene.Update(); + m_scene.Update(10); distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos); Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on second move"); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index c5a76b2683..bebc10ca25 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -63,17 +63,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests Thread testThread = new Thread(testClass.run); - try - { - // Seems kind of redundant to start a thread and then join it, however.. We need to protect against - // A thread abort exception in the simulator code. - testThread.Start(); - testThread.Join(); - } - catch (ThreadAbortException) - { - - } + // Seems kind of redundant to start a thread and then join it, however.. We need to protect against + // A thread abort exception in the simulator code. + testThread.Start(); + testThread.Join(); + Assert.That(testClass.results.Result, Is.EqualTo(true), testClass.results.Message); // Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod()); } diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs index 8b8aea58e4..5c9a77db67 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs @@ -61,7 +61,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestHelpers.InMethod(); Scene scene = SceneHelpers.SetupScene(); - scene.Update(); + scene.Update(1); Assert.That(scene.Frame, Is.EqualTo(1)); } diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 9a7e9e8b95..eea0b2e6ad 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -238,7 +238,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests // For now, we'll make the scene presence fly to simplify this test, but this needs to change. npc.Flying = true; - m_scene.Update(); + m_scene.Update(1); Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); Vector3 targetPos = startPos + new Vector3(0, 10, 0); @@ -249,7 +249,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests Assert.That( npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001)); - m_scene.Update(); + m_scene.Update(1); // We should really check the exact figure. Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X)); @@ -257,8 +257,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X)); - for (int i = 0; i < 10; i++) - m_scene.Update(); + m_scene.Update(10); double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move"); @@ -275,7 +274,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests Assert.That( npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001)); - m_scene.Update(); + m_scene.Update(1); // We should really check the exact figure. Assert.That(npc.AbsolutePosition.X, Is.GreaterThan(startPos.X)); @@ -283,8 +282,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); - for (int i = 0; i < 10; i++) - m_scene.Update(); + m_scene.Update(10); distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on second move"); diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 6f6ed7f1fc..3bd15ce5af 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -358,7 +358,7 @@ namespace OpenSim.Region.Physics.Meshing if (physicsParms == null) { - m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset"); + m_log.WarnFormat("[MESH]: No recognized physics mesh found in mesh asset for {0}", primName); return false; } diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 6d1f41da05..8397eb4331 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -114,6 +114,11 @@ namespace OpenSim.Region.Physics.OdePlugin private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes. + /// + /// Base movement for calculating tilt. + /// + private float m_tiltBaseMovement = (float)Math.Sqrt(2); + /// /// Used to introduce a fixed tilt because a straight-up capsule falls through terrain, probably a bug in terrain collider /// @@ -524,14 +529,14 @@ namespace OpenSim.Region.Physics.OdePlugin if (movementVector.Y > 0) { // northeast - movementVector.X = (float)Math.Sqrt(2.0); - movementVector.Y = (float)Math.Sqrt(2.0); + movementVector.X = m_tiltBaseMovement; + movementVector.Y = m_tiltBaseMovement; } else { // southeast - movementVector.X = (float)Math.Sqrt(2.0); - movementVector.Y = -(float)Math.Sqrt(2.0); + movementVector.X = m_tiltBaseMovement; + movementVector.Y = -m_tiltBaseMovement; } } else @@ -540,14 +545,14 @@ namespace OpenSim.Region.Physics.OdePlugin if (movementVector.Y > 0) { // northwest - movementVector.X = -(float)Math.Sqrt(2.0); - movementVector.Y = (float)Math.Sqrt(2.0); + movementVector.X = -m_tiltBaseMovement; + movementVector.Y = m_tiltBaseMovement; } else { // southwest - movementVector.X = -(float)Math.Sqrt(2.0); - movementVector.Y = -(float)Math.Sqrt(2.0); + movementVector.X = -m_tiltBaseMovement; + movementVector.Y = -m_tiltBaseMovement; } } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 97890ee398..1f79cd8e83 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -842,17 +842,23 @@ namespace OpenSim.Region.Physics.OdePlugin mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage mesh.releaseSourceMeshData(); // free up the original mesh data to save memory - if (m_MeshToTriMeshMap.ContainsKey(mesh)) - { - _triMeshData = m_MeshToTriMeshMap[mesh]; - } - else - { - _triMeshData = d.GeomTriMeshDataCreate(); - d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); - d.GeomTriMeshDataPreprocess(_triMeshData); - m_MeshToTriMeshMap[mesh] = _triMeshData; + // We must lock here since m_MeshToTriMeshMap is static and multiple scene threads may call this method at + // the same time. + lock (m_MeshToTriMeshMap) + { + if (m_MeshToTriMeshMap.ContainsKey(mesh)) + { + _triMeshData = m_MeshToTriMeshMap[mesh]; + } + else + { + _triMeshData = d.GeomTriMeshDataCreate(); + + d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); + d.GeomTriMeshDataPreprocess(_triMeshData); + m_MeshToTriMeshMap[mesh] = _triMeshData; + } } // _parent_scene.waitForSpaceUnlock(m_targetSpace); diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 598530c50f..842ff916dc 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -181,8 +181,15 @@ namespace OpenSim.Region.Physics.OdePlugin private float avPIDP = 1400f; private float avCapRadius = 0.37f; private float avStandupTensor = 2000000f; - private bool avCapsuleTilted = true; // true = old compatibility mode with leaning capsule; false = new corrected mode - public bool IsAvCapsuleTilted { get { return avCapsuleTilted; } set { avCapsuleTilted = value; } } + + /// + /// true = old compatibility mode with leaning capsule; false = new corrected mode + /// + /// + /// Even when set to false, the capsule still tilts but this is done in a different way. + /// + public bool IsAvCapsuleTilted { get; private set; } + private float avDensity = 80f; // private float avHeightFudgeFactor = 0.52f; private float avMovementDivisorWalk = 1.3f; @@ -501,7 +508,7 @@ namespace OpenSim.Region.Physics.OdePlugin avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f); avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f); avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f); - avCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", false); + IsAvCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", false); contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80); diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index d4108d72dc..7712076a1b 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -401,16 +401,16 @@ namespace OpenSim.Region.ScriptEngine.XEngine // sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count); SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(this); - sb.AppendFormat("Sensors : {0}\n", sr.SensorsCount); + sb.AppendFormat("Sensors : {0}\n", sr != null ? sr.SensorsCount : 0); Dataserver ds = AsyncCommandManager.GetDataserverPlugin(this); - sb.AppendFormat("Dataserver requests : {0}\n", ds.DataserverRequestsCount); + sb.AppendFormat("Dataserver requests : {0}\n", ds != null ? ds.DataserverRequestsCount : 0); Timer t = AsyncCommandManager.GetTimerPlugin(this); - sb.AppendFormat("Timers : {0}\n", t.TimersCount); + sb.AppendFormat("Timers : {0}\n", t != null ? t.TimersCount : 0); Listener l = AsyncCommandManager.GetListenerPlugin(this); - sb.AppendFormat("Listeners : {0}\n", l.ListenerCount); + sb.AppendFormat("Listeners : {0}\n", l != null ? l.ListenerCount : 0); return sb.ToString(); } diff --git a/OpenSim/Services/AssetService/XAssetService.cs b/OpenSim/Services/AssetService/XAssetService.cs index d161c58005..05eb125ebc 100644 --- a/OpenSim/Services/AssetService/XAssetService.cs +++ b/OpenSim/Services/AssetService/XAssetService.cs @@ -42,7 +42,7 @@ namespace OpenSim.Services.AssetService /// This will be developed into a de-duplicating asset service. /// XXX: Currently it's a just a copy of the existing AssetService. so please don't attempt to use it. /// - public class XAssetService : AssetServiceBase, IAssetService + public class XAssetService : XAssetServiceBase, IAssetService { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); diff --git a/OpenSim/Services/AssetService/XAssetServiceBase.cs b/OpenSim/Services/AssetService/XAssetServiceBase.cs new file mode 100644 index 0000000000..0c5c2c3d15 --- /dev/null +++ b/OpenSim/Services/AssetService/XAssetServiceBase.cs @@ -0,0 +1,94 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Data; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Base; + +namespace OpenSim.Services.AssetService +{ + public class XAssetServiceBase : ServiceBase + { + protected IXAssetDataPlugin m_Database = null; + protected IAssetLoader m_AssetLoader = null; + + public XAssetServiceBase(IConfigSource config) : base(config) + { + string dllName = String.Empty; + string connString = String.Empty; + + // + // Try reading the [AssetService] section first, if it exists + // + IConfig assetConfig = config.Configs["AssetService"]; + if (assetConfig != null) + { + dllName = assetConfig.GetString("StorageProvider", dllName); + connString = assetConfig.GetString("ConnectionString", connString); + } + + // + // Try reading the [DatabaseService] section, if it exists + // + IConfig dbConfig = config.Configs["DatabaseService"]; + if (dbConfig != null) + { + if (dllName == String.Empty) + dllName = dbConfig.GetString("StorageProvider", String.Empty); + if (connString == String.Empty) + connString = dbConfig.GetString("ConnectionString", String.Empty); + } + + // + // We tried, but this doesn't exist. We can't proceed. + // + if (dllName.Equals(String.Empty)) + throw new Exception("No StorageProvider configured"); + + m_Database = LoadPlugin(dllName); + if (m_Database == null) + throw new Exception("Could not find a storage interface in the given module"); + + m_Database.Initialise(connString); + + string loaderName = assetConfig.GetString("DefaultAssetLoader", + String.Empty); + + if (loaderName != String.Empty) + { + m_AssetLoader = LoadPlugin(loaderName); + + if (m_AssetLoader == null) + throw new Exception("Asset loader could not be loaded"); + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Services/UserAccountService/UserAccountService.cs b/OpenSim/Services/UserAccountService/UserAccountService.cs index 6f1d745956..a281b3b50e 100644 --- a/OpenSim/Services/UserAccountService/UserAccountService.cs +++ b/OpenSim/Services/UserAccountService/UserAccountService.cs @@ -521,7 +521,7 @@ namespace OpenSim.Services.UserAccountService else { m_log.DebugFormat( - "[USER ACCOUNT SERVICE]; Created user inventory for {0} {1}", firstName, lastName); + "[USER ACCOUNT SERVICE]: Created user inventory for {0} {1}", firstName, lastName); } if (m_CreateDefaultAvatarEntries) diff --git a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs index 295e8681cf..579d41ca03 100644 --- a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs @@ -120,7 +120,7 @@ namespace OpenSim.Data.Null /// public class NullDataStore : ISimulationDataStore { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Dictionary m_regionSettings = new Dictionary(); protected Dictionary m_sceneObjectParts = new Dictionary(); diff --git a/OpenSim/Tests/Torture/ObjectTortureTests.cs b/OpenSim/Tests/Torture/ObjectTortureTests.cs index 978a3085bf..d0d2199b0c 100644 --- a/OpenSim/Tests/Torture/ObjectTortureTests.cs +++ b/OpenSim/Tests/Torture/ObjectTortureTests.cs @@ -157,7 +157,7 @@ namespace OpenSim.Tests.Torture // // However, that means that we need to manually run an update here to clear out that list so that deleted // objects will be clean up by the garbage collector before the next stress test is run. - scene.Update(); + scene.Update(1); Console.WriteLine( "Took {0}ms, {1}MB ({2} - {3}) to create {4} objects each containing {5} prim(s)", diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index d98c826c5e..db9f08b729 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -66,7 +66,6 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ; * in turn, reads the asset loader and database connection information ; * [AssetService] - StorageProvider = "OpenSim.Data.MySQL.dll:MySQLAssetData" LocalServiceModule = "OpenSim.Services.AssetService.dll:AssetService" DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll" AssetLoaderArgs = "./assets/AssetSets.xml" diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index 691bfdc1e9..326caeb86d 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -58,7 +58,6 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ; * in turn, reads the asset loader and database connection information ; * [AssetService] - StorageProvider = "OpenSim.Data.MySQL.dll:MySQLAssetData" LocalServiceModule = "OpenSim.Services.AssetService.dll:AssetService" DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll" AssetLoaderArgs = "./assets/AssetSets.xml" diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 4c734a1ab4..3dfbed7fdc 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -44,7 +44,6 @@ ;AuthorizationServices = "LocalAuthorizationServicesConnector" [AssetService] - StorageProvider = "OpenSim.Data.MySQL.dll:MySQLAssetData" DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll" AssetLoaderArgs = "assets/AssetSets.xml" @@ -241,4 +240,4 @@ ; DisallowForeigners -- HG visitors not allowed ; DisallowResidents -- only Admins and Managers allowed ; Example: - ; Region_Test_1 = "DisallowForeigners" \ No newline at end of file + ; Region_Test_1 = "DisallowForeigners" diff --git a/bin/shutdown_commands.txt b/bin/shutdown_commands.txt deleted file mode 100644 index 4397749d23..0000000000 --- a/bin/shutdown_commands.txt +++ /dev/null @@ -1,3 +0,0 @@ -; You can place simulator console commands here to execute when the simulator is shut down -; e.g. show stats -; Lines starting with ; are comments diff --git a/bin/shutdown_commands.txt.example b/bin/shutdown_commands.txt.example new file mode 100644 index 0000000000..dc07dc93db --- /dev/null +++ b/bin/shutdown_commands.txt.example @@ -0,0 +1,3 @@ +; Copy this file to shutdown_commands.txt to execute region console commands when the simulator is asked to shut down +; e.g. show stats +; Lines that start with ; are comments diff --git a/bin/startup_commands.txt b/bin/startup_commands.txt deleted file mode 100644 index 1abfa64c87..0000000000 --- a/bin/startup_commands.txt +++ /dev/null @@ -1,3 +0,0 @@ -; You can place region console commands here to execute once the simulator has finished starting up -; e.g. show stats -; Lines start with ; are comments. diff --git a/bin/startup_commands.txt.example b/bin/startup_commands.txt.example new file mode 100644 index 0000000000..677109c5a2 --- /dev/null +++ b/bin/startup_commands.txt.example @@ -0,0 +1,3 @@ +; Copy this file to startup_commands.txt to run region console commands once the simulator has finished starting up +; e.g. show stats +; Lines that start with ; are comments.