diff --git a/OpenSim/Addons/Groups/GroupsMessagingModule.cs b/OpenSim/Addons/Groups/GroupsMessagingModule.cs index 5de1fb4c6a..be59c6258c 100644 --- a/OpenSim/Addons/Groups/GroupsMessagingModule.cs +++ b/OpenSim/Addons/Groups/GroupsMessagingModule.cs @@ -246,7 +246,7 @@ namespace OpenSim.Groups public void SendMessageToGroup(GridInstantMessage im, UUID groupID) { UUID fromAgentID = new UUID(im.fromAgentID); - List groupMembers = m_groupData.GetGroupMembers("all", groupID); + List groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), groupID); int groupMembersCount = groupMembers.Count; PresenceInfo[] onlineAgents = null; @@ -297,6 +297,10 @@ namespace OpenSim.Groups if (member.AgentID.Guid == im.fromAgentID) continue; + if (clientsAlreadySent.Contains(member.AgentID)) + continue; + clientsAlreadySent.Add(member.AgentID); + if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID)) { // Don't deliver messages to people who have dropped this session @@ -336,12 +340,9 @@ namespace OpenSim.Groups // Deliver locally, directly if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); - if (clientsAlreadySent.Contains(member.AgentID)) - continue; - clientsAlreadySent.Add(member.AgentID); - ProcessMessageFromGroupSession(im); } + } if (m_debugEnabled) @@ -403,8 +404,7 @@ namespace OpenSim.Groups Scene aScene = m_sceneList[0]; GridRegion regionOfOrigin = aScene.GridService.GetRegionByUUID(aScene.RegionInfo.ScopeID, regionID); - List groupMembers = m_groupData.GetGroupMembers("all", GroupID); - List alreadySeen = new List(); + List groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), GroupID); //if (m_debugEnabled) // foreach (GroupMembersData m in groupMembers) @@ -414,15 +414,10 @@ namespace OpenSim.Groups { s.ForEachScenePresence(sp => { - // We need this, because we are searching through all - // SPs, both root and children - if (alreadySeen.Contains(sp.UUID)) - { - if (m_debugEnabled) - m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because we've already seen it", sp.UUID); + // If we got this via grid messaging, it's because the caller thinks + // that the root agent is here. We should only send the IM to root agents. + if (sp.IsChildAgent) return; - } - alreadySeen.Add(sp.UUID); GroupMembersData m = groupMembers.Find(gmd => { diff --git a/OpenSim/Addons/Groups/GroupsModule.cs b/OpenSim/Addons/Groups/GroupsModule.cs index 826fcbf80c..da8030c22b 100644 --- a/OpenSim/Addons/Groups/GroupsModule.cs +++ b/OpenSim/Addons/Groups/GroupsModule.cs @@ -991,6 +991,10 @@ namespace OpenSim.Groups // Should this send updates to everyone in the group? SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); + + if (reason != string.Empty) + // A warning + remoteClient.SendAlertMessage("Warning: " + reason); } else remoteClient.SendJoinGroupReply(groupID, false); diff --git a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs index daa07282ab..c33168ce26 100644 --- a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs +++ b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs @@ -254,7 +254,10 @@ namespace OpenSim.Groups { string url = string.Empty, gname = string.Empty; if (IsLocal(GroupID, out url, out gname)) - return m_LocalGroupsConnector.GetGroupMembers(AgentUUI(RequestingAgentID), GroupID); + { + string agentID = AgentUUI(RequestingAgentID); + return m_LocalGroupsConnector.GetGroupMembers(agentID, GroupID); + } else if (!string.IsNullOrEmpty(url)) { ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, GroupID); @@ -396,17 +399,21 @@ namespace OpenSim.Groups if (success) { + // Here we always return true. The user has been added to the local group, + // independent of whether the remote operation succeeds or not url = m_UserManagement.GetUserServerURL(uid, "GroupsServerURI"); if (url == string.Empty) { - reason = "User doesn't have a groups server"; - return false; + reason = "You don't have have an accessible groups server in your home world. You membership to this group in only within this grid."; + return true; } GroupsServiceHGConnector c = GetConnector(url); if (c != null) - return c.CreateProxy(AgentUUI(RequestingAgentID), AgentID, token, GroupID, m_LocalGroupsServiceLocation, name, out reason); + c.CreateProxy(AgentUUI(RequestingAgentID), AgentID, token, GroupID, m_LocalGroupsServiceLocation, name, out reason); + return true; } + return false; } } else if (m_UserManagement.IsLocalGridUser(uid)) // local user diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs index 9a3e125dab..161ca0c4cc 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs @@ -256,6 +256,7 @@ namespace OpenSim.Groups Dictionary sendData = new Dictionary(); sendData["GroupID"] = GroupID.ToString(); sendData["RequestingAgentID"] = RequestingAgentID; + Dictionary ret = MakeRequest("GETGROUPMEMBERS", sendData); if (ret == null) diff --git a/OpenSim/Addons/Groups/Service/GroupsService.cs b/OpenSim/Addons/Groups/Service/GroupsService.cs index 294b89a201..037ef59b9e 100644 --- a/OpenSim/Addons/Groups/Service/GroupsService.cs +++ b/OpenSim/Addons/Groups/Service/GroupsService.cs @@ -257,8 +257,8 @@ namespace OpenSim.Groups // Check visibility? // When we don't want to check visibility, we pass it "all" as the requestingAgentID - bool checkVisibility = !RequestingAgentID.Equals("all"); - m_log.DebugFormat("[ZZZ]: AgentID is {0}. checkVisibility is {1}", RequestingAgentID, checkVisibility); + bool checkVisibility = !RequestingAgentID.Equals(UUID.Zero.ToString()); + if (checkVisibility) { // Is the requester a member of the group? diff --git a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs index 6a68322531..f6f458d3ec 100644 --- a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs +++ b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; using OpenMetaverse; using OpenMetaverse.StructuredData; @@ -39,8 +40,6 @@ namespace OpenSim.Framework.Monitoring /// public class SimExtraStatsCollector : BaseStatsCollector { - private long abnormalClientThreadTerminations; - // private long assetsInCache; // private long texturesInCache; // private long assetCacheMemoryUsage; @@ -73,11 +72,6 @@ namespace OpenSim.Framework.Monitoring private volatile float activeScripts; private volatile float scriptLinesPerSecond; - /// - /// Number of times that a client thread terminated because of an exception - /// - public long AbnormalClientThreadTerminations { get { return abnormalClientThreadTerminations; } } - // /// // /// These statistics are being collected by push rather than pull. Pull would be simpler, but I had the // /// notion of providing some flow statistics (which pull wouldn't give us). Though admittedly these @@ -166,11 +160,6 @@ namespace OpenSim.Framework.Monitoring private IDictionary packetQueueStatsCollectors = new Dictionary(); - public void AddAbnormalClientThreadTermination() - { - abnormalClientThreadTerminations++; - } - // public void AddAsset(AssetBase asset) // { // assetsInCache++; @@ -324,10 +313,12 @@ Asset service request failures: {3}" + Environment.NewLine, sb.Append(Environment.NewLine); sb.Append("CONNECTION STATISTICS"); sb.Append(Environment.NewLine); - sb.Append( - string.Format( - "Abnormal client thread terminations: {0}" + Environment.NewLine, - abnormalClientThreadTerminations)); + + List stats = StatsManager.GetStatsFromEachContainer("clientstack", "ClientLogoutsDueToNoReceives"); + + sb.AppendFormat( + "Client logouts due to no data receive timeout: {0}\n\n", + stats != null ? stats.Sum(s => s.Value).ToString() : "unknown"); // sb.Append(Environment.NewLine); // sb.Append("INVENTORY STATISTICS"); @@ -338,7 +329,7 @@ Asset service request failures: {3}" + Environment.NewLine, // InventoryServiceRetrievalFailures)); sb.Append(Environment.NewLine); - sb.Append("FRAME STATISTICS"); + sb.Append("SAMPLE FRAME STATISTICS"); sb.Append(Environment.NewLine); sb.Append("Dilatn SimFPS PhyFPS AgntUp RootAg ChldAg Prims AtvPrm AtvScr ScrLPS"); sb.Append(Environment.NewLine); diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs index a5b54c9bf9..e6a230454c 100644 --- a/OpenSim/Framework/Monitoring/StatsManager.cs +++ b/OpenSim/Framework/Monitoring/StatsManager.cs @@ -271,7 +271,7 @@ namespace OpenSim.Framework.Monitoring // Stat name is not unique across category/container/shortname key. // XXX: For now just return false. This is to avoid problems in regression tests where all tests // in a class are run in the same instance of the VM. - if (TryGetStat(stat, out category, out container)) + if (TryGetStatParents(stat, out category, out container)) return false; // We take a copy-on-write approach here of replacing dictionaries when keys are added or removed. @@ -307,7 +307,7 @@ namespace OpenSim.Framework.Monitoring lock (RegisteredStats) { - if (!TryGetStat(stat, out category, out container)) + if (!TryGetStatParents(stat, out category, out container)) return false; newContainer = new SortedDictionary(container); @@ -323,12 +323,67 @@ namespace OpenSim.Framework.Monitoring } } - public static bool TryGetStats(string category, out SortedDictionary> stats) + public static bool TryGetStat(string category, string container, string statShortName, out Stat stat) { - return RegisteredStats.TryGetValue(category, out stats); + stat = null; + SortedDictionary> categoryStats; + + lock (RegisteredStats) + { + if (!TryGetStatsForCategory(category, out categoryStats)) + return false; + + SortedDictionary containerStats; + + if (!categoryStats.TryGetValue(container, out containerStats)) + return false; + + return containerStats.TryGetValue(statShortName, out stat); + } } - public static bool TryGetStat( + public static bool TryGetStatsForCategory( + string category, out SortedDictionary> stats) + { + lock (RegisteredStats) + return RegisteredStats.TryGetValue(category, out stats); + } + + /// + /// Get the same stat for each container in a given category. + /// + /// + /// The stats if there were any to fetch. Otherwise null. + /// + /// + /// + public static List GetStatsFromEachContainer(string category, string statShortName) + { + SortedDictionary> categoryStats; + + lock (RegisteredStats) + { + if (!RegisteredStats.TryGetValue(category, out categoryStats)) + return null; + + List stats = null; + + foreach (SortedDictionary containerStats in categoryStats.Values) + { + if (containerStats.ContainsKey(statShortName)) + { + if (stats == null) + stats = new List(); + + stats.Add(containerStats[statShortName]); + } + } + + return stats; + } + } + + public static bool TryGetStatParents( Stat stat, out SortedDictionary> category, out SortedDictionary container) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index c12b8d649b..c8e1e83da0 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -82,6 +82,8 @@ namespace OpenSim.Region.ClientStack.Linden private Dictionary m_pollservices = new Dictionary(); + private string m_URL; + #region ISharedRegionModule Members public void Initialise(IConfigSource source) @@ -343,13 +345,13 @@ namespace OpenSim.Region.ClientStack.Linden private void RegisterCaps(UUID agentID, Caps caps) { - string capUrl = "/CAPS/" + UUID.Random() + "/"; + m_URL = "/CAPS/" + UUID.Random() + "/"; // Register this as a poll service PollServiceTextureEventArgs args = new PollServiceTextureEventArgs(agentID, m_scene); args.Type = PollServiceEventArgs.EventType.Texture; - MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); + MainServer.Instance.AddPollServiceHTTPHandler(m_URL, args); string hostName = m_scene.RegionInfo.ExternalHostName; uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port; @@ -361,20 +363,23 @@ namespace OpenSim.Region.ClientStack.Linden port = MainServer.Instance.SSLPort; protocol = "https"; } - caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl)); + + IExternalCapsModule handler = m_scene.RequestModuleInterface(); + if (handler != null) + handler.RegisterExternalUserCapsHandler(agentID, caps, "GetTexture", m_URL); + else + caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, m_URL)); m_pollservices[agentID] = args; - m_capsDict[agentID] = capUrl; + m_capsDict[agentID] = m_URL; } private void DeregisterCaps(UUID agentID, Caps caps) { - string capUrl; PollServiceTextureEventArgs args; - if (m_capsDict.TryGetValue(agentID, out capUrl)) - { - MainServer.Instance.RemoveHTTPHandler("", capUrl); - m_capsDict.Remove(agentID); - } + + MainServer.Instance.RemoveHTTPHandler("", m_URL); + m_capsDict.Remove(agentID); + if (m_pollservices.TryGetValue(agentID, out args)) { m_pollservices.Remove(agentID); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index 7d9f935d42..e4d8a20fb6 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs @@ -68,7 +68,6 @@ namespace OpenSim.Region.ClientStack.Linden /// private OSDMap m_features = new OSDMap(); - private string m_MapImageServerURL = string.Empty; private string m_SearchURL = string.Empty; private bool m_ExportSupported = false; @@ -78,15 +77,7 @@ namespace OpenSim.Region.ClientStack.Linden { IConfig config = source.Configs["SimulatorFeatures"]; if (config != null) - { - m_MapImageServerURL = config.GetString("MapImageServerURI", string.Empty); - if (m_MapImageServerURL != string.Empty) - { - m_MapImageServerURL = m_MapImageServerURL.Trim(); - if (!m_MapImageServerURL.EndsWith("/")) - m_MapImageServerURL = m_MapImageServerURL + "/"; - } - + { m_SearchURL = config.GetString("SearchServerURI", string.Empty); m_ExportSupported = config.GetBoolean("ExportSupported", m_ExportSupported); @@ -149,15 +140,16 @@ namespace OpenSim.Region.ClientStack.Linden m_features["PhysicsShapeTypes"] = typesMap; // Extra information for viewers that want to use it - OSDMap gridServicesMap = new OSDMap(); - if (m_MapImageServerURL != string.Empty) - gridServicesMap["map-server-url"] = m_MapImageServerURL; + // TODO: Take these out of here into their respective modules, like map-server-url + OSDMap extrasMap = new OSDMap(); if (m_SearchURL != string.Empty) - gridServicesMap["search"] = m_SearchURL; - m_features["GridServices"] = gridServicesMap; - + extrasMap["search-server-url"] = m_SearchURL; if (m_ExportSupported) - m_features["ExportSupported"] = true; + extrasMap["ExportSupported"] = true; + + if (extrasMap.Count > 0) + m_features["OpenSimExtras"] = extrasMap; + } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 544b54b39e..2a2c819eb3 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -67,11 +67,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP { m_udpServer.AddScene(scene); + StatsManager.RegisterStat( + new Stat( + "ClientLogoutsDueToNoReceives", + "Number of times a client has been logged out because no packets were received before the timeout.", + "", + "", + "clientstack", + scene.Name, + StatType.Pull, + MeasuresOfInterest.None, + stat => stat.Value = m_udpServer.ClientLogoutsDueToNoReceives, + StatVerbosity.Debug)); + StatsManager.RegisterStat( new Stat( "IncomingUDPReceivesCount", "Number of UDP receives performed", - "Number of UDP receives performed", + "", "", "clientstack", scene.Name, @@ -84,7 +97,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP new Stat( "IncomingPacketsProcessedCount", "Number of inbound LL protocol packets processed", - "Number of inbound LL protocol packets processed", + "", "", "clientstack", scene.Name, @@ -97,7 +110,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP new Stat( "OutgoingUDPSendsCount", "Number of UDP sends performed", - "Number of UDP sends performed", + "", "", "clientstack", scene.Name, @@ -149,6 +162,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Maximum transmission unit, or UDP packet size, for the LLUDP protocol public const int MTU = 1400; + /// Number of forced client logouts due to no receipt of packets before timeout. + public int ClientLogoutsDueToNoReceives { get; private set; } + /// /// Default packet debug level given to new clients /// @@ -1058,7 +1074,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Fire this out on a different thread so that we don't hold up outgoing packet processing for // everybody else if this is being called due to an ack timeout. // This is the same as processing as the async process of a logout request. - Util.FireAndForget(o => DeactivateClientDueToTimeout(client)); + Util.FireAndForget(o => DeactivateClientDueToTimeout(client, timeoutTicks)); return; } @@ -1842,18 +1858,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// regular client pings. /// /// - private void DeactivateClientDueToTimeout(LLClientView client) + /// + private void DeactivateClientDueToTimeout(LLClientView client, int timeoutTicks) { lock (client.CloseSyncLock) - { + { + ClientLogoutsDueToNoReceives++; + m_log.WarnFormat( - "[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}", - client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName); - - StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); + "[LLUDPSERVER]: No packets received from {0} agent of {1} for {2}ms in {3}. Disconnecting.", + client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, timeoutTicks, m_scene.Name); if (!client.SceneAgent.IsChildAgent) - client.Kick("Simulator logged you out due to connection timeout"); + client.Kick("Simulator logged you out due to connection timeout."); client.CloseWithoutChecks(true); } diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index 7b11658c66..f196973817 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs @@ -31,6 +31,7 @@ using System.Reflection; using log4net; using Nini.Config; using OpenMetaverse; +using OpenMetaverse.StructuredData; using Mono.Addins; using OpenSim.Framework; using OpenSim.Region.CoreModules.World.WorldMap; @@ -48,20 +49,63 @@ namespace OpenSim.Region.CoreModules.Hypergrid // Remember the map area that each client has been exposed to in this region private Dictionary> m_SeenMapBlocks = new Dictionary>(); + private string m_MapImageServerURL = string.Empty; + + private IUserManagement m_UserManagement; + #region INonSharedRegionModule Members - public override void Initialise(IConfigSource config) + public override void Initialise(IConfigSource source) { if (Util.GetConfigVarFromSections( - config, "WorldMapModule", new string[] { "Map", "Startup" }, "WorldMap") == "HGWorldMap") + source, "WorldMapModule", new string[] { "Map", "Startup" }, "WorldMap") == "HGWorldMap") + { m_Enabled = true; + + m_MapImageServerURL = Util.GetConfigVarFromSections(source, "MapTileURL", new string[] {"LoginService", "HGWorldMap", "SimulatorFeatures"}); + + if (!string.IsNullOrEmpty(m_MapImageServerURL)) + { + m_MapImageServerURL = m_MapImageServerURL.Trim(); + if (!m_MapImageServerURL.EndsWith("/")) + m_MapImageServerURL = m_MapImageServerURL + "/"; + } + + + } } public override void AddRegion(Scene scene) { + if (!m_Enabled) + return; + base.AddRegion(scene); - scene.EventManager.OnClientClosed += new EventManager.ClientClosed(EventManager_OnClientClosed); + scene.EventManager.OnClientClosed += EventManager_OnClientClosed; + } + + public override void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + base.RegionLoaded(scene); + ISimulatorFeaturesModule featuresModule = m_scene.RequestModuleInterface(); + + if (featuresModule != null) + featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest; + + m_UserManagement = m_scene.RequestModuleInterface(); + + } + + public override void RemoveRegion(Scene scene) + { + if (!m_Enabled) + return; + + scene.EventManager.OnClientClosed -= EventManager_OnClientClosed; } public override string Name @@ -115,6 +159,20 @@ namespace OpenSim.Region.CoreModules.Hypergrid return mapBlocks; } + private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features) + { + if (m_UserManagement != null && !string.IsNullOrEmpty(m_MapImageServerURL) && !m_UserManagement.IsLocalGridUser(agentID)) + { + OSD extras = new OSDMap(); + if (features.ContainsKey("OpenSimExtras")) + extras = features["OpenSimExtras"]; + else + features["OpenSimExtras"] = extras; + + ((OSDMap)extras)["map-server-url"] = m_MapImageServerURL; + + } + } } class MapArea diff --git a/OpenSim/Region/Framework/Interfaces/IExternalCapsModule.cs b/OpenSim/Region/Framework/Interfaces/IExternalCapsModule.cs new file mode 100644 index 0000000000..a730cfdcb9 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IExternalCapsModule.cs @@ -0,0 +1,48 @@ +/* + * 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 OpenMetaverse; +using OpenSim.Framework; +using Caps=OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Region.Framework.Interfaces +{ + public interface IExternalCapsModule + { + /// + /// This function extends the simple URL configuration in the caps handlers + /// to facilitate more interesting computation when an external handler is + /// sent to the viewer. + /// + /// New user UUID + /// Internal caps registry, where the external handler will be registered + /// Name of the specific cap we are registering + /// The skeleton URL provided in the caps configuration + bool RegisterExternalUserCapsHandler(UUID agentID, Caps caps, String capName, String urlSkel); + } +} diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs index 6009dc57a8..0cbc5f9e76 100755 --- a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs +++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs @@ -31,10 +31,10 @@ using System.Reflection; using System.Text; using OpenSim.Framework; +using OpenSim.Region.CoreModules; using OpenSim.Region.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.CoreModules; using Mono.Addins; using Nini.Config; @@ -49,6 +49,10 @@ public class ExtendedPhysics : INonSharedRegionModule private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static string LogHeader = "[EXTENDED PHYSICS]"; + // Since BulletSim is a plugin, this these values aren't defined easily in one place. + // This table must coorespond to an identical table in BSScene. + public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType"; + private IConfig Configuration { get; set; } private bool Enabled { get; set; } private Scene BaseScene { get; set; } @@ -143,13 +147,6 @@ public class ExtendedPhysics : INonSharedRegionModule [ScriptConstant] public static int PHYS_CENTER_OF_MASS = 1 << 0; - [ScriptConstant] - public static int PHYS_LINKSET_TYPE_CONSTRAINT = 1; - [ScriptConstant] - public static int PHYS_LINKSET_TYPE_COMPOUND = 2; - [ScriptConstant] - public static int PHYS_LINKSET_TYPE_MANUAL = 3; - [ScriptInvocation] public string physGetEngineType(UUID hostID, UUID scriptID) { @@ -163,9 +160,50 @@ public class ExtendedPhysics : INonSharedRegionModule return ret; } + [ScriptConstant] + public static int PHYS_LINKSET_TYPE_CONSTRAINT = 0; + [ScriptConstant] + public static int PHYS_LINKSET_TYPE_COMPOUND = 1; + [ScriptConstant] + public static int PHYS_LINKSET_TYPE_MANUAL = 2; + [ScriptInvocation] public void physSetLinksetType(UUID hostID, UUID scriptID, int linksetType) { + if (!Enabled) return; + + // The part that is requesting the change. + SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID); + + if (requestingPart != null) + { + // The change is always made to the root of a linkset. + SceneObjectGroup containingGroup = requestingPart.ParentGroup; + SceneObjectPart rootPart = containingGroup.RootPart; + + if (rootPart != null) + { + Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor; + if (rootPhysActor != null) + { + rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType); + } + else + { + m_log.WarnFormat("{0} physSetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}", + LogHeader, rootPart.Name, hostID); + } + } + else + { + m_log.WarnFormat("{0} physSetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}", + LogHeader, requestingPart.Name, hostID); + } + } + else + { + m_log.WarnFormat("{0} physSetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID); + } } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 59e7f5ffbe..58a417ed8f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -75,7 +75,7 @@ public sealed class BSCharacter : BSPhysObject RawVelocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); Friction = BSParam.AvatarStandingFriction; - Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor; + Density = BSParam.AvatarDensity; // Old versions of ScenePresence passed only the height. If width and/or depth are zero, // replace with the default values. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 82d7c44253..f0d17d366a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -589,10 +589,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_vehicleMass = ControllingPrim.TotalMass; // Friction affects are handled by this vehicle code - m_physicsScene.PE.SetFriction(ControllingPrim.PhysBody, BSParam.VehicleFriction); - m_physicsScene.PE.SetRestitution(ControllingPrim.PhysBody, BSParam.VehicleRestitution); - // ControllingPrim.Linkset.SetPhysicalFriction(BSParam.VehicleFriction); - // ControllingPrim.Linkset.SetPhysicalRestitution(BSParam.VehicleRestitution); + // m_physicsScene.PE.SetFriction(ControllingPrim.PhysBody, BSParam.VehicleFriction); + // m_physicsScene.PE.SetRestitution(ControllingPrim.PhysBody, BSParam.VehicleRestitution); + ControllingPrim.Linkset.SetPhysicalFriction(BSParam.VehicleFriction); + ControllingPrim.Linkset.SetPhysicalRestitution(BSParam.VehicleRestitution); // Moderate angular movement introduced by Bullet. // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. @@ -602,21 +602,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_physicsScene.PE.SetAngularFactorV(ControllingPrim.PhysBody, BSParam.VehicleAngularFactor); // Vehicles report collision events so we know when it's on the ground - m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); - // ControllingPrim.Linkset.SetPhysicalCollisionFlags(CollisionFlags.BS_VEHICLE_COLLISIONS); + // m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); + ControllingPrim.Linkset.AddToPhysicalCollisionFlags(CollisionFlags.BS_VEHICLE_COLLISIONS); - Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape.physShapeInfo, m_vehicleMass); - ControllingPrim.Inertia = inertia * BSParam.VehicleInertiaFactor; - m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia); - m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody); - // ControllingPrim.Linkset.ComputeLocalInertia(BSParam.VehicleInertiaFactor); + // Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape.physShapeInfo, m_vehicleMass); + // ControllingPrim.Inertia = inertia * BSParam.VehicleInertiaFactor; + // m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia); + // m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody); + ControllingPrim.Linkset.ComputeAndSetLocalInertia(BSParam.VehicleInertiaFactor, m_vehicleMass); // Set the gravity for the vehicle depending on the buoyancy // TODO: what should be done if prim and vehicle buoyancy differ? m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy); // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same. - m_physicsScene.PE.SetGravity(ControllingPrim.PhysBody, Vector3.Zero); - // ControllingPrim.Linkset.SetPhysicalGravity(Vector3.Zero); + // m_physicsScene.PE.SetGravity(ControllingPrim.PhysBody, Vector3.Zero); + ControllingPrim.Linkset.SetPhysicalGravity(Vector3.Zero); VDetailLog("{0},BSDynamics.SetPhysicalParameters,mass={1},inert={2},vehGrav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}", ControllingPrim.LocalID, m_vehicleMass, ControllingPrim.Inertia, m_VehicleGravity, @@ -1121,7 +1121,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin { m_VhoverTargetHeight = m_VhoverHeight; } - if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0) { // If body is already heigher, use its height as target height @@ -1170,7 +1169,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, verticalError, verticalCorrection); } - } } @@ -1357,6 +1355,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin private void ComputeAngularTurning(float pTimestep) { // The user wants this many radians per second angular change? + Vector3 origVehicleRotationalVelocity = VehicleRotationalVelocity; // DEBUG DEBUG Vector3 currentAngularV = VehicleRotationalVelocity * Quaternion.Inverse(VehicleOrientation); Vector3 angularMotorContributionV = m_angularMotor.Step(pTimestep, currentAngularV); @@ -1369,20 +1368,20 @@ namespace OpenSim.Region.Physics.BulletSPlugin // TODO: This is here because this is where ODE put it but documentation says it // is a linear effect. Where should this check go? //if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) - // { + // { // angularMotorContributionV.X = 0f; // angularMotorContributionV.Y = 0f; - // } + // } // Reduce any velocity by friction. Vector3 frictionFactorW = ComputeFrictionFactor(m_angularFrictionTimescale, pTimestep); angularMotorContributionV -= (currentAngularV * frictionFactorW); - VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation; + Vector3 angularMotorContributionW = angularMotorContributionV * VehicleOrientation; + VehicleRotationalVelocity += angularMotorContributionW; - - - VDetailLog("{0}, MoveAngular,angularTurning,angContribV={1}", ControllingPrim.LocalID, angularMotorContributionV); + VDetailLog("{0}, MoveAngular,angularTurning,curAngVelV={1},origVehRotVel={2},vehRotVel={3},frictFact={4}, angContribV={5},angContribW={6}", + ControllingPrim.LocalID, currentAngularV, origVehicleRotationalVelocity, VehicleRotationalVelocity, frictionFactorW, angularMotorContributionV, angularMotorContributionW); } // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: @@ -1409,7 +1408,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Flipping what was originally a timescale into a speed variable and then multiplying it by 2 // since only computing half the distance between the angles. - float VerticalAttractionSpeed = (1 / m_verticalAttractionTimescale) * 2.0f; + float verticalAttractionSpeed = (1 / m_verticalAttractionTimescale) * 2.0f; // Make a prediction of where the up axis will be when this is applied rather then where it is now as // this makes for a smoother adjustment and less fighting between the various forces. @@ -1419,12 +1418,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ); // Scale vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared - Vector3 vertContributionV = torqueVector * VerticalAttractionSpeed * VerticalAttractionSpeed; + Vector3 vertContributionV = torqueVector * verticalAttractionSpeed * verticalAttractionSpeed; VehicleRotationalVelocity += vertContributionV; - VDetailLog("{0}, MoveAngular,verticalAttraction,upAxis={1},PredictedUp={2},torqueVector={3},contrib={4}", + VDetailLog("{0}, MoveAngular,verticalAttraction,vertAttrSpeed={1},upAxis={2},PredictedUp={3},torqueVector={4},contrib={5}", ControllingPrim.LocalID, + verticalAttractionSpeed, vehicleUpAxis, predictedUp, torqueVector, @@ -1437,37 +1437,38 @@ namespace OpenSim.Region.Physics.BulletSPlugin // http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no // Create a rotation that is only the vehicle's rotation around Z - Vector3 currentEuler = Vector3.Zero; - VehicleOrientation.GetEulerAngles(out currentEuler.X, out currentEuler.Y, out currentEuler.Z); - Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEuler.Z); + Vector3 currentEulerW = Vector3.Zero; + VehicleOrientation.GetEulerAngles(out currentEulerW.X, out currentEulerW.Y, out currentEulerW.Z); + Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEulerW.Z); // Create the axis that is perpendicular to the up vector and the rotated up vector. - Vector3 differenceAxis = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation); + Vector3 differenceAxisW = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation); // Compute the angle between those to vectors. double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleOrientation))); // 'differenceAngle' is the angle to rotate and 'differenceAxis' is the plane to rotate in to get the vehicle vertical // Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied. // TODO: add 'efficiency'. - differenceAngle /= m_verticalAttractionTimescale; + // differenceAngle /= m_verticalAttractionTimescale; // Create the quaterian representing the correction angle - Quaternion correctionRotation = Quaternion.CreateFromAxisAngle(differenceAxis, (float)differenceAngle); + Quaternion correctionRotationW = Quaternion.CreateFromAxisAngle(differenceAxisW, (float)differenceAngle); // Turn that quaternion into Euler values to make it into velocities to apply. - Vector3 vertContributionV = Vector3.Zero; - correctionRotation.GetEulerAngles(out vertContributionV.X, out vertContributionV.Y, out vertContributionV.Z); - vertContributionV *= -1f; + Vector3 vertContributionW = Vector3.Zero; + correctionRotationW.GetEulerAngles(out vertContributionW.X, out vertContributionW.Y, out vertContributionW.Z); + vertContributionW *= -1f; + vertContributionW /= m_verticalAttractionTimescale; - VehicleRotationalVelocity += vertContributionV; + VehicleRotationalVelocity += vertContributionW; VDetailLog("{0}, MoveAngular,verticalAttraction,upAxis={1},diffAxis={2},diffAng={3},corrRot={4},contrib={5}", ControllingPrim.LocalID, vehicleUpAxis, - differenceAxis, + differenceAxisW, differenceAngle, - correctionRotation, - vertContributionV); + correctionRotationW, + vertContributionW); break; } case 2: diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 960c0b4d2b..7f946662ad 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -309,16 +309,18 @@ public abstract class BSLinkset } ); } - public virtual void ComputeLocalInertia(OMV.Vector3 inertiaFactor) + public virtual void ComputeAndSetLocalInertia(OMV.Vector3 inertiaFactor, float linksetMass) { ForEachMember((member) => { if (member.PhysBody.HasPhysicalBody) { - OMV.Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(member.PhysShape.physShapeInfo, member.Mass); + OMV.Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(member.PhysShape.physShapeInfo, linksetMass); member.Inertia = inertia * inertiaFactor; - m_physicsScene.PE.SetMassProps(member.PhysBody, member.Mass, member.Inertia); + m_physicsScene.PE.SetMassProps(member.PhysBody, linksetMass, member.Inertia); m_physicsScene.PE.UpdateInertiaTensor(member.PhysBody); + DetailLog("{0},BSLinkset.ComputeAndSetLocalInertia,m.mass={1}, inertia={2}", member.LocalID, linksetMass, member.Inertia); + } return false; // 'false' says to continue looping } @@ -334,6 +336,16 @@ public abstract class BSLinkset } ); } + public virtual void AddToPhysicalCollisionFlags(CollisionFlags collFlags) + { + ForEachMember((member) => + { + if (member.PhysBody.HasPhysicalBody) + m_physicsScene.PE.AddToCollisionFlags(member.PhysBody, collFlags); + return false; // 'false' says to continue looping + } + ); + } public virtual void RemoveFromPhysicalCollisionFlags(CollisionFlags collFlags) { ForEachMember((member) => diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 33ae5a503c..6359046ca8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -61,11 +61,11 @@ public sealed class BSLinksetCompound : BSLinkset if (LinksetRoot.PhysBody.HasPhysicalBody) m_physicsScene.PE.SetGravity(LinksetRoot.PhysBody, gravity); } - public override void ComputeLocalInertia(OMV.Vector3 inertiaFactor) + public override void ComputeAndSetLocalInertia(OMV.Vector3 inertiaFactor, float linksetMass) { - OMV.Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(LinksetRoot.PhysShape.physShapeInfo, LinksetRoot.Mass); + OMV.Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(LinksetRoot.PhysShape.physShapeInfo, linksetMass); LinksetRoot.Inertia = inertia * inertiaFactor; - m_physicsScene.PE.SetMassProps(LinksetRoot.PhysBody, LinksetRoot.Mass, LinksetRoot.Inertia); + m_physicsScene.PE.SetMassProps(LinksetRoot.PhysBody, linksetMass, LinksetRoot.Inertia); m_physicsScene.PE.UpdateInertiaTensor(LinksetRoot.PhysBody); } public override void SetPhysicalCollisionFlags(CollisionFlags collFlags) @@ -73,6 +73,11 @@ public sealed class BSLinksetCompound : BSLinkset if (LinksetRoot.PhysBody.HasPhysicalBody) m_physicsScene.PE.SetCollisionFlags(LinksetRoot.PhysBody, collFlags); } + public override void AddToPhysicalCollisionFlags(CollisionFlags collFlags) + { + if (LinksetRoot.PhysBody.HasPhysicalBody) + m_physicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, collFlags); + } public override void RemoveFromPhysicalCollisionFlags(CollisionFlags collFlags) { if (LinksetRoot.PhysBody.HasPhysicalBody) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 0bdb5f1031..452017177f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -463,7 +463,7 @@ public static class BSParam // Density is passed around as 100kg/m3. This scales that to 1kg/m3. // Reduce by power of 100 because Bullet doesn't seem to handle objects with large mass very well new ParameterDefn("DensityScaleFactor", "Conversion for simulator/viewer density (100kg/m3) to physical density (1kg/m3)", - 0.0001f ), + 0.01f ), new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", 2200f ), @@ -474,8 +474,9 @@ public static class BSParam 0.2f, (s) => { return DefaultFriction; }, (s,v) => { DefaultFriction = v; s.UnmanagedParams[0].defaultFriction = v; } ), + // For historical reasons, the viewer and simulator multiply the density by 100 new ParameterDefn("DefaultDensity", "Density for new objects" , - 10.000006836f, // Aluminum g/cm3 + 1000.0006836f, // Aluminum g/cm3 * 100 (s) => { return DefaultDensity; }, (s,v) => { DefaultDensity = v; s.UnmanagedParams[0].defaultDensity = v; } ), new ParameterDefn("DefaultRestitution", "Bouncyness of an object" , @@ -555,8 +556,9 @@ public static class BSParam 0.95f ), new ParameterDefn("AvatarAlwaysRunFactor", "Speed multiplier if avatar is set to always run", 1.3f ), - new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", - 3.5f) , + // For historical reasons, density is reported * 100 + new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation. Scaled times 100.", + 3500f) , // 3.5 * 100 new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", 0f ), new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule", @@ -608,9 +610,8 @@ public static class BSParam 0.0f ), new ParameterDefn("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)", 0.0f ), - // Turn off fudge with DensityScaleFactor = 0.0001. Value used to be 0.2f; new ParameterDefn("VehicleGroundGravityFudge", "Factor to multiply gravity if a ground vehicle is probably on the ground (0.0 - 1.0)", - 1.0f ), + 0.2f ), new ParameterDefn("VehicleAngularBankingTimescaleFudge", "Factor to multiple angular banking timescale. Tune to increase realism.", 60.0f ), new ParameterDefn("VehicleEnableLinearDeflection", "Turn on/off vehicle linear deflection effect", diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index d34b7975f3..07045919e8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -187,10 +187,23 @@ public abstract class BSPhysObject : PhysicsActor MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); Friction = matAttrib.friction; Restitution = matAttrib.restitution; - Density = matAttrib.density / BSParam.DensityScaleFactor; + Density = matAttrib.density; // DetailLog("{0},{1}.SetMaterial,Mat={2},frict={3},rest={4},den={5}", LocalID, TypeName, Material, Friction, Restitution, Density); } + public override float Density + { + get + { + return base.Density; + } + set + { + DetailLog("{0},BSPhysObject.Density,set,den={1}", LocalID, value); + base.Density = value; + } + } + // Stop all physical motion. public abstract void ZeroMotion(bool inTaintTime); public abstract void ZeroAngularMotion(bool inTaintTime); diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs index 74b980c17e..6f8d9ed2e4 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Collections.Specialized; using System.IO; using System.Net; using System.Reflection; @@ -122,7 +123,7 @@ namespace OpenSim.Services.Connectors.SimianGrid m_Enabled = true; } - #region IAssetService +#region IAssetService public AssetBase Get(string id) { @@ -140,8 +141,9 @@ namespace OpenSim.Services.Connectors.SimianGrid return asset; } - return GetRemote(id); + return SimianGetOperation(id); } + public AssetBase GetCached(string id) { @@ -164,8 +166,6 @@ namespace OpenSim.Services.Connectors.SimianGrid throw new InvalidOperationException(); } - AssetMetadata metadata = null; - // Cache fetch if (m_cache != null) { @@ -174,50 +174,18 @@ namespace OpenSim.Services.Connectors.SimianGrid return asset.Metadata; } - Uri url; - - // Determine if id is an absolute URL or a grid-relative UUID - if (!Uri.TryCreate(id, UriKind.Absolute, out url)) - url = new Uri(m_serverUrl + id); - - try - { - HttpWebRequest request = UntrustedHttpWebRequest.Create(url); - request.Method = "HEAD"; - - using (WebResponse response = request.GetResponse()) - { - using (Stream responseStream = response.GetResponseStream()) - { - // Create the metadata object - metadata = new AssetMetadata(); - metadata.ContentType = response.ContentType; - metadata.ID = id; - - UUID uuid; - if (UUID.TryParse(id, out uuid)) - metadata.FullID = uuid; - - string lastModifiedStr = response.Headers.Get("Last-Modified"); - if (!String.IsNullOrEmpty(lastModifiedStr)) - { - DateTime lastModified; - if (DateTime.TryParse(lastModifiedStr, out lastModified)) - metadata.CreationDate = lastModified; - } - } - } - } - catch (Exception ex) - { - m_log.Warn("[SIMIAN ASSET CONNECTOR]: Asset HEAD from " + url + " failed: " + ex.Message); - } - - return metadata; + // return GetRemoteMetadata(id); + return SimianGetMetadataOperation(id); } - + public byte[] GetData(string id) { + if (String.IsNullOrEmpty(m_serverUrl)) + { + m_log.Error("[SIMIAN ASSET CONNECTOR]: No AssetServerURI configured"); + throw new InvalidOperationException(); + } + AssetBase asset = Get(id); if (asset != null) @@ -255,7 +223,7 @@ namespace OpenSim.Services.Connectors.SimianGrid Util.FireAndForget( delegate(object o) { - AssetBase asset = GetRemote(id); + AssetBase asset = SimianGetOperation(id); handler(id, sender, asset); } ); @@ -278,7 +246,6 @@ namespace OpenSim.Services.Connectors.SimianGrid } bool storedInCache = false; - string errorMessage = null; // AssetID handling if (String.IsNullOrEmpty(asset.ID) || asset.ID == ZeroID) @@ -307,83 +274,9 @@ namespace OpenSim.Services.Connectors.SimianGrid return asset.ID; } - // Distinguish public and private assets - bool isPublic = true; - switch ((AssetType)asset.Type) - { - case AssetType.CallingCard: - case AssetType.Gesture: - case AssetType.LSLBytecode: - case AssetType.LSLText: - isPublic = false; - break; - } - - // Make sure ContentType is set - if (String.IsNullOrEmpty(asset.Metadata.ContentType)) - asset.Metadata.ContentType = SLUtil.SLAssetTypeToContentType(asset.Type); - - // Build the remote storage request - List postParameters = new List() - { - new MultipartForm.Parameter("AssetID", asset.FullID.ToString()), - new MultipartForm.Parameter("CreatorID", asset.Metadata.CreatorID), - new MultipartForm.Parameter("Temporary", asset.Temporary ? "1" : "0"), - new MultipartForm.Parameter("Public", isPublic ? "1" : "0"), - new MultipartForm.File("Asset", asset.Name, asset.Metadata.ContentType, asset.Data) - }; - - // Make the remote storage request - try - { - // Simian does not require the asset ID to be in the URL because it's in the post data. - // By appending it to the URL also, we allow caching proxies (squid) to invalidate asset URLs - HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl + asset.FullID.ToString()); - - using (HttpWebResponse response = MultipartForm.Post(request, postParameters)) - { - using (Stream responseStream = response.GetResponseStream()) - { - string responseStr = null; - - try - { - responseStr = responseStream.GetStreamString(); - OSD responseOSD = OSDParser.Deserialize(responseStr); - if (responseOSD.Type == OSDType.Map) - { - OSDMap responseMap = (OSDMap)responseOSD; - if (responseMap["Success"].AsBoolean()) - return asset.ID; - else - errorMessage = "Upload failed: " + responseMap["Message"].AsString(); - } - else - { - errorMessage = "Response format was invalid:\n" + responseStr; - } - } - catch (Exception ex) - { - if (!String.IsNullOrEmpty(responseStr)) - errorMessage = "Failed to parse the response:\n" + responseStr; - else - errorMessage = "Failed to retrieve the response: " + ex.Message; - } - } - } - } - catch (WebException ex) - { - errorMessage = ex.Message; - } - - m_log.WarnFormat("[SIMIAN ASSET CONNECTOR]: Failed to store asset \"{0}\" ({1}, {2}): {3}", - asset.Name, asset.ID, asset.Metadata.ContentType, errorMessage); - - return null; + return SimianStoreOperation(asset); } - + /// /// Update an asset's content /// @@ -393,11 +286,17 @@ namespace OpenSim.Services.Connectors.SimianGrid /// public bool UpdateContent(string id, byte[] data) { + if (String.IsNullOrEmpty(m_serverUrl)) + { + m_log.Error("[SIMIAN ASSET CONNECTOR]: No AssetServerURI configured"); + throw new InvalidOperationException(); + } + AssetBase asset = Get(id); if (asset == null) { - m_log.Warn("[SIMIAN ASSET CONNECTOR]: Failed to fetch asset " + id + " for updating"); + m_log.WarnFormat("[SIMIAN ASSET CONNECTOR]: Failed to fetch asset {0} for updating", id); return false; } @@ -420,83 +319,347 @@ namespace OpenSim.Services.Connectors.SimianGrid throw new InvalidOperationException(); } - //string errorMessage = String.Empty; - string url = m_serverUrl + id; - if (m_cache != null) m_cache.Expire(id); + return SimianDeleteOperation(id); + } + +#endregion IAssetService + +#region SimianOperations + /// + /// Invokes the xRemoveAsset operation on the simian server to delete an asset + /// + /// + /// + private bool SimianDeleteOperation(string id) + { try { - HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); - request.Method = "DELETE"; - - using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) - { - if (response.StatusCode != HttpStatusCode.NoContent) + NameValueCollection requestArgs = new NameValueCollection { - m_log.Warn("[SIMIAN ASSET CONNECTOR]: Unexpected response when deleting asset " + url + ": " + - response.StatusCode + " (" + response.StatusDescription + ")"); - } - } + { "RequestMethod", "xRemoveAsset" }, + { "AssetID", id } + }; + OSDMap response = SimianGrid.PostToService(m_serverUrl,requestArgs); + if (! response["Success"].AsBoolean()) + { + m_log.WarnFormat("[SIMIAN ASSET CONNECTOR]: failed to delete asset; {0}",response["Message"].AsString()); + return false; + } + return true; + } catch (Exception ex) { - m_log.Warn("[SIMIAN ASSET CONNECTOR]: Failed to delete asset " + id + " from the asset service: " + ex.Message); - return false; + m_log.WarnFormat("[SIMIAN ASSET CONNECTOR]: failed to delete asset {0}; {1}", id, ex.Message); } + + return false; } - #endregion IAssetService - - private AssetBase GetRemote(string id) + /// + /// Invokes the xAddAsset operation on the simian server to create or update an asset + /// + /// + /// + private string SimianStoreOperation(AssetBase asset) { - AssetBase asset = null; - Uri url; - - // Determine if id is an absolute URL or a grid-relative UUID - if (!Uri.TryCreate(id, UriKind.Absolute, out url)) - url = new Uri(m_serverUrl + id); - try { - HttpWebRequest request = UntrustedHttpWebRequest.Create(url); - - using (WebResponse response = request.GetResponse()) - { - using (Stream responseStream = response.GetResponseStream()) + NameValueCollection requestArgs = new NameValueCollection { - string creatorID = response.Headers.GetOne("X-Asset-Creator-Id") ?? String.Empty; - - // Create the asset object - asset = new AssetBase(id, String.Empty, SLUtil.ContentTypeToSLAssetType(response.ContentType), creatorID); - - UUID assetID; - if (UUID.TryParse(id, out assetID)) - asset.FullID = assetID; - - // Grab the asset data from the response stream - using (MemoryStream stream = new MemoryStream()) - { - responseStream.CopyStream(stream, Int32.MaxValue); - asset.Data = stream.ToArray(); - } - } + { "RequestMethod", "xAddAsset" }, + { "ContentType", asset.Metadata.ContentType }, + { "EncodedData", Convert.ToBase64String(asset.Data) }, + { "AssetID", asset.FullID.ToString() }, + { "CreatorID", asset.Metadata.CreatorID }, + { "Temporary", asset.Temporary ? "1" : "0" }, + { "Name", asset.Name } + }; + + OSDMap response = SimianGrid.PostToService(m_serverUrl,requestArgs); + if (! response["Success"].AsBoolean()) + { + m_log.WarnFormat("[SIMIAN ASSET CONNECTOR] failed to store asset; {0}",response["Message"].AsString()); + return null; } - // Cache store - if (m_cache != null && asset != null) - m_cache.Cache(asset); + // asset.ID is always set before calling this function + return asset.ID; + + } + catch (Exception ex) + { + m_log.ErrorFormat("[SIMIAN ASSET CONNECTOR] failed to store asset; {0}",ex.Message); + } + + return null; + } + + /// + /// Invokes the xGetAsset operation on the simian server to get data associated with an asset + /// + /// + /// + private AssetBase SimianGetOperation(string id) + { + try + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "xGetAsset" }, + { "ID", id } + }; + + OSDMap response = SimianGrid.PostToService(m_serverUrl,requestArgs); + if (! response["Success"].AsBoolean()) + { + m_log.WarnFormat("[SIMIAN ASSET CONNECTOR] Failed to get asset; {0}",response["Message"].AsString()); + return null; + } + + AssetBase asset = new AssetBase(); + + asset.ID = id; + asset.Name = String.Empty; + asset.Metadata.ContentType = response["ContentType"].AsString(); // this will also set the asset Type property + asset.CreatorID = response["CreatorID"].AsString(); + asset.Data = System.Convert.FromBase64String(response["EncodedData"].AsString()); + asset.Local = false; + asset.Temporary = response["Temporary"]; return asset; } catch (Exception ex) { - m_log.Warn("[SIMIAN ASSET CONNECTOR]: Asset GET from " + url + " failed: " + ex.Message); - return null; + m_log.WarnFormat("[SIMIAN ASSET CONNECTOR]: failed to retrieve asset {0}; {1}", id, ex.Message); } + + return null; } + + /// + /// Invokes the xGetAssetMetadata operation on the simian server to retrieve metadata for an asset + /// This operation is generally used to determine if an asset exists in the database + /// + /// + /// + private AssetMetadata SimianGetMetadataOperation(string id) + { + try + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "xGetAssetMetadata" }, + { "ID", id } + }; + + OSDMap response = SimianGrid.PostToService(m_serverUrl,requestArgs); + if (! response["Success"].AsBoolean()) + { + // this is not really an error, this call is used to test existence + // m_log.DebugFormat("[SIMIAN ASSET CONNECTOR] Failed to get asset metadata; {0}",response["Message"].AsString()); + return null; + } + + AssetMetadata metadata = new AssetMetadata(); + metadata.ID = id; + metadata.ContentType = response["ContentType"].AsString(); + metadata.CreatorID = response["CreatorID"].AsString(); + metadata.Local = false; + metadata.Temporary = response["Temporary"]; + + string lastModifiedStr = response["Last-Modified"].AsString(); + if (! String.IsNullOrEmpty(lastModifiedStr)) + { + DateTime lastModified; + if (DateTime.TryParse(lastModifiedStr, out lastModified)) + metadata.CreationDate = lastModified; + } + + return metadata; + } + catch (Exception ex) + { + m_log.WarnFormat("[SIMIAN ASSET CONNECTOR]: Failed to get asset metadata; {0}", ex.Message); + } + + return null; + } +#endregion + + // private AssetMetadata GetRemoteMetadata(string id) + // { + // Uri url; + // AssetMetadata metadata = null; + + // // Determine if id is an absolute URL or a grid-relative UUID + // if (!Uri.TryCreate(id, UriKind.Absolute, out url)) + // url = new Uri(m_serverUrl + id); + + // try + // { + // HttpWebRequest request = UntrustedHttpWebRequest.Create(url); + // request.Method = "HEAD"; + + // using (WebResponse response = request.GetResponse()) + // { + // using (Stream responseStream = response.GetResponseStream()) + // { + // // Create the metadata object + // metadata = new AssetMetadata(); + // metadata.ContentType = response.ContentType; + // metadata.ID = id; + + // UUID uuid; + // if (UUID.TryParse(id, out uuid)) + // metadata.FullID = uuid; + + // string lastModifiedStr = response.Headers.Get("Last-Modified"); + // if (!String.IsNullOrEmpty(lastModifiedStr)) + // { + // DateTime lastModified; + // if (DateTime.TryParse(lastModifiedStr, out lastModified)) + // metadata.CreationDate = lastModified; + // } + // } + // } + // } + // catch (Exception ex) + // { + // m_log.Warn("[SIMIAN ASSET CONNECTOR]: Asset HEAD from " + url + " failed: " + ex.Message); + // } + + // return metadata; + // } + + // private AssetBase GetRemote(string id) + // { + // AssetBase asset = null; + // Uri url; + + // // Determine if id is an absolute URL or a grid-relative UUID + // if (!Uri.TryCreate(id, UriKind.Absolute, out url)) + // url = new Uri(m_serverUrl + id); + + // try + // { + // HttpWebRequest request = UntrustedHttpWebRequest.Create(url); + + // using (WebResponse response = request.GetResponse()) + // { + // using (Stream responseStream = response.GetResponseStream()) + // { + // string creatorID = response.Headers.GetOne("X-Asset-Creator-Id") ?? String.Empty; + + // // Create the asset object + // asset = new AssetBase(id, String.Empty, SLUtil.ContentTypeToSLAssetType(response.ContentType), creatorID); + + // UUID assetID; + // if (UUID.TryParse(id, out assetID)) + // asset.FullID = assetID; + + // // Grab the asset data from the response stream + // using (MemoryStream stream = new MemoryStream()) + // { + // responseStream.CopyStream(stream, Int32.MaxValue); + // asset.Data = stream.ToArray(); + // } + // } + // } + + // // Cache store + // if (m_cache != null && asset != null) + // m_cache.Cache(asset); + + // return asset; + // } + // catch (Exception ex) + // { + // m_log.Warn("[SIMIAN ASSET CONNECTOR]: Asset GET from " + url + " failed: " + ex.Message); + // return null; + // } + // } + + // private string StoreRemote(AssetBase asset) + // { + // // Distinguish public and private assets + // bool isPublic = true; + // switch ((AssetType)asset.Type) + // { + // case AssetType.CallingCard: + // case AssetType.Gesture: + // case AssetType.LSLBytecode: + // case AssetType.LSLText: + // isPublic = false; + // break; + // } + + // string errorMessage = null; + + // // Build the remote storage request + // List postParameters = new List() + // { + // new MultipartForm.Parameter("AssetID", asset.FullID.ToString()), + // new MultipartForm.Parameter("CreatorID", asset.Metadata.CreatorID), + // new MultipartForm.Parameter("Temporary", asset.Temporary ? "1" : "0"), + // new MultipartForm.Parameter("Public", isPublic ? "1" : "0"), + // new MultipartForm.File("Asset", asset.Name, asset.Metadata.ContentType, asset.Data) + // }; + + // // Make the remote storage request + // try + // { + // // Simian does not require the asset ID to be in the URL because it's in the post data. + // // By appending it to the URL also, we allow caching proxies (squid) to invalidate asset URLs + // HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl + asset.FullID.ToString()); + + // using (HttpWebResponse response = MultipartForm.Post(request, postParameters)) + // { + // using (Stream responseStream = response.GetResponseStream()) + // { + // string responseStr = null; + + // try + // { + // responseStr = responseStream.GetStreamString(); + // OSD responseOSD = OSDParser.Deserialize(responseStr); + // if (responseOSD.Type == OSDType.Map) + // { + // OSDMap responseMap = (OSDMap)responseOSD; + // if (responseMap["Success"].AsBoolean()) + // return asset.ID; + // else + // errorMessage = "Upload failed: " + responseMap["Message"].AsString(); + // } + // else + // { + // errorMessage = "Response format was invalid:\n" + responseStr; + // } + // } + // catch (Exception ex) + // { + // if (!String.IsNullOrEmpty(responseStr)) + // errorMessage = "Failed to parse the response:\n" + responseStr; + // else + // errorMessage = "Failed to retrieve the response: " + ex.Message; + // } + // } + // } + // } + // catch (WebException ex) + // { + // errorMessage = ex.Message; + // } + + // m_log.WarnFormat("[SIMIAN ASSET CONNECTOR]: Failed to store asset \"{0}\" ({1}, {2}): {3}", + // asset.Name, asset.ID, asset.Metadata.ContentType, errorMessage); + + // return null; + // } } } diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs index 03b19aef31..c402907073 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs @@ -116,7 +116,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "UserID", principalID.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean() && response["Identities"] is OSDArray) { bool md5hashFound = false; @@ -159,7 +159,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "SessionID", token } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean()) { return true; @@ -181,7 +181,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "UserID", principalID.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean()) { return true; @@ -204,7 +204,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "UserID", principalID.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean() && response["User"] is OSDMap) { OSDMap userMap = (OSDMap)response["User"]; @@ -224,7 +224,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "UserID", principalID.ToString() } }; - response = WebUtil.PostToService(m_serverUrl, requestArgs); + response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) @@ -303,7 +303,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "UserID", userID.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean()) return response["SessionID"].AsUUID().ToString(); else diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs index 841bfa0bd1..a3977407a4 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs @@ -122,7 +122,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "UserID", userID.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean()) { OSDMap map = null; @@ -168,7 +168,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "LLPackedAppearance", OSDParser.SerializeJsonString(map) } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (! success) @@ -189,7 +189,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "UserID", userID.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean()) { OSDMap map = null; @@ -306,7 +306,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "LLAttachments", OSDParser.SerializeJsonString(items) } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs b/OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs new file mode 100644 index 0000000000..8226705183 --- /dev/null +++ b/OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs @@ -0,0 +1,179 @@ +/* + * 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.Collections; +using System.Collections.Generic; +using System.Reflection; +using System.IO; +using System.Web; + +using log4net; +using Nini.Config; +using Mono.Addins; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using Caps = OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Services.Connectors.SimianGrid +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimianExternalCapsModule")] + public class SimianExternalCapsModule : INonSharedRegionModule, IExternalCapsModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private bool m_enabled = true; + private Scene m_scene; + private String m_simianURL; + + private IGridUserService m_GridUserService; + +#region IRegionModule Members + + + public string Name + { + get { return this.GetType().Name; } + } + + public void Initialise(IConfigSource config) + { + try + { + IConfig m_config; + + if ((m_config = config.Configs["SimianExternalCaps"]) != null) + { + m_enabled = m_config.GetBoolean("Enabled", m_enabled); + if ((m_config = config.Configs["SimianGrid"]) != null) + { + m_simianURL = m_config.GetString("SimianServiceURL"); + if (String.IsNullOrEmpty(m_simianURL)) + m_log.ErrorFormat("[SimianGrid] service URL is not defined"); + } + } + else + m_enabled = false; + } + catch (Exception e) + { + m_log.ErrorFormat("[SimianExternalCaps] initialization error: {0}",e.Message); + return; + } + } + + public void PostInitialise() { } + public void Close() { } + + public void AddRegion(Scene scene) + { + if (! m_enabled) + return; + + m_scene = scene; + m_scene.RegisterModuleInterface(this); + } + + public void RemoveRegion(Scene scene) + { + if (! m_enabled) + return; + + m_scene.EventManager.OnRegisterCaps -= RegisterCapsEventHandler; + m_scene.EventManager.OnDeregisterCaps -= DeregisterCapsEventHandler; + } + + public void RegionLoaded(Scene scene) + { + if (! m_enabled) + return; + + m_scene.EventManager.OnRegisterCaps += RegisterCapsEventHandler; + m_scene.EventManager.OnDeregisterCaps += DeregisterCapsEventHandler; + } + + public Type ReplaceableInterface + { + get { return null; } + } + +#endregion + +#region IExternalCapsModule + // Eg http://grid.sciencesim.com/GridPublic/%CAP%/%OP%/" + public bool RegisterExternalUserCapsHandler(UUID agentID, Caps caps, String capName, String urlSkel) + { + UUID cap = UUID.Random(); + + // Call to simian to register the cap we generated + // NameValueCollection requestArgs = new NameValueCollection + // { + // { "RequestMethod", "AddCapability" }, + // { "Resource", "user" }, + // { "Expiration", 0 }, + // { "OwnerID", agentID.ToString() }, + // { "CapabilityID", cap.ToString() } + // }; + + // OSDMap response = SimianGrid.PostToService(m_simianURL, requestArgs); + + Dictionary subs = new Dictionary(); + subs["%OP%"] = capName; + subs["%USR%"] = agentID.ToString(); + subs["%CAP%"] = cap.ToString(); + subs["%SIM%"] = m_scene.RegionInfo.RegionID.ToString(); + + caps.RegisterHandler(capName,ExpandSkeletonURL(urlSkel,subs)); + return true; + } + +#endregion + +#region EventHandlers + public void RegisterCapsEventHandler(UUID agentID, Caps caps) { } + public void DeregisterCapsEventHandler(UUID agentID, Caps caps) { } +#endregion + + private String ExpandSkeletonURL(String urlSkel, Dictionary subs) + { + String result = urlSkel; + + foreach (KeyValuePair kvp in subs) + { + result = result.Replace(kvp.Key,kvp.Value); + } + + return result; + } + } +} \ No newline at end of file diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs index 7422d94b44..9a8164c5bf 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs @@ -153,7 +153,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "Value", flags.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) @@ -180,7 +180,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "Key", friend } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) @@ -200,7 +200,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "Type", "Friend" } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { return (OSDArray)response["Entries"]; @@ -221,7 +221,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "Type", "Friend" } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { return (OSDArray)response["Entries"]; diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs index 847319c25a..a4dd36c40e 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs @@ -26,8 +26,122 @@ */ using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Reflection; + +using log4net; using Mono.Addins; using Nini.Config; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + [assembly: Addin("SimianGrid", "1.0")] [assembly: AddinDependency("OpenSim", "0.5")] + +namespace OpenSim.Services.Connectors.SimianGrid +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimianExternalCapsModule")] + public class SimianGrid : ISharedRegionModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private IConfig m_config = null; + private bool m_enabled = true; + + private String m_simianURL; + +#region IRegionModule Members + + public string Name + { + get { return this.GetType().Name; } + } + + + public void Initialise(IConfigSource config) + { + try + { + m_config = config.Configs["SimianGrid"]; + + if (m_config != null) + { + m_simianURL = m_config.GetString("SimianServiceURL"); + if (String.IsNullOrEmpty(m_simianURL)) + m_log.ErrorFormat("[SimianGrid] service URL is not defined"); + + InitialiseSimCap(); + SimulatorCapability = SimulatorCapability.Trim(); + m_log.WarnFormat("[SimianExternalCaps] using {0} as simulator capability",SimulatorCapability); + } + } + catch (Exception e) + { + m_log.ErrorFormat("[SimianExternalCaps] initialization error: {0}",e.Message); + return; + } + } + + public void PostInitialise() { } + public void Close() { } + public void AddRegion(Scene scene) { } + public void RemoveRegion(Scene scene) { } + public void RegionLoaded(Scene scene) { } + + public Type ReplaceableInterface + { + get { return null; } + } + + /// + /// Try a variety of methods for finding the simian simulator capability; first check the + /// configuration itself, then look for a file that contains the cap, then finally look + /// for an environment variable that contains it. + /// + private void InitialiseSimCap() + { + if (m_config.Contains("SimulatorCapability")) + { + SimulatorCapability = m_config.GetString("SimulatorCapability"); + return; + } + + if (m_config.Contains("SimulatorCapabilityFile")) + { + String filename = m_config.GetString("SimulatorCapabilityFile"); + if (System.IO.File.Exists(filename)) + { + SimulatorCapability = System.IO.File.ReadAllText(filename); + return; + } + } + + if (m_config.Contains("SimulatorCapabilityVariable")) + { + String envname = m_config.GetString("SimulatorCapabilityVariable"); + String envvalue = System.Environment.GetEnvironmentVariable(envname); + if (envvalue != null) + { + SimulatorCapability = envvalue; + return; + } + } + + m_log.WarnFormat("[SimianExternalCaps] no method specified for simulator capability"); + } + +#endregion + public static String SimulatorCapability = UUID.Zero.ToString(); + public static OSDMap PostToService(string url, NameValueCollection data) + { + data["cap"] = SimulatorCapability; + return WebUtil.PostToService(url, data); + } + } +} diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs index 93fdae38c1..b999509510 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Collections.Specialized; using System.Reflection; using System.Net; using System.IO; @@ -43,7 +44,8 @@ using OpenSim.Region.Framework.Scenes; using OpenMetaverse; using OpenMetaverse.StructuredData; -namespace OpenSim.Region.OptionalModules.Simian +//namespace OpenSim.Region.OptionalModules.Simian +namespace OpenSim.Services.Connectors.SimianGrid { /// /// @@ -196,67 +198,84 @@ namespace OpenSim.Region.OptionalModules.Simian } } - List postParameters = new List() - { - new MultipartForm.Parameter("X", scene.RegionInfo.RegionLocX.ToString()), - new MultipartForm.Parameter("Y", scene.RegionInfo.RegionLocY.ToString()), - new MultipartForm.File("Tile", "tile.png", "image/png", pngData) - }; - - string errorMessage = null; - int tickstart = Util.EnvironmentTickCount(); - - // Make the remote storage request - try - { - HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl); - request.Timeout = 20000; - request.ReadWriteTimeout = 5000; - - using (HttpWebResponse response = MultipartForm.Post(request, postParameters)) + NameValueCollection requestArgs = new NameValueCollection { - using (Stream responseStream = response.GetResponseStream()) - { - string responseStr = responseStream.GetStreamString(); - OSD responseOSD = OSDParser.Deserialize(responseStr); - if (responseOSD.Type == OSDType.Map) - { - OSDMap responseMap = (OSDMap)responseOSD; - if (responseMap["Success"].AsBoolean()) - return; - - errorMessage = "Upload failed: " + responseMap["Message"].AsString(); - } - else - { - errorMessage = "Response format was invalid:\n" + responseStr; - } - } - } - } - catch (WebException we) + { "RequestMethod", "xAddMapTile" }, + { "X", scene.RegionInfo.RegionLocX.ToString() }, + { "Y", scene.RegionInfo.RegionLocY.ToString() }, + { "ContentType", "image/png" }, + { "EncodedData", System.Convert.ToBase64String(pngData) } + }; + + OSDMap response = SimianGrid.PostToService(m_serverUrl,requestArgs); + if (! response["Success"].AsBoolean()) { - errorMessage = we.Message; - if (we.Status == WebExceptionStatus.ProtocolError) - { - HttpWebResponse webResponse = (HttpWebResponse)we.Response; - errorMessage = String.Format("[{0}] {1}", - webResponse.StatusCode,webResponse.StatusDescription); - } - } - catch (Exception ex) - { - errorMessage = ex.Message; - } - finally - { - // This just dumps a warning for any operation that takes more than 100 ms - int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); - m_log.DebugFormat("[SIMIAN MAPTILE]: map tile uploaded in {0}ms",tickdiff); + m_log.WarnFormat("[SIMIAN MAPTILE] failed to store map tile; {0}",response["Message"].AsString()); + return; } - m_log.WarnFormat("[SIMIAN MAPTILE]: Failed to store {0} byte tile for {1}: {2}", - pngData.Length, scene.RegionInfo.RegionName, errorMessage); + // List postParameters = new List() + // { + // new MultipartForm.Parameter("X", scene.RegionInfo.RegionLocX.ToString()), + // new MultipartForm.Parameter("Y", scene.RegionInfo.RegionLocY.ToString()), + // new MultipartForm.File("Tile", "tile.png", "image/png", pngData) + // }; + + // string errorMessage = null; + // int tickstart = Util.EnvironmentTickCount(); + + // // Make the remote storage request + // try + // { + // HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl); + // request.Timeout = 20000; + // request.ReadWriteTimeout = 5000; + + // using (HttpWebResponse response = MultipartForm.Post(request, postParameters)) + // { + // using (Stream responseStream = response.GetResponseStream()) + // { + // string responseStr = responseStream.GetStreamString(); + // OSD responseOSD = OSDParser.Deserialize(responseStr); + // if (responseOSD.Type == OSDType.Map) + // { + // OSDMap responseMap = (OSDMap)responseOSD; + // if (responseMap["Success"].AsBoolean()) + // return; + + // errorMessage = "Upload failed: " + responseMap["Message"].AsString(); + // } + // else + // { + // errorMessage = "Response format was invalid:\n" + responseStr; + // } + // } + // } + // } + // catch (WebException we) + // { + // errorMessage = we.Message; + // if (we.Status == WebExceptionStatus.ProtocolError) + // { + // HttpWebResponse webResponse = (HttpWebResponse)we.Response; + // errorMessage = String.Format("[{0}] {1}", + // webResponse.StatusCode,webResponse.StatusDescription); + // } + // } + // catch (Exception ex) + // { + // errorMessage = ex.Message; + // } + // finally + // { + // // This just dumps a warning for any operation that takes more than 100 ms + // int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); + // m_log.DebugFormat("[SIMIAN MAPTILE]: map tile uploaded in {0}ms",tickdiff); + // } + + // m_log.WarnFormat("[SIMIAN MAPTILE]: Failed to store {0} byte tile for {1}: {2}", + // pngData.Length, scene.RegionInfo.RegionName, errorMessage); + } } } \ No newline at end of file diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs index 20eaa3a788..043d131128 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs @@ -140,7 +140,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "ExtraData", OSDParser.SerializeJsonString(extraData) } }; - OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); + OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs); if (response["Success"].AsBoolean()) return String.Empty; else @@ -156,7 +156,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "Enabled", "0" } }; - OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); + OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) @@ -203,7 +203,7 @@ namespace OpenSim.Services.Connectors.SimianGrid // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request region with uuid {0}",regionID.ToString()); - OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); + OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs); if (response["Success"].AsBoolean()) { // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] uuid request successful {0}",response["Name"].AsString()); @@ -231,7 +231,7 @@ namespace OpenSim.Services.Connectors.SimianGrid // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request grid at {0}",position.ToString()); - OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); + OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs); if (response["Success"].AsBoolean()) { // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] position request successful {0}",response["Name"].AsString()); @@ -272,7 +272,7 @@ namespace OpenSim.Services.Connectors.SimianGrid // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request regions with name {0}",name); - OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); + OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs); if (response["Success"].AsBoolean()) { // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] found regions with name {0}",name); @@ -310,7 +310,7 @@ namespace OpenSim.Services.Connectors.SimianGrid //m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request regions by range {0} to {1}",minPosition.ToString(),maxPosition.ToString()); - OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); + OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs); if (response["Success"].AsBoolean()) { OSDArray array = response["Scenes"] as OSDArray; @@ -361,7 +361,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "Enabled", "1" } }; - OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); + OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs); if (response["Success"].AsBoolean()) { // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] found regions with name {0}",name); @@ -391,7 +391,7 @@ namespace OpenSim.Services.Connectors.SimianGrid m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request region flags for {0}",regionID.ToString()); - OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); + OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs); if (response["Success"].AsBoolean()) { OSDMap extraData = response["ExtraData"] as OSDMap; @@ -498,7 +498,7 @@ namespace OpenSim.Services.Connectors.SimianGrid if (onlyEnabled) requestArgs["Enabled"] = "1"; - OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); + OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs); if (response["Success"].AsBoolean()) { return ResponseToGridRegion(response); diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs index 36325ce483..97eaabe68a 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs @@ -156,7 +156,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "OwnerID", userID.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) @@ -182,7 +182,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "ChildrenOnly", "0" } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean() && response["Items"] is OSDArray) { OSDArray items = (OSDArray)response["Items"]; @@ -244,7 +244,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "ChildrenOnly", "1" } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean() && response["Items"] is OSDArray) { OSDArray items = (OSDArray)response["Items"]; @@ -274,7 +274,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "OwnerID", userID.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean() && response["Folder"] is OSDMap) { OSDMap folder = (OSDMap)response["Folder"]; @@ -312,7 +312,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "ChildrenOnly", "1" } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean() && response["Items"] is OSDArray) { List items = GetItemsFromResponse((OSDArray)response["Items"]); @@ -349,7 +349,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "ChildrenOnly", "1" } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean() && response["Items"] is OSDArray) { OSDArray items = (OSDArray)response["Items"]; @@ -383,7 +383,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "ChildrenOnly", "1" } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean() && response["Items"] is OSDArray) { OSDArray items = (OSDArray)response["Items"]; @@ -423,7 +423,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "ChildrenOnly", "1" } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean() && response["Items"] is OSDArray) { OSDArray items = (OSDArray)response["Items"]; @@ -454,7 +454,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "ContentType", SLUtil.SLAssetTypeToContentType(folder.Type) } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) @@ -518,7 +518,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "ItemID", itemID.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) @@ -546,7 +546,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "FolderID", folder.ID.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) @@ -623,7 +623,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "ExtraData", OSDParser.SerializeJsonString(extraData) } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) @@ -847,7 +847,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "Items", String.Join(",", itemIDs) } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) @@ -885,7 +885,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "UserID", userID.ToString() } }; - OSDMap response = WebUtil.PostToService(m_userServerUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_userServerUrl, requestArgs); if (response["Success"].AsBoolean()) { OSDMap user = response["User"] as OSDMap; @@ -916,7 +916,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "Gestures", OSDParser.SerializeJsonString(gestures) } }; - OSDMap response = WebUtil.PostToService(m_userServerUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_userServerUrl, requestArgs); if (!response["Success"].AsBoolean()) { m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to save active gestures for " + userID + ": " + diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs index 01163aae0b..211b775368 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs @@ -149,7 +149,7 @@ namespace OpenSim.Services.Connectors.SimianGrid requestArgs["SecureSessionID"] = secureSessionID.ToString(); } - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) @@ -168,7 +168,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "SessionID", sessionID.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) @@ -187,7 +187,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "SceneID", regionID.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) @@ -232,7 +232,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "UserIDList", String.Join(",",userIDs) } }; - OSDMap sessionListResponse = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap sessionListResponse = SimianGrid.PostToService(m_serverUrl, requestArgs); if (! sessionListResponse["Success"].AsBoolean()) { m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve sessions: {0}",sessionListResponse["Message"].AsString()); @@ -275,7 +275,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "LastLocation", SerializeLocation(regionID, lastPosition, lastLookAt) } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) @@ -295,7 +295,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "HomeLocation", SerializeLocation(regionID, position, lookAt) } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) @@ -340,7 +340,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "UserID", userID.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean() && response["User"] is OSDMap) return response; @@ -356,7 +356,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "SessionID", sessionID.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean()) return response; @@ -376,7 +376,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "SceneLookAt", lastLookAt.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs index bd8069f49c..684a0db9de 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs @@ -392,7 +392,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "UserID", client.AgentId.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); string email = response["Email"].AsString(); if (!response["Success"].AsBoolean()) @@ -443,7 +443,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { key, OSDParser.SerializeJsonString(value) } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (!success) @@ -462,7 +462,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "UserID", userID.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean() && response["User"] is OSDMap) { return (OSDMap)response["User"]; diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs index fcb5115d6e..fdc86972be 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs @@ -165,7 +165,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "NameQuery", query } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean()) { OSDArray array = response["Users"] as OSDArray; @@ -209,7 +209,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "AccessLevel", data.UserLevel.ToString() } }; - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean()) { @@ -224,7 +224,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "UserTitle", data.UserTitle } }; - response = WebUtil.PostToService(m_serverUrl, requestArgs); + response = SimianGrid.PostToService(m_serverUrl, requestArgs); bool success = response["Success"].AsBoolean(); if (success) @@ -257,7 +257,7 @@ namespace OpenSim.Services.Connectors.SimianGrid string lookupValue = (requestArgs.Count > 1) ? requestArgs[1] : "(Unknown)"; // m_log.DebugFormat("[SIMIAN ACCOUNT CONNECTOR]: Looking up user account with query: " + lookupValue); - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); if (response["Success"].AsBoolean()) { OSDMap user = response["User"] as OSDMap; diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index d12ea5ba2a..920a691451 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -205,3 +205,12 @@ ; DisallowResidents -- only Admins and Managers allowed ; Example: ; Region_Test_1 = "DisallowForeigners" + + +;; Uncomment if you are using SimianGrid for grid services +[SimianGrid] + ;; SimianGrid services URL + ;; SimianServiceURL = "http://grid.sciencesim.com/Grid/" + + ;; Capability assigned by the grid administrator for the simulator + ;; SimulatorCapability = "00000000-0000-0000-0000-000000000000" \ No newline at end of file diff --git a/prebuild.xml b/prebuild.xml index d536539ec8..87c07a7369 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -988,8 +988,10 @@ + +