From 33b54807a1646a9457a7a718f767ccec1c0cb39f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 28 Jul 2013 18:08:50 -0700 Subject: [PATCH 01/20] Changing the visibility test in groups service to be UUID.Zero.ToString() instead of "all" because some paths in the code assume there's a UUI in the RequestingAgent string. --- OpenSim/Addons/Groups/GroupsMessagingModule.cs | 4 ++-- .../Groups/Hypergrid/GroupsServiceHGConnectorModule.cs | 5 ++++- OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs | 1 + OpenSim/Addons/Groups/Service/GroupsService.cs | 4 ++-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/OpenSim/Addons/Groups/GroupsMessagingModule.cs b/OpenSim/Addons/Groups/GroupsMessagingModule.cs index 5de1fb4c6a..cd45432734 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; @@ -403,7 +403,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 groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), GroupID); List alreadySeen = new List(); //if (m_debugEnabled) diff --git a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs index daa07282ab..5e539815d6 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); 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? From 1d4bf06fe7731f4ca3d8f27a38d64f67d222c6af Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 28 Jul 2013 18:49:10 -0700 Subject: [PATCH 02/20] Group chat: guard against duplicate sends --- OpenSim/Addons/Groups/GroupsMessagingModule.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/OpenSim/Addons/Groups/GroupsMessagingModule.cs b/OpenSim/Addons/Groups/GroupsMessagingModule.cs index cd45432734..83d296ed56 100644 --- a/OpenSim/Addons/Groups/GroupsMessagingModule.cs +++ b/OpenSim/Addons/Groups/GroupsMessagingModule.cs @@ -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) From 1b94de8e58434cc882e1dde83919ecd3f1425e3f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 28 Jul 2013 19:31:17 -0700 Subject: [PATCH 03/20] Group chat: prevent a situation where dupe IMs could occur. --- OpenSim/Addons/Groups/GroupsMessagingModule.cs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/OpenSim/Addons/Groups/GroupsMessagingModule.cs b/OpenSim/Addons/Groups/GroupsMessagingModule.cs index 83d296ed56..be59c6258c 100644 --- a/OpenSim/Addons/Groups/GroupsMessagingModule.cs +++ b/OpenSim/Addons/Groups/GroupsMessagingModule.cs @@ -405,7 +405,6 @@ namespace OpenSim.Groups GridRegion regionOfOrigin = aScene.GridService.GetRegionByUUID(aScene.RegionInfo.ScopeID, regionID); List groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), GroupID); - List alreadySeen = new List(); //if (m_debugEnabled) // foreach (GroupMembersData m in groupMembers) @@ -415,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 => { From 7eee9eb312e9f947d201e0ef3e2f34bceec4568d Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 28 Jul 2013 20:47:15 -0700 Subject: [PATCH 04/20] Groups: Better warning messages to the user. --- OpenSim/Addons/Groups/GroupsModule.cs | 4 ++++ .../Groups/Hypergrid/GroupsServiceHGConnectorModule.cs | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) 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 5e539815d6..c33168ce26 100644 --- a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs +++ b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs @@ -399,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 From 8efe4bfc2ed7086e9fdf4812297e6525f955f6ac Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 29 Jul 2013 23:18:29 +0100 Subject: [PATCH 05/20] Make "abnormal thread terminations" into "ClientLogoutsDueToNoReceives" and add this to the StatsManager This reflects the actual use of this stat - it hasn't recorded general exceptions for some time. Make the sim extra stats collector draw the data from the stats manager rather than maintaing this data itself. --- .../Monitoring/SimExtraStatsCollector.cs | 25 +++---- OpenSim/Framework/Monitoring/StatsManager.cs | 65 +++++++++++++++++-- .../ClientStack/Linden/UDP/LLUDPServer.cs | 26 ++++++-- 3 files changed, 89 insertions(+), 27 deletions(-) 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/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 25e10bef4f..9e6a4019e5 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 /// @@ -1037,7 +1053,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP timeoutTicks = m_pausedAckTimeout; if (client.IsActive && - (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) + (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > -1) { // We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even // though it's set later on by LLClientView.Close() @@ -1778,7 +1794,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP "[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}", client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName); - StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); + ClientLogoutsDueToNoReceives++; if (!client.SceneAgent.IsChildAgent) client.Kick("Simulator logged you out due to connection timeout"); From 8004e6f31cb03abc9b6170622099879ccaf5570b Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 29 Jul 2013 23:38:54 +0100 Subject: [PATCH 06/20] Fix issue just introduced in 8efe4bfc2ed7086e9fdf4812297e6525f955f6ac where I accidentally left in a test line to force very quick client unack --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 9e6a4019e5..bf50868dd3 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1053,7 +1053,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP timeoutTicks = m_pausedAckTimeout; if (client.IsActive && - (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > -1) + (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) { // We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even // though it's set later on by LLClientView.Close() From 1416c909326d89566cbe785b6dacac228e31a5a0 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 29 Jul 2013 23:53:59 +0100 Subject: [PATCH 07/20] minor: Add timeout secs to connection timeout message. Change message to reflect it is a timeout due to no data received rather than an ack issue. --- .../ClientStack/Linden/UDP/LLUDPServer.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index bf50868dd3..85fe1a4050 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1062,7 +1062,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; } @@ -1786,18 +1786,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// regular client pings. /// /// - private void DeactivateClientDueToTimeout(LLClientView client) + /// + private void DeactivateClientDueToTimeout(LLClientView client, int timeoutTicks) { lock (client.CloseSyncLock) - { - m_log.WarnFormat( - "[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}", - client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName); - + { ClientLogoutsDueToNoReceives++; + + m_log.WarnFormat( + "[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(); } From 5a7784a0e6c3f549d0e7b59380ad05729cb93a4f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 24 Jul 2013 10:52:54 -0700 Subject: [PATCH 08/20] BulletSim: make density display and return value consistant with how the simulator expects it (scaled to 100kg/m^3). --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 13 +++++++------ .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 15 ++++++++++++++- 3 files changed, 22 insertions(+), 8 deletions(-) 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/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); From 6ad577d32bcb7520a33e4c0c7510d81a7cad674c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 30 Jul 2013 15:22:32 -0700 Subject: [PATCH 09/20] BulletSim: test method for debugging of extended physics script operations. --- .../ExtendedPhysics/ExtendedPhysics.cs | 54 ++++++++++++++++--- 1 file changed, 46 insertions(+), 8 deletions(-) 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); + } } } } From 0d189165a83bb97f243a1f29cfa6896936ca6db0 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 30 Jul 2013 15:23:33 -0700 Subject: [PATCH 10/20] BulletSim: distribute vehicle physical settings to all members of a linkset. Enables constraint based linksets. Rename some internal variables to clarify whether values world or vehicle relative. --- .../Physics/BulletSPlugin/BSDynamics.cs | 75 ++++++++++--------- .../Region/Physics/BulletSPlugin/BSLinkset.cs | 18 ++++- .../BulletSPlugin/BSLinksetCompound.cs | 11 ++- 3 files changed, 61 insertions(+), 43 deletions(-) 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) From 2b5419927143667048bddf0a501e42c093a71147 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 30 Jul 2013 17:26:56 -0700 Subject: [PATCH 11/20] After talking to lkalif on the IRC: SimulatorFeatures response: renamed the OSDMap GridServices to OpenSimExtras, normalized the url keys under it, and moved ExportEnabled to under it too. Melanie: change your viewer code accordingly. Documentation at http://opensimulator.org/wiki/SimulatorFeatures_Extras --- .../Linden/Caps/SimulatorFeaturesModule.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index 7d9f935d42..4bd17b1b8c 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs @@ -149,15 +149,16 @@ namespace OpenSim.Region.ClientStack.Linden m_features["PhysicsShapeTypes"] = typesMap; // Extra information for viewers that want to use it - OSDMap gridServicesMap = new OSDMap(); + OSDMap extrasMap = new OSDMap(); if (m_MapImageServerURL != string.Empty) - gridServicesMap["map-server-url"] = m_MapImageServerURL; + extrasMap["map-server-url"] = m_MapImageServerURL; 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; + } } From fd050fca7caef83d72d00241d0c0db5c1ec5d1ff Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 30 Jul 2013 21:10:00 -0700 Subject: [PATCH 12/20] Doing the HG Map / SimulatorFeatures "the right way": moved it to HGMapModule, hooking on to SimulatorFeatures.OnSimulatorFeaturesRequest event (similar to what the DynamicMenuModule does). Only HG Visitors get this var, to avoid spamming local users. The config var is now called MapTileURL, to be consistent with the login one, and its being picked up from either [LoginService], [HGWorldMap] or [SimulatorFeatures], just because I have a bad memory. --- .../Linden/Caps/SimulatorFeaturesModule.cs | 15 ++---- .../CoreModules/Hypergrid/HGWorldMapModule.cs | 47 ++++++++++++++++++- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index 4bd17b1b8c..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,13 +140,13 @@ namespace OpenSim.Region.ClientStack.Linden m_features["PhysicsShapeTypes"] = typesMap; // Extra information for viewers that want to use it + // TODO: Take these out of here into their respective modules, like map-server-url OSDMap extrasMap = new OSDMap(); - if (m_MapImageServerURL != string.Empty) - extrasMap["map-server-url"] = m_MapImageServerURL; if (m_SearchURL != string.Empty) extrasMap["search-server-url"] = m_SearchURL; if (m_ExportSupported) extrasMap["ExportSupported"] = true; + if (extrasMap.Count > 0) m_features["OpenSimExtras"] = extrasMap; diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index c4255b951d..4a5a35250b 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,13 +49,30 @@ 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 (m_MapImageServerURL != string.Empty) + { + m_MapImageServerURL = m_MapImageServerURL.Trim(); + if (!m_MapImageServerURL.EndsWith("/")) + m_MapImageServerURL = m_MapImageServerURL + "/"; + } + + + } } public override void AddRegion(Scene scene) @@ -64,6 +82,17 @@ namespace OpenSim.Region.CoreModules.Hypergrid scene.EventManager.OnClientClosed += new EventManager.ClientClosed(EventManager_OnClientClosed); } + public override void RegionLoaded(Scene scene) + { + base.RegionLoaded(scene); + ISimulatorFeaturesModule featuresModule = m_scene.RequestModuleInterface(); + + if (featuresModule != null) + featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest; + + m_UserManagement = m_scene.RequestModuleInterface(); + + } public override string Name { get { return "HGWorldMap"; } @@ -115,6 +144,20 @@ namespace OpenSim.Region.CoreModules.Hypergrid return mapBlocks; } + private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features) + { + if (m_UserManagement != null && !m_UserManagement.IsLocalGridUser(agentID) && m_MapImageServerURL != string.Empty) + { + OSD extras = new OSDMap(); + if (features.ContainsKey("OpenSimExtras")) + extras = features["OpenSimExtras"]; + else + features["OpenSimExtras"] = extras; + + ((OSDMap)extras)["map-server-url"] = m_MapImageServerURL; + + } + } } class MapArea From e4ecbc2b104959eced649e1620108afca22346dc Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 30 Jul 2013 21:38:41 -0700 Subject: [PATCH 13/20] Fix null ref. --- OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index 4a5a35250b..a7dd44ef3d 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs @@ -64,7 +64,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid m_MapImageServerURL = Util.GetConfigVarFromSections(source, "MapTileURL", new string[] {"LoginService", "HGWorldMap", "SimulatorFeatures"}); - if (m_MapImageServerURL != string.Empty) + if (!string.IsNullOrEmpty(m_MapImageServerURL)) { m_MapImageServerURL = m_MapImageServerURL.Trim(); if (!m_MapImageServerURL.EndsWith("/")) From 3c540f0d33894060d53616aa0aa67bc9d8ab82ec Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 30 Jul 2013 22:07:33 -0700 Subject: [PATCH 14/20] Avoid another null ref opportunity. --- OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index a7dd44ef3d..a2aee08913 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs @@ -146,7 +146,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features) { - if (m_UserManagement != null && !m_UserManagement.IsLocalGridUser(agentID) && m_MapImageServerURL != string.Empty) + if (m_UserManagement != null && !string.IsNullOrEmpty(m_MapImageServerURL) && !m_UserManagement.IsLocalGridUser(agentID)) { OSD extras = new OSDMap(); if (features.ContainsKey("OpenSimExtras")) From 87fcff9fc39f180ceb7d5511ca8bc23965fab17f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 31 Jul 2013 11:13:55 -0700 Subject: [PATCH 15/20] HGWorldMapModule: check whether it's enabled or not. --- OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index a2aee08913..cb22f0b0c3 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs @@ -77,6 +77,9 @@ namespace OpenSim.Region.CoreModules.Hypergrid public override void AddRegion(Scene scene) { + if (!m_Enabled) + return; + base.AddRegion(scene); scene.EventManager.OnClientClosed += new EventManager.ClientClosed(EventManager_OnClientClosed); @@ -84,6 +87,9 @@ namespace OpenSim.Region.CoreModules.Hypergrid public override void RegionLoaded(Scene scene) { + if (!m_Enabled) + return; + base.RegionLoaded(scene); ISimulatorFeaturesModule featuresModule = m_scene.RequestModuleInterface(); From ac2ad9690d9e8b8988dc68cf4e2933c7b18a71bc Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 31 Jul 2013 11:20:27 -0700 Subject: [PATCH 16/20] HGWorldMapModule: unregister event on RemoveRegion --- .../Region/CoreModules/Hypergrid/HGWorldMapModule.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index cb22f0b0c3..97227b3c4b 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs @@ -82,7 +82,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid base.AddRegion(scene); - scene.EventManager.OnClientClosed += new EventManager.ClientClosed(EventManager_OnClientClosed); + scene.EventManager.OnClientClosed += EventManager_OnClientClosed; } public override void RegionLoaded(Scene scene) @@ -99,6 +99,15 @@ namespace OpenSim.Region.CoreModules.Hypergrid m_UserManagement = m_scene.RequestModuleInterface(); } + + public override void RemoveRegion(Scene scene) + { + if (!m_Enabled) + return; + + scene.EventManager.OnClientClosed -= EventManager_OnClientClosed; + } + public override string Name { get { return "HGWorldMap"; } From 64f2dc778ad7a080ba89a1077da538c011c7c934 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 31 Jul 2013 11:27:35 -0700 Subject: [PATCH 17/20] A pretty major restructuring of the simian method invocations in order to service access capabilities. In conjunction with the corresponding Simian updates, this enables explicit per-simulator capability-based access to grid services. That enables grid owners to add or revoke access to the grid on a simulator by simulator basis. --- .../SimianGrid/SimianAssetServiceConnector.cs | 513 ++++++++++++------ .../SimianAuthenticationServiceConnector.cs | 12 +- .../SimianAvatarServiceConnector.cs | 8 +- .../SimianFriendsServiceConnector.cs | 8 +- .../Connectors/SimianGrid/SimianGrid.cs | 114 ++++ .../SimianGrid/SimianGridMaptileModule.cs | 135 +++-- .../SimianGrid/SimianGridServiceConnector.cs | 18 +- .../SimianInventoryServiceConnector.cs | 30 +- .../SimianPresenceServiceConnector.cs | 18 +- .../Connectors/SimianGrid/SimianProfiles.cs | 6 +- .../SimianUserAccountServiceConnector.cs | 8 +- 11 files changed, 583 insertions(+), 287 deletions(-) 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 6603f6e4dc..3bd11d99a3 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs @@ -110,7 +110,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; @@ -153,7 +153,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; @@ -175,7 +175,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; @@ -198,7 +198,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"]; @@ -218,7 +218,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) @@ -297,7 +297,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/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 038a4bf2b6..bcc1e4adc9 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs @@ -129,7 +129,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 @@ -145,7 +145,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) @@ -192,7 +192,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()); @@ -220,7 +220,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()); @@ -261,7 +261,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); @@ -299,7 +299,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; @@ -350,7 +350,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); @@ -380,7 +380,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; @@ -410,7 +410,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 6e32b3a7be..7e36c69cc7 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; @@ -204,7 +204,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()) { @@ -219,7 +219,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) @@ -252,7 +252,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; From d82126b651d07893c701c8477630aabf022b30d0 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 31 Jul 2013 11:42:22 -0700 Subject: [PATCH 18/20] Add the Simian service config to the GridCommon example --- bin/config-include/GridCommon.ini.example | 9 +++++++++ 1 file changed, 9 insertions(+) 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 From 12995924052a1804f01dceb80803447fccc1d9fe Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 31 Jul 2013 15:37:15 -0700 Subject: [PATCH 19/20] Experimental comment to eneralize the handling of Linden caps when the cap is something other than "localhost". A new interface for handling external caps is supported with an example implemented for Simian. The only linden cap supporting this interface right now is the GetTexture cap. --- .../Linden/Caps/GetTextureModule.cs | 6 +- .../Interfaces/IExternalCapsModule.cs | 48 +++++ .../SimianGrid/SimianExternalCapsModule.cs | 179 ++++++++++++++++++ prebuild.xml | 1 + 4 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 OpenSim/Region/Framework/Interfaces/IExternalCapsModule.cs create mode 100644 OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index 13415f82fc..54cf285cf6 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -137,7 +137,11 @@ namespace OpenSim.Region.ClientStack.Linden else { // m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); - caps.RegisterHandler("GetTexture", m_URL); + IExternalCapsModule handler = m_scene.RequestModuleInterface(); + if (handler != null) + handler.RegisterExternalUserCapsHandler(agentID,caps,"GetTexture",m_URL); + else + caps.RegisterHandler("GetTexture", m_URL); } } 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/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/prebuild.xml b/prebuild.xml index 91c326c14e..b376e86a73 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -869,6 +869,7 @@ + From 9f05a7ac7bfba66989b053af06dca051a522a9b1 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 1 Aug 2013 00:25:59 +0100 Subject: [PATCH 20/20] Include missing reference that probably stops windows build from commit 12995924052a1804f01dceb80803447fccc1d9fe --- prebuild.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/prebuild.xml b/prebuild.xml index b376e86a73..af8f686b79 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -872,6 +872,7 @@ +