From 33b54807a1646a9457a7a718f767ccec1c0cb39f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 28 Jul 2013 18:08:50 -0700 Subject: 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 ++-- OpenSim/Addons/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(-) (limited to 'OpenSim') diff --git a/OpenSim/Addons/Groups/GroupsMessagingModule.cs b/OpenSim/Addons/Groups/GroupsMessagingModule.cs index 5de1fb4..cd45432 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 daa0728..5e53981 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 9a3e125..161ca0c 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 294b89a..037ef59 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? -- cgit v1.1 From 1d4bf06fe7731f4ca3d8f27a38d64f67d222c6af Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 28 Jul 2013 18:49:10 -0700 Subject: Group chat: guard against duplicate sends --- OpenSim/Addons/Groups/GroupsMessagingModule.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Addons/Groups/GroupsMessagingModule.cs b/OpenSim/Addons/Groups/GroupsMessagingModule.cs index cd45432..83d296e 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) -- cgit v1.1 From 1b94de8e58434cc882e1dde83919ecd3f1425e3f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 28 Jul 2013 19:31:17 -0700 Subject: Group chat: prevent a situation where dupe IMs could occur. --- OpenSim/Addons/Groups/GroupsMessagingModule.cs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Addons/Groups/GroupsMessagingModule.cs b/OpenSim/Addons/Groups/GroupsMessagingModule.cs index 83d296e..be59c62 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 => { -- cgit v1.1 From 7eee9eb312e9f947d201e0ef3e2f34bceec4568d Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 28 Jul 2013 20:47:15 -0700 Subject: Groups: Better warning messages to the user. --- OpenSim/Addons/Groups/GroupsModule.cs | 4 ++++ .../Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Addons/Groups/GroupsModule.cs b/OpenSim/Addons/Groups/GroupsModule.cs index 826fcbf..da8030c 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 5e53981..c33168c 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 -- cgit v1.1 From 8efe4bfc2ed7086e9fdf4812297e6525f955f6ac Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 29 Jul 2013 23:18:29 +0100 Subject: 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. --- .../Framework/Monitoring/SimExtraStatsCollector.cs | 25 +++------ OpenSim/Framework/Monitoring/StatsManager.cs | 65 ++++++++++++++++++++-- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 26 +++++++-- 3 files changed, 89 insertions(+), 27 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs index 6a68322..f6f458d 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 a5b54c9..e6a2304 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 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 TryGetStat( + 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 25e10be..9e6a401 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -69,9 +69,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP 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"); -- cgit v1.1 From 8004e6f31cb03abc9b6170622099879ccaf5570b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 29 Jul 2013 23:38:54 +0100 Subject: 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(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 9e6a401..bf50868 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() -- cgit v1.1 From 1416c909326d89566cbe785b6dacac228e31a5a0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 29 Jul 2013 23:53:59 +0100 Subject: 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. --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index bf50868..85fe1a4 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(); } -- cgit v1.1 From 5a7784a0e6c3f549d0e7b59380ad05729cb93a4f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 24 Jul 2013 10:52:54 -0700 Subject: BulletSim: make density display and return value consistant with how the simulator expects it (scaled to 100kg/m^3). --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 13 +++++++------ OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | 15 ++++++++++++++- 3 files changed, 22 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 59e7f5f..58a417e 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 0bdb5f1..4520171 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 d34b797..0704591 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); -- cgit v1.1 From 6ad577d32bcb7520a33e4c0c7510d81a7cad674c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 30 Jul 2013 15:22:32 -0700 Subject: BulletSim: test method for debugging of extended physics script operations. --- .../Scripting/ExtendedPhysics/ExtendedPhysics.cs | 54 ++++++++++++++++++---- 1 file changed, 46 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs index 6009dc5..0cbc5f9 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); + } } } } -- cgit v1.1 From 0d189165a83bb97f243a1f29cfa6896936ca6db0 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 30 Jul 2013 15:23:33 -0700 Subject: 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. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 75 +++++++++++----------- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 18 +++++- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 11 +++- 3 files changed, 61 insertions(+), 43 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 82d7c44..f0d17d3 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 960c0b4..7f94666 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 33ae5a5..6359046 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) -- cgit v1.1 From 2b5419927143667048bddf0a501e42c093a71147 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 30 Jul 2013 17:26:56 -0700 Subject: 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 --- .../ClientStack/Linden/Caps/SimulatorFeaturesModule.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index 7d9f935..4bd17b1 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; + } } -- cgit v1.1 From fd050fca7caef83d72d00241d0c0db5c1ec5d1ff Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 30 Jul 2013 21:10:00 -0700 Subject: 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(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index 4bd17b1..e4d8a20 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 c4255b9..4a5a352 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 -- cgit v1.1 From e4ecbc2b104959eced649e1620108afca22346dc Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 30 Jul 2013 21:38:41 -0700 Subject: Fix null ref. --- OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index 4a5a352..a7dd44e 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("/")) -- cgit v1.1 From 3c540f0d33894060d53616aa0aa67bc9d8ab82ec Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 30 Jul 2013 22:07:33 -0700 Subject: Avoid another null ref opportunity. --- OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index a7dd44e..a2aee08 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")) -- cgit v1.1 From 87fcff9fc39f180ceb7d5511ca8bc23965fab17f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 31 Jul 2013 11:13:55 -0700 Subject: HGWorldMapModule: check whether it's enabled or not. --- OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index a2aee08..cb22f0b 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(); -- cgit v1.1 From ac2ad9690d9e8b8988dc68cf4e2933c7b18a71bc Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 31 Jul 2013 11:20:27 -0700 Subject: HGWorldMapModule: unregister event on RemoveRegion --- OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index cb22f0b..97227b3 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"; } -- cgit v1.1 From 64f2dc778ad7a080ba89a1077da538c011c7c934 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 31 Jul 2013 11:27:35 -0700 Subject: 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 | 507 ++++++++++++++------- .../SimianAuthenticationServiceConnector.cs | 12 +- .../SimianGrid/SimianAvatarServiceConnector.cs | 8 +- .../SimianGrid/SimianFriendsServiceConnector.cs | 8 +- .../Services/Connectors/SimianGrid/SimianGrid.cs | 114 +++++ .../SimianGrid/SimianGridMaptileModule.cs | 131 +++--- .../SimianGrid/SimianGridServiceConnector.cs | 18 +- .../SimianGrid/SimianInventoryServiceConnector.cs | 30 +- .../SimianGrid/SimianPresenceServiceConnector.cs | 18 +- .../Connectors/SimianGrid/SimianProfiles.cs | 6 +- .../SimianUserAccountServiceConnector.cs | 8 +- 11 files changed, 578 insertions(+), 282 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs index 74b980c..6f8d9ed 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"; + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "xRemoveAsset" }, + { "AssetID", id } + }; - using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) + OSDMap response = SimianGrid.PostToService(m_serverUrl,requestArgs); + if (! response["Success"].AsBoolean()) { - if (response.StatusCode != HttpStatusCode.NoContent) - { - m_log.Warn("[SIMIAN ASSET CONNECTOR]: Unexpected response when deleting asset " + url + ": " + - response.StatusCode + " (" + response.StatusDescription + ")"); - } + 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); } - } - #endregion IAssetService + return false; + } - 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; + try + { + NameValueCollection requestArgs = new NameValueCollection + { + { "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; + } - // 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); + // 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; + } - try + /// + /// Invokes the xGetAsset operation on the simian server to get data associated with an asset + /// + /// + /// + private AssetBase SimianGetOperation(string id) + { + try { - HttpWebRequest request = UntrustedHttpWebRequest.Create(url); + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "xGetAsset" }, + { "ID", id } + }; - using (WebResponse response = request.GetResponse()) + OSDMap response = SimianGrid.PostToService(m_serverUrl,requestArgs); + if (! response["Success"].AsBoolean()) { - 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(); - } - } + m_log.WarnFormat("[SIMIAN ASSET CONNECTOR] Failed to get asset; {0}",response["Message"].AsString()); + return null; } + + AssetBase asset = new AssetBase(); - // Cache store - if (m_cache != null && asset != null) - m_cache.Cache(asset); + 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 6603f6e..3bd11d9 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 841bfa0..a397740 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 7422d94..9a8164c 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 847319c..a4dd36c 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 93fdae3..b999509 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() + NameValueCollection requestArgs = new NameValueCollection + { + { "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()) { - 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) - }; + m_log.WarnFormat("[SIMIAN MAPTILE] failed to store map tile; {0}",response["Message"].AsString()); + return; + } - string errorMessage = null; - int tickstart = Util.EnvironmentTickCount(); + // 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) + // }; - // Make the remote storage request - try - { - HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl); - request.Timeout = 20000; - request.ReadWriteTimeout = 5000; + // string errorMessage = null; + // int tickstart = Util.EnvironmentTickCount(); - 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; + // // Make the remote storage request + // try + // { + // HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl); + // request.Timeout = 20000; + // request.ReadWriteTimeout = 5000; - 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); - } + // 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); - 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 038a4bf..bcc1e4a 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 36325ce..97eaabe 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 01163aa..211b775 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 bd8069f..684a0db 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 6e32b3a..7e36c69 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; -- cgit v1.1 From 12995924052a1804f01dceb80803447fccc1d9fe Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 31 Jul 2013 15:37:15 -0700 Subject: 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. --- .../ClientStack/Linden/Caps/GetTextureModule.cs | 6 +- .../Framework/Interfaces/IExternalCapsModule.cs | 48 ++++++ .../SimianGrid/SimianExternalCapsModule.cs | 179 +++++++++++++++++++++ 3 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 OpenSim/Region/Framework/Interfaces/IExternalCapsModule.cs create mode 100644 OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index 13415f8..54cf285 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 0000000..a730cfd --- /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 0000000..8226705 --- /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 -- cgit v1.1