From 1c79e8a779a94317670e90e99215311fe90caa9a Mon Sep 17 00:00:00 2001 From: teravus Date: Mon, 14 Jan 2013 19:37:44 -0500 Subject: [PATCH 01/26] * Document the additional Visual Params of newer browsers in AvatarAppearance.VPElement so it can be easily looked up in code/module --- OpenSim/Framework/AvatarAppearance.cs | 53 ++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index ffc3527035..041fb94ff1 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs @@ -1558,7 +1558,58 @@ namespace OpenSim.Framework SHAPE_EYELID_INNER_CORNER_UP = 214, SKIRT_SKIRT_RED = 215, SKIRT_SKIRT_GREEN = 216, - SKIRT_SKIRT_BLUE = 217 + SKIRT_SKIRT_BLUE = 217, + + /// + /// Avatar Physics section. These are 0 type visual params which get transmitted. + /// + + /// + /// Breast Part 1 + /// + BREAST_PHYSICS_MASS = 218, + BREAST_PHYSICS_GRAVITY = 219, + BREAST_PHYSICS_DRAG = 220, + BREAST_PHYSICS_UPDOWN_MAX_EFFECT = 221, + BREAST_PHYSICS_UPDOWN_SPRING = 222, + BREAST_PHYSICS_UPDOWN_GAIN = 223, + BREAST_PHYSICS_UPDOWN_DAMPING = 224, + BREAST_PHYSICS_INOUT_MAX_EFFECT = 225, + BREAST_PHYSICS_INOUT_SPRING = 226, + BREAST_PHYSICS_INOUT_GAIN = 227, + BREAST_PHYSICS_INOUT_DAMPING = 228, + /// + /// Belly + /// + BELLY_PHYISCS_MASS = 229, + BELLY_PHYSICS_GRAVITY = 230, + BELLY_PHYSICS_DRAG = 231, + BELLY_PHYISCS_UPDOWN_MAX_EFFECT = 232, + BELLY_PHYSICS_UPDOWN_SPRING = 233, + BELLY_PHYSICS_UPDOWN_GAIN = 234, + BELLY_PHYSICS_UPDOWN_DAMPING = 235, + + /// + /// Butt + /// + BUTT_PHYSICS_MASS = 236, + BUTT_PHYSICS_GRAVITY = 237, + BUTT_PHYSICS_DRAG = 238, + BUTT_PHYSICS_UPDOWN_MAX_EFFECT = 239, + BUTT_PHYSICS_UPDOWN_SPRING = 240, + BUTT_PHYSICS_UPDOWN_GAIN = 241, + BUTT_PHYSICS_UPDOWN_DAMPING = 242, + BUTT_PHYSICS_LEFTRIGHT_MAX_EFFECT = 243, + BUTT_PHYSICS_LEFTRIGHT_SPRING = 244, + BUTT_PHYSICS_LEFTRIGHT_GAIN = 245, + BUTT_PHYSICS_LEFTRIGHT_DAMPING = 246, + /// + /// Breast Part 2 + /// + BREAST_PHYSICS_LEFTRIGHT_MAX_EFFECT = 247, + BREAST_PHYSICS_LEFTRIGHT_SPRING= 248, + BREAST_PHYSICS_LEFTRIGHT_GAIN = 249, + BREAST_PHYSICS_LEFTRIGHT_DAMPING = 250 } #endregion } From 582cb89beb597247ceb6d82cdfc8fc983ffe8496 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 16 Jan 2013 19:29:27 +0100 Subject: [PATCH 02/26] Add a way to put things at the front of the queue for any throttle group. Adds a DoubleLocklessQueue and uses it for the outgoing buckets. Added a flag value to the Throttle Type (again) because although it's hacky, it's the best of a bad bunch to get the message through the UDP stack to where it's needed. --- OpenSim/Framework/LocklessQueue.cs | 8 +-- OpenSim/Framework/ThrottleOutPacketType.cs | 2 + .../ClientStack/Linden/UDP/LLClientView.cs | 8 +-- .../ClientStack/Linden/UDP/LLUDPClient.cs | 54 +++++++++++++++---- .../ClientStack/Linden/UDP/LLUDPServer.cs | 10 +++- 5 files changed, 63 insertions(+), 19 deletions(-) diff --git a/OpenSim/Framework/LocklessQueue.cs b/OpenSim/Framework/LocklessQueue.cs index 84f887cc4d..9bd9baf321 100644 --- a/OpenSim/Framework/LocklessQueue.cs +++ b/OpenSim/Framework/LocklessQueue.cs @@ -29,7 +29,7 @@ using System.Threading; namespace OpenSim.Framework { - public sealed class LocklessQueue + public class LocklessQueue { private sealed class SingleLinkNode { @@ -41,7 +41,7 @@ namespace OpenSim.Framework SingleLinkNode tail; int count; - public int Count { get { return count; } } + public virtual int Count { get { return count; } } public LocklessQueue() { @@ -76,7 +76,7 @@ namespace OpenSim.Framework Interlocked.Increment(ref count); } - public bool Dequeue(out T item) + public virtual bool Dequeue(out T item) { item = default(T); SingleLinkNode oldHead = null; @@ -136,4 +136,4 @@ namespace OpenSim.Framework (object)Interlocked.CompareExchange(ref location, newValue, comparand); } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/ThrottleOutPacketType.cs b/OpenSim/Framework/ThrottleOutPacketType.cs index ca4b126c97..87899f0870 100644 --- a/OpenSim/Framework/ThrottleOutPacketType.cs +++ b/OpenSim/Framework/ThrottleOutPacketType.cs @@ -47,6 +47,8 @@ namespace OpenSim.Framework Texture = 5, /// Non-texture assets Asset = 6, + + HighPriority = 128, } [Flags] diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 956c2c9377..9550b5ab8d 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -2788,7 +2788,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Transfer.TransferInfo.Size = req.AssetInf.Data.Length; Transfer.TransferInfo.TransferID = req.TransferRequestID; Transfer.Header.Zerocoded = true; - OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task : ThrottleOutPacketType.Asset); + OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset); if (req.NumPackets == 1) { @@ -2799,7 +2799,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP TransferPacket.TransferData.Data = req.AssetInf.Data; TransferPacket.TransferData.Status = 1; TransferPacket.Header.Zerocoded = true; - OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task : ThrottleOutPacketType.Asset); + OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset); } else { @@ -2832,7 +2832,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP TransferPacket.TransferData.Status = 1; } TransferPacket.Header.Zerocoded = true; - OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task : ThrottleOutPacketType.Asset); + OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset); processedLength += chunkSize; packetNumber++; @@ -3605,7 +3605,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - OutPacket(aw, ThrottleOutPacketType.Task); + OutPacket(aw, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); } public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index f1a181209a..e52ac37466 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs @@ -92,7 +92,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Packets we have sent that need to be ACKed by the client public readonly UnackedPacketCollection NeedAcks = new UnackedPacketCollection(); /// ACKs that are queued up, waiting to be sent to the client - public readonly OpenSim.Framework.LocklessQueue PendingAcks = new OpenSim.Framework.LocklessQueue(); + public readonly DoubleLocklessQueue PendingAcks = new DoubleLocklessQueue(); /// Current packet sequence number public int CurrentSequence; @@ -146,7 +146,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Throttle buckets for each packet category private readonly TokenBucket[] m_throttleCategories; /// Outgoing queues for throttled packets - private readonly OpenSim.Framework.LocklessQueue[] m_packetOutboxes = new OpenSim.Framework.LocklessQueue[THROTTLE_CATEGORY_COUNT]; + private readonly DoubleLocklessQueue[] m_packetOutboxes = new DoubleLocklessQueue[THROTTLE_CATEGORY_COUNT]; /// A container that can hold one packet for each outbox, used to store /// dequeued packets that are being held for throttling private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT]; @@ -202,7 +202,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ThrottleOutPacketType type = (ThrottleOutPacketType)i; // Initialize the packet outboxes, where packets sit while they are waiting for tokens - m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue(); + m_packetOutboxes[i] = new DoubleLocklessQueue(); // Initialize the token buckets that control the throttling for each category m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type)); } @@ -429,16 +429,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// false if the packet has not been queued and should be sent immediately. /// public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue) + { + return EnqueueOutgoing(packet, forceQueue, false); + } + + public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue, bool highPriority) { int category = (int)packet.Category; if (category >= 0 && category < m_packetOutboxes.Length) { - OpenSim.Framework.LocklessQueue queue = m_packetOutboxes[category]; + DoubleLocklessQueue queue = m_packetOutboxes[category]; if (m_deliverPackets == false) { - queue.Enqueue(packet); + queue.Enqueue(packet, highPriority); return true; } @@ -449,7 +454,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // queued packets if (queue.Count > 0) { - queue.Enqueue(packet); + queue.Enqueue(packet, highPriority); return true; } @@ -462,7 +467,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP else { // Force queue specified or not enough tokens in the bucket, queue this packet - queue.Enqueue(packet); + queue.Enqueue(packet, highPriority); return true; } } @@ -494,7 +499,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (m_deliverPackets == false) return false; OutgoingPacket packet = null; - OpenSim.Framework.LocklessQueue queue; + DoubleLocklessQueue queue; TokenBucket bucket; bool packetSent = false; ThrottleOutPacketTypeFlags emptyCategories = 0; @@ -534,7 +539,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } catch { - m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue(); + m_packetOutboxes[i] = new DoubleLocklessQueue(); } if (success) { @@ -567,7 +572,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { - m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue(); + m_packetOutboxes[i] = new DoubleLocklessQueue(); emptyCategories |= CategoryToFlag(i); } } @@ -724,4 +729,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } } + + public class DoubleLocklessQueue : OpenSim.Framework.LocklessQueue + { + OpenSim.Framework.LocklessQueue highQueue = new OpenSim.Framework.LocklessQueue(); + + public override int Count + { + get + { + return base.Count + highQueue.Count; + } + } + + public override bool Dequeue(out T item) + { + if (highQueue.Dequeue(out item)) + return true; + + return base.Dequeue(out item); + } + + public void Enqueue(T item, bool highPriority) + { + if (highPriority) + highQueue.Enqueue(item); + else + Enqueue(item); + } + } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 9a4abd4877..6c72edca08 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -803,6 +803,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Queue or Send + bool highPriority = false; + + if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0) + { + category = (ThrottleOutPacketType)((int)category & 127); + highPriority = true; + } + OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); // If we were not provided a method for handling unacked, use the UDPServer default method outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); @@ -811,7 +819,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // continue to display the deleted object until relog. Therefore, we need to always queue a kill object // packet so that it isn't sent before a queued update packet. bool requestQueue = type == PacketType.KillObject; - if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) + if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority)) SendPacketFinal(outgoingPacket); #endregion Queue or Send From 3e0e9a096287512f1e53b4f54c5e916958774d8e Mon Sep 17 00:00:00 2001 From: teravus Date: Wed, 16 Jan 2013 17:59:13 -0500 Subject: [PATCH 03/26] * Enables loading cached bakes on teleport by filling in the appropriate avatar fields from the bake data. No more auto rebaking on teleport assuming your wearables, bakes and cache are consistent. * Speeds up appearance sending.. since there's nothing to wait for. --- .../AvatarFactory/AvatarFactoryModule.cs | 73 ++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 27cf20473a..7ec28605c1 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -373,6 +373,52 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { bool defonly = true; // are we only using default textures IImprovedAssetCache cache = m_scene.RequestModuleInterface(); + IBakedTextureModule bakedModule = m_scene.RequestModuleInterface(); + WearableCacheItem[] wearableCache = null; + + // Cache wearable data for teleport. + // Only makes sense if there's a bake module and a cache module + if (bakedModule != null && cache != null) + { + try + { + wearableCache = bakedModule.Get(sp.UUID); + } + catch (Exception) + { + + } + if (wearableCache != null) + { + for (int i = 0; i < wearableCache.Length; i++) + { + cache.Cache(wearableCache[i].TextureAsset); + } + } + } + /* + IBakedTextureModule bakedModule = m_scene.RequestModuleInterface(); + if (invService.GetRootFolder(userID) != null) + { + WearableCacheItem[] wearableCache = null; + if (bakedModule != null) + { + try + { + wearableCache = bakedModule.Get(userID); + appearance.WearableCacheItems = wearableCache; + appearance.WearableCacheItemsDirty = false; + foreach (WearableCacheItem item in wearableCache) + { + appearance.Texture.FaceTextures[item.TextureIndex].TextureID = item.TextureID; + } + } + catch (Exception) + { + + } + } + */ // Process the texture entry for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) @@ -380,9 +426,32 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory int idx = AvatarAppearance.BAKE_INDICES[i]; Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; - // if there is no texture entry, skip it + // No face, so lets check our baked service cache, teleport or login. if (face == null) - continue; + { + if (wearableCache != null) + { + // If we find the an appearance item, set it as the textureentry and the face + WearableCacheItem searchitem = WearableCacheItem.SearchTextureIndex((uint) idx, wearableCache); + if (searchitem != null) + { + sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint) idx); + sp.Appearance.Texture.FaceTextures[idx].TextureID = searchitem.TextureID; + face = sp.Appearance.Texture.FaceTextures[idx]; + } + else + { + // if there is no texture entry and no baked cache, skip it + continue; + } + } + else + { + //No texture entry face and no cache. Skip this face. + continue; + } + } + // m_log.DebugFormat( // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", From 13232718262920101ee50cfbe87192096c5c3805 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 19 Jan 2013 13:21:43 +0100 Subject: [PATCH 04/26] Kill the dumb Opensimulator Testing group again - for good. --- .../Region/CoreModules/Avatar/Groups/GroupsModule.cs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs index af54c1a1de..d2ef6b19e8 100644 --- a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs @@ -73,17 +73,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups } else { - m_Enabled = groupsConfig.GetBoolean("Enabled", false); - if (!m_Enabled) + if (groupsConfig.GetBoolean("Enabled", false)) { - m_log.Info("[GROUPS]: Groups disabled in configuration"); - return; + if (groupsConfig.GetString("Module", "Default") == "Default") + m_Enabled = true; } - - if (groupsConfig.GetString("Module", "Default") != "Default") - return; } - } public void AddRegion(Scene scene) From bd77e2b7bac54112040706eb26f2d787f668d8a9 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 19 Jan 2013 14:29:09 +0100 Subject: [PATCH 05/26] Remove the core groups module --- .../CoreModules/Avatar/Groups/GroupsModule.cs | 252 ------------------ 1 file changed, 252 deletions(-) delete mode 100644 OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs diff --git a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs deleted file mode 100644 index d2ef6b19e8..0000000000 --- a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs +++ /dev/null @@ -1,252 +0,0 @@ -/* - * 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.Generic; -using System.Reflection; -using log4net; -using Nini.Config; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; - -using Mono.Addins; - -namespace OpenSim.Region.CoreModules.Avatar.Groups -{ - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsModule")] - public class GroupsModule : ISharedRegionModule - { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private Dictionary m_GroupMap = - new Dictionary(); - - private Dictionary m_ClientMap = - new Dictionary(); - - private UUID opensimulatorGroupID = - new UUID("00000000-68f9-1111-024e-222222111123"); - - private List m_SceneList = new List(); - - private static GroupMembershipData osGroup = - new GroupMembershipData(); - - private bool m_Enabled = false; - - #region ISharedRegionModule Members - - public void Initialise(IConfigSource config) - { - IConfig groupsConfig = config.Configs["Groups"]; - - if (groupsConfig == null) - { - m_log.Info("[GROUPS]: No configuration found. Using defaults"); - } - else - { - if (groupsConfig.GetBoolean("Enabled", false)) - { - if (groupsConfig.GetString("Module", "Default") == "Default") - m_Enabled = true; - } - } - } - - public void AddRegion(Scene scene) - { - if (!m_Enabled) - return; - - lock (m_SceneList) - { - if (!m_SceneList.Contains(scene)) - { - if (m_SceneList.Count == 0) - { - osGroup.GroupID = opensimulatorGroupID; - osGroup.GroupName = "OpenSimulator Testing"; - osGroup.GroupPowers = - (uint)(GroupPowers.AllowLandmark | - GroupPowers.AllowSetHome); - m_GroupMap[opensimulatorGroupID] = osGroup; - } - m_SceneList.Add(scene); - } - } - - scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnClientClosed += OnClientClosed; - // scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - } - - public void RemoveRegion(Scene scene) - { - if (!m_Enabled) - return; - - lock (m_SceneList) - { - if (m_SceneList.Contains(scene)) - m_SceneList.Remove(scene); - } - - scene.EventManager.OnNewClient -= OnNewClient; - scene.EventManager.OnClientClosed -= OnClientClosed; - } - - public void RegionLoaded(Scene scene) - { - } - - public void PostInitialise() - { - } - - public void Close() - { - if (!m_Enabled) - return; - -// m_log.Debug("[GROUPS]: Shutting down group module."); - - lock (m_ClientMap) - { - m_ClientMap.Clear(); - } - - lock (m_GroupMap) - { - m_GroupMap.Clear(); - } - } - - public string Name - { - get { return "GroupsModule"; } - } - - public Type ReplaceableInterface - { - get { return null; } - } - - #endregion - - private void OnNewClient(IClientAPI client) - { - // Subscribe to instant messages -// client.OnInstantMessage += OnInstantMessage; - client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; - client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; - lock (m_ClientMap) - { - if (!m_ClientMap.ContainsKey(client.AgentId)) - { - m_ClientMap.Add(client.AgentId, client); - } - } - - GroupMembershipData[] updateGroups = new GroupMembershipData[1]; - updateGroups[0] = osGroup; - - client.SendGroupMembership(updateGroups); - } - - private void OnAgentDataUpdateRequest(IClientAPI remoteClient, - UUID AgentID, UUID SessionID) - { - UUID ActiveGroupID; - string ActiveGroupName; - ulong ActiveGroupPowers; - - string firstname = remoteClient.FirstName; - string lastname = remoteClient.LastName; - - string ActiveGroupTitle = "I IZ N0T"; - - ActiveGroupID = osGroup.GroupID; - ActiveGroupName = osGroup.GroupName; - ActiveGroupPowers = osGroup.GroupPowers; - - remoteClient.SendAgentDataUpdate(AgentID, ActiveGroupID, firstname, - lastname, ActiveGroupPowers, ActiveGroupName, - ActiveGroupTitle); - } - -// private void OnInstantMessage(IClientAPI client, GridInstantMessage im) -// { -// } - -// private void OnGridInstantMessage(GridInstantMessage msg) -// { -// // Trigger the above event handler -// OnInstantMessage(null, msg); -// } - - private void HandleUUIDGroupNameRequest(UUID id,IClientAPI remote_client) - { - string groupnamereply = "Unknown"; - UUID groupUUID = UUID.Zero; - - lock (m_GroupMap) - { - if (m_GroupMap.ContainsKey(id)) - { - GroupMembershipData grp = m_GroupMap[id]; - groupnamereply = grp.GroupName; - groupUUID = grp.GroupID; - } - } - remote_client.SendGroupNameReply(groupUUID, groupnamereply); - } - - private void OnClientClosed(UUID agentID, Scene scene) - { - lock (m_ClientMap) - { - if (m_ClientMap.ContainsKey(agentID)) - { -// IClientAPI cli = m_ClientMap[agentID]; -// if (cli != null) -// { -// //m_log.Info("[GROUPS]: Removing all reference to groups for " + cli.Name); -// } -// else -// { -// //m_log.Info("[GROUPS]: Removing all reference to groups for " + agentID.ToString()); -// } - m_ClientMap.Remove(agentID); - } - } - } - } -} From 7bd9a0edb75ede38e71ca0f436bf89835b13d9ad Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 19 Jan 2013 14:30:38 +0100 Subject: [PATCH 06/26] Remove group IM test code also mentioning "OpenSimulator Testing" --- .../ClientStack/Linden/UDP/LLClientView.cs | 27 +------------------ 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 9550b5ab8d..fd82db703b 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -897,32 +897,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP msg.MessageBlock.Message = Util.StringToBytes1024(im.message); msg.MessageBlock.BinaryBucket = im.binaryBucket; - if (im.message.StartsWith("[grouptest]")) - { // this block is test code for implementing group IM - delete when group IM is finished - IEventQueue eq = Scene.RequestModuleInterface(); - if (eq != null) - { - im.dialog = 17; - - //eq.ChatterboxInvitation( - // new UUID("00000000-68f9-1111-024e-222222111123"), - // "OpenSimulator Testing", im.fromAgentID, im.message, im.toAgentID, im.fromAgentName, im.dialog, 0, - // false, 0, new Vector3(), 1, im.imSessionID, im.fromGroup, im.binaryBucket); - - eq.ChatterboxInvitation( - new UUID("00000000-68f9-1111-024e-222222111123"), - "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0, - false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Util.StringToBytes256("OpenSimulator Testing")); - - eq.ChatterBoxSessionAgentListUpdates( - new UUID("00000000-68f9-1111-024e-222222111123"), - new UUID(im.fromAgentID), new UUID(im.toAgentID), false, false, false); - } - - Console.WriteLine("SendInstantMessage: " + msg); - } - else - OutPacket(msg, ThrottleOutPacketType.Task); + OutPacket(msg, ThrottleOutPacketType.Task); } } From 903cc71f0d6b0caaf8dfa176dabaeac21e77490d Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 19 Jan 2013 22:53:51 +0100 Subject: [PATCH 07/26] Remove an extra ScriptSleep (merge artefact) from llSetLinkPrimitiveParamsFast --- .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 617f382242..fcb68b2896 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7782,8 +7782,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); - - ScriptSleep(200); } private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) From 461ecd7cf9edebce45ab715901a7f3b02c216e7b Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 20 Jan 2013 02:08:38 +0100 Subject: [PATCH 08/26] Refactor scripted http request to use async calls rather than hard threads --- .../HttpRequest/ScriptsHttpRequests.cs | 140 +++++++++++------- 1 file changed, 87 insertions(+), 53 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index a0ae2030cb..5b39794783 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -206,7 +206,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest m_pendingRequests.Add(reqID, htc); } - htc.Process(); + htc.SendRequest(); return reqID; } @@ -340,7 +340,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public string HttpMIMEType = "text/plain;charset=utf-8"; public int HttpTimeout; public bool HttpVerifyCert = true; - private Thread httpThread; // Request info private UUID _itemID; @@ -374,27 +373,11 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public void Process() { - httpThread = new Thread(SendRequest); - httpThread.Name = "HttpRequestThread"; - httpThread.Priority = ThreadPriority.BelowNormal; - httpThread.IsBackground = true; - _finished = false; - httpThread.Start(); + SendRequest(); } - /* - * TODO: More work on the response codes. Right now - * returning 200 for success or 499 for exception - */ - public void SendRequest() { - HttpWebResponse response = null; - StringBuilder sb = new StringBuilder(); - byte[] buf = new byte[8192]; - string tempString = null; - int count = 0; - try { Request = (HttpWebRequest) WebRequest.Create(Url); @@ -409,13 +392,9 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { // We could hijack Connection Group Name to identify // a desired security exception. But at the moment we'll use a dummy header instead. -// Request.ConnectionGroupName = "NoVerify"; Request.Headers.Add("NoVerifyCert", "true"); } -// else -// { -// Request.ConnectionGroupName="Verify"; -// } + if (proxyurl != null && proxyurl.Length > 0) { if (proxyexcepts != null && proxyexcepts.Length > 0) @@ -430,10 +409,14 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest } foreach (KeyValuePair entry in ResponseHeaders) + { if (entry.Key.ToLower().Equals("user-agent")) Request.UserAgent = entry.Value; else Request.Headers[entry.Key] = entry.Value; + } + + Request.Timeout = HttpTimeout; // Encode outbound data if (OutboundBody.Length > 0) @@ -441,16 +424,78 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest byte[] data = Util.UTF8.GetBytes(OutboundBody); Request.ContentLength = data.Length; - Stream bstream = Request.GetRequestStream(); - bstream.Write(data, 0, data.Length); - bstream.Close(); + Request.BeginGetRequestStream(new AsyncCallback(SendRequestData), this); + return; } - Request.Timeout = HttpTimeout; + Request.BeginGetResponse(new AsyncCallback(ProcessResponse), this); + } + catch (Exception e) + { + // Do nothing. Abort was called. + } + } + + private void SendRequestData(IAsyncResult ar) + { + try + { + byte[] data = Util.UTF8.GetBytes(OutboundBody); + + Stream bstream = Request.EndGetRequestStream(ar); + bstream.Write(data, 0, data.Length); + bstream.Close(); + + Request.BeginGetResponse(new AsyncCallback(ProcessResponse), this); + } + catch (WebException e) + { + // Abort was called. Just go away + if (e.Status == WebExceptionStatus.RequestCanceled) + return; + + // Server errored on request + if (e.Status == WebExceptionStatus.ProtocolError && e.Response != null) + { + HttpWebResponse webRsp = (HttpWebResponse)e.Response; + + Status = (int)webRsp.StatusCode; + + try + { + using (Stream responseStream = webRsp.GetResponseStream()) + { + ResponseBody = responseStream.GetStreamString(); + } + } + catch + { + ResponseBody = webRsp.StatusDescription; + } + finally + { + webRsp.Close(); + } + return; + } + + _finished = true; + } + } + + private void ProcessResponse(IAsyncResult ar) + { + HttpWebResponse response = null; + StringBuilder sb = new StringBuilder(); + byte[] buf = new byte[8192]; + string tempString = null; + int count = 0; + + try + { try { - // execute the request - response = (HttpWebResponse) Request.GetResponse(); + response = (HttpWebResponse) Request.EndGetResponse(ar); } catch (WebException e) { @@ -485,33 +530,22 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest ResponseBody = sb.ToString().Replace("\r", ""); } - catch (Exception e) + catch (WebException e) { - if (e is WebException && ((WebException)e).Status == WebExceptionStatus.ProtocolError) - { - HttpWebResponse webRsp = (HttpWebResponse)((WebException)e).Response; - Status = (int)webRsp.StatusCode; - try - { - using (Stream responseStream = webRsp.GetResponseStream()) - { - ResponseBody = responseStream.GetStreamString(); - } - } - catch - { - ResponseBody = webRsp.StatusDescription; - } - } - else - { - Status = (int)OSHttpStatusCode.ClientErrorJoker; - ResponseBody = e.Message; - } + // Abort was called. Just go away + if (e.Status == WebExceptionStatus.RequestCanceled) + return; + Status = (int)OSHttpStatusCode.ClientErrorJoker; + + ResponseBody = e.Message; _finished = true; return; } + catch (Exception e) + { + // Ignore + } finally { if (response != null) @@ -525,7 +559,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { try { - httpThread.Abort(); + Request.Abort(); } catch (Exception) { From cf4bf7432a545888e3af8f540f65092aea6f2686 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 20 Jan 2013 15:58:20 +0100 Subject: [PATCH 09/26] Revert "Refactor scripted http request to use async calls rather than hard threads" This reverts commit 461ecd7cf9edebce45ab715901a7f3b02c216e7b. --- .../HttpRequest/ScriptsHttpRequests.cs | 144 +++++++----------- 1 file changed, 55 insertions(+), 89 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index 5b39794783..a0ae2030cb 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -206,7 +206,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest m_pendingRequests.Add(reqID, htc); } - htc.SendRequest(); + htc.Process(); return reqID; } @@ -340,6 +340,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public string HttpMIMEType = "text/plain;charset=utf-8"; public int HttpTimeout; public bool HttpVerifyCert = true; + private Thread httpThread; // Request info private UUID _itemID; @@ -373,11 +374,27 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public void Process() { - SendRequest(); + httpThread = new Thread(SendRequest); + httpThread.Name = "HttpRequestThread"; + httpThread.Priority = ThreadPriority.BelowNormal; + httpThread.IsBackground = true; + _finished = false; + httpThread.Start(); } + /* + * TODO: More work on the response codes. Right now + * returning 200 for success or 499 for exception + */ + public void SendRequest() { + HttpWebResponse response = null; + StringBuilder sb = new StringBuilder(); + byte[] buf = new byte[8192]; + string tempString = null; + int count = 0; + try { Request = (HttpWebRequest) WebRequest.Create(Url); @@ -392,9 +409,13 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { // We could hijack Connection Group Name to identify // a desired security exception. But at the moment we'll use a dummy header instead. +// Request.ConnectionGroupName = "NoVerify"; Request.Headers.Add("NoVerifyCert", "true"); } - +// else +// { +// Request.ConnectionGroupName="Verify"; +// } if (proxyurl != null && proxyurl.Length > 0) { if (proxyexcepts != null && proxyexcepts.Length > 0) @@ -409,14 +430,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest } foreach (KeyValuePair entry in ResponseHeaders) - { if (entry.Key.ToLower().Equals("user-agent")) Request.UserAgent = entry.Value; else Request.Headers[entry.Key] = entry.Value; - } - - Request.Timeout = HttpTimeout; // Encode outbound data if (OutboundBody.Length > 0) @@ -424,78 +441,16 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest byte[] data = Util.UTF8.GetBytes(OutboundBody); Request.ContentLength = data.Length; - Request.BeginGetRequestStream(new AsyncCallback(SendRequestData), this); - return; + Stream bstream = Request.GetRequestStream(); + bstream.Write(data, 0, data.Length); + bstream.Close(); } - Request.BeginGetResponse(new AsyncCallback(ProcessResponse), this); - } - catch (Exception e) - { - // Do nothing. Abort was called. - } - } - - private void SendRequestData(IAsyncResult ar) - { - try - { - byte[] data = Util.UTF8.GetBytes(OutboundBody); - - Stream bstream = Request.EndGetRequestStream(ar); - bstream.Write(data, 0, data.Length); - bstream.Close(); - - Request.BeginGetResponse(new AsyncCallback(ProcessResponse), this); - } - catch (WebException e) - { - // Abort was called. Just go away - if (e.Status == WebExceptionStatus.RequestCanceled) - return; - - // Server errored on request - if (e.Status == WebExceptionStatus.ProtocolError && e.Response != null) - { - HttpWebResponse webRsp = (HttpWebResponse)e.Response; - - Status = (int)webRsp.StatusCode; - - try - { - using (Stream responseStream = webRsp.GetResponseStream()) - { - ResponseBody = responseStream.GetStreamString(); - } - } - catch - { - ResponseBody = webRsp.StatusDescription; - } - finally - { - webRsp.Close(); - } - return; - } - - _finished = true; - } - } - - private void ProcessResponse(IAsyncResult ar) - { - HttpWebResponse response = null; - StringBuilder sb = new StringBuilder(); - byte[] buf = new byte[8192]; - string tempString = null; - int count = 0; - - try - { + Request.Timeout = HttpTimeout; try { - response = (HttpWebResponse) Request.EndGetResponse(ar); + // execute the request + response = (HttpWebResponse) Request.GetResponse(); } catch (WebException e) { @@ -530,21 +485,32 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest ResponseBody = sb.ToString().Replace("\r", ""); } - catch (WebException e) - { - // Abort was called. Just go away - if (e.Status == WebExceptionStatus.RequestCanceled) - return; - - Status = (int)OSHttpStatusCode.ClientErrorJoker; - - ResponseBody = e.Message; - _finished = true; - return; - } catch (Exception e) { - // Ignore + if (e is WebException && ((WebException)e).Status == WebExceptionStatus.ProtocolError) + { + HttpWebResponse webRsp = (HttpWebResponse)((WebException)e).Response; + Status = (int)webRsp.StatusCode; + try + { + using (Stream responseStream = webRsp.GetResponseStream()) + { + ResponseBody = responseStream.GetStreamString(); + } + } + catch + { + ResponseBody = webRsp.StatusDescription; + } + } + else + { + Status = (int)OSHttpStatusCode.ClientErrorJoker; + ResponseBody = e.Message; + } + + _finished = true; + return; } finally { @@ -559,7 +525,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { try { - Request.Abort(); + httpThread.Abort(); } catch (Exception) { From b7b3063849c8d7299fa0c262e122ff1a050bfdcb Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 20 Jan 2013 18:38:00 +0100 Subject: [PATCH 10/26] Implement HTTP Request froma thread pool to avoid packet congestion --- .../HttpRequest/ScriptsHttpRequests.cs | 59 ++++++++++++++----- prebuild.xml | 1 + 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index a0ae2030cb..708b99d6ea 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -42,6 +42,7 @@ using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Mono.Addins; +using Amib.Threading; /***************************************************** * @@ -102,6 +103,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest private Dictionary m_pendingRequests; private Scene m_scene; // private Queue rpcQueue = new Queue(); + public static SmartThreadPool ThreadPool = null; public HttpRequestModule() { @@ -279,7 +281,30 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); + int maxThreads = 50; + + IConfig httpConfig = config.Configs["HttpRequestModule"]; + if (httpConfig != null) + { + maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads); + } + m_pendingRequests = new Dictionary(); + + // First instance sets this up for all sims + if (ThreadPool == null) + { + STPStartInfo startInfo = new STPStartInfo(); + startInfo.IdleTimeout = 20000; + startInfo.MaxWorkerThreads = maxThreads; + startInfo.MinWorkerThreads = 5; + startInfo.ThreadPriority = ThreadPriority.BelowNormal; + startInfo.StartSuspended = true; + + ThreadPool = new SmartThreadPool(startInfo); + + ThreadPool.Start(); + } } public void AddRegion(Scene scene) @@ -340,7 +365,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public string HttpMIMEType = "text/plain;charset=utf-8"; public int HttpTimeout; public bool HttpVerifyCert = true; - private Thread httpThread; + public IWorkItemResult WorkItem = null; // Request info private UUID _itemID; @@ -374,12 +399,16 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public void Process() { - httpThread = new Thread(SendRequest); - httpThread.Name = "HttpRequestThread"; - httpThread.Priority = ThreadPriority.BelowNormal; - httpThread.IsBackground = true; _finished = false; - httpThread.Start(); + + lock (HttpRequestModule.ThreadPool) + WorkItem = HttpRequestModule.ThreadPool.QueueWorkItem(new WorkItemCallback(StpSendWrapper), null); + } + + private object StpSendWrapper(object o) + { + SendRequest(); + return null; } /* @@ -409,13 +438,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { // We could hijack Connection Group Name to identify // a desired security exception. But at the moment we'll use a dummy header instead. -// Request.ConnectionGroupName = "NoVerify"; Request.Headers.Add("NoVerifyCert", "true"); } -// else -// { -// Request.ConnectionGroupName="Verify"; -// } if (proxyurl != null && proxyurl.Length > 0) { if (proxyexcepts != null && proxyexcepts.Length > 0) @@ -485,9 +509,9 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest ResponseBody = sb.ToString().Replace("\r", ""); } - catch (Exception e) + catch (WebException e) { - if (e is WebException && ((WebException)e).Status == WebExceptionStatus.ProtocolError) + if (e.Status == WebExceptionStatus.ProtocolError) { HttpWebResponse webRsp = (HttpWebResponse)((WebException)e).Response; Status = (int)webRsp.StatusCode; @@ -512,6 +536,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest _finished = true; return; } + catch (Exception e) + { + // Don't crash on anything else + } finally { if (response != null) @@ -525,7 +553,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { try { - httpThread.Abort(); + if (!WorkItem.Cancel()) + { + WorkItem.Abort(); + } } catch (Exception) { diff --git a/prebuild.xml b/prebuild.xml index 7fff2e04d3..fa2172268c 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1680,6 +1680,7 @@ + From 0e17887e03fb6d32cdd07838caa56e34103ae8f2 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 21 Jan 2013 01:46:40 +0100 Subject: [PATCH 11/26] Allow TeleportCancel packets to reset the transfer state machine --- .../Framework/EntityTransfer/EntityTransferModule.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 7e72d4747f..0c8a2b17ad 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -150,6 +150,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { client.OnTeleportHomeRequest += TriggerTeleportHome; client.OnTeleportLandmarkRequest += RequestTeleportLandmark; + client.OnTeleportCancel += TeleportCancel; } public virtual void Close() {} @@ -993,6 +994,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return neighbourRegion; } + private void TeleportCancel(IClientAPI remoteClient) + { + m_entityTransferStateMachine.ResetFromTransit(remoteClient.AgentId); + } + public bool Cross(ScenePresence agent, bool isFlying) { uint x; From 80529a6baca35e61e684fa3eb1a40c141101ff2c Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 21 Jan 2013 01:47:09 +0100 Subject: [PATCH 12/26] Prevent scene from holding references to SOGs with attargets beyond SOG deletion --- OpenSim/Region/Framework/Scenes/Scene.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 23006f2df6..9d07537973 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -282,7 +282,7 @@ namespace OpenSim.Region.Framework.Scenes private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing private volatile bool m_backingup; private Dictionary m_returns = new Dictionary(); - private Dictionary m_groupsWithTargets = new Dictionary(); + private Dictionary m_groupsWithTargets = new Dictionary(); private bool m_physics_enabled = true; private bool m_scripts_enabled = true; @@ -1736,7 +1736,7 @@ namespace OpenSim.Region.Framework.Scenes public void AddGroupTarget(SceneObjectGroup grp) { lock (m_groupsWithTargets) - m_groupsWithTargets[grp.UUID] = grp; + m_groupsWithTargets[grp.UUID] = 0; } public void RemoveGroupTarget(SceneObjectGroup grp) @@ -1747,18 +1747,24 @@ namespace OpenSim.Region.Framework.Scenes private void CheckAtTargets() { - List objs = null; + List objs = null; lock (m_groupsWithTargets) { if (m_groupsWithTargets.Count != 0) - objs = new List(m_groupsWithTargets.Values); + objs = new List(m_groupsWithTargets.Keys); } if (objs != null) { - foreach (SceneObjectGroup entry in objs) - entry.checkAtTargets(); + foreach (UUID entry in objs) + { + SceneObjectGroup grp = GetSceneObjectGroup(entry); + if (grp == null) + m_groupsWithTargets.Remove(entry); + else + grp.checkAtTargets(); + } } } From a291e6be93ada150e35e141dbeb37a31d580f87d Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 21 Jan 2013 01:47:54 +0100 Subject: [PATCH 13/26] Limit active at targets to 8 --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index b4749796ec..17f5a0f1dc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -320,8 +320,8 @@ namespace OpenSim.Region.Framework.Scenes protected SceneObjectPart m_rootPart; // private Dictionary m_scriptEvents = new Dictionary(); - private Dictionary m_targets = new Dictionary(); - private Dictionary m_rotTargets = new Dictionary(); + private SortedDictionary m_targets = new SortedDictionary(); + private SortedDictionary m_rotTargets = new SortedDictionary(); private bool m_scriptListens_atTarget; private bool m_scriptListens_notAtTarget; @@ -4112,6 +4112,8 @@ namespace OpenSim.Region.Framework.Scenes waypoint.handle = handle; lock (m_rotTargets) { + if (m_rotTargets.Count >= 8) + m_rotTargets.Remove(m_rotTargets.ElementAt(0).Key); m_rotTargets.Add(handle, waypoint); } m_scene.AddGroupTarget(this); @@ -4137,6 +4139,8 @@ namespace OpenSim.Region.Framework.Scenes waypoint.handle = handle; lock (m_targets) { + if (m_targets.Count >= 8) + m_targets.Remove(m_targets.ElementAt(0).Key); m_targets.Add(handle, waypoint); } m_scene.AddGroupTarget(this); From da6f589885b7acf5f85aaeb2c011792b9d41a22e Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 21 Jan 2013 08:36:21 +0100 Subject: [PATCH 14/26] Add accessors to allow serializing rot and position targets --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 17f5a0f1dc..ed1bbd8827 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -79,14 +79,14 @@ namespace OpenSim.Region.Framework.Scenes object_rez = 4194304 } - struct scriptPosTarget + public struct scriptPosTarget { public Vector3 targetPos; public float tolerance; public uint handle; } - struct scriptRotTarget + public struct scriptRotTarget { public Quaternion targetRot; public float tolerance; @@ -323,6 +323,16 @@ namespace OpenSim.Region.Framework.Scenes private SortedDictionary m_targets = new SortedDictionary(); private SortedDictionary m_rotTargets = new SortedDictionary(); + public SortedDictionary AtTargets + { + get { return m_targets; } + } + + public SortedDictionary RotTargets + { + get { return m_rotTargets; } + } + private bool m_scriptListens_atTarget; private bool m_scriptListens_notAtTarget; private bool m_scriptListens_atRotTarget; From 09a3e134e4fd9300899131f13b5be1494a767970 Mon Sep 17 00:00:00 2001 From: teravus Date: Mon, 21 Jan 2013 17:30:38 -0500 Subject: [PATCH 15/26] * Fix notecard loading - If the notecard name is formatted like a UUID but isn't an actual asset UUID, then try to load it like an asset id first, then try to load it as a task inventoryitem name. If the passed UUID is a string, try to load it like a task inventory item name. --- .../Shared/Api/Implementation/OSSL_Api.cs | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 51c8c7ed89..7c2f8edbca 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -1821,17 +1821,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { UUID assetID = UUID.Zero; - if (!UUID.TryParse(notecardNameOrUuid, out assetID)) + bool notecardNameIsUUID = UUID.TryParse(notecardNameOrUuid, out assetID); + + if (!notecardNameIsUUID) { - m_host.TaskInventory.LockItemsForRead(true); - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) - { - if (item.Type == 7 && item.Name == notecardNameOrUuid) - { - assetID = item.AssetID; - } - } - m_host.TaskInventory.LockItemsForRead(false); + assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid); } if (assetID == UUID.Zero) @@ -1842,7 +1836,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api AssetBase a = World.AssetService.Get(assetID.ToString()); if (a == null) - return UUID.Zero; + { + // Whoops, it's still possible here that the notecard name was properly + // formatted like a UUID but isn't an asset UUID so lets look it up by name after all + assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid); + if (assetID == UUID.Zero) + return UUID.Zero; + + if (!NotecardCache.IsCached(assetID)) + { + a = World.AssetService.Get(assetID.ToString()); + + if (a == null) + { + return UUID.Zero; + } + } + } string data = Encoding.UTF8.GetString(a.Data); NotecardCache.Cache(assetID, data); @@ -1850,6 +1860,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return assetID; } + protected UUID SearchTaskInventoryForAssetId(string name) + { + UUID assetId = UUID.Zero; + m_host.TaskInventory.LockItemsForRead(true); + foreach (TaskInventoryItem item in m_host.TaskInventory.Values) + { + if (item.Type == 7 && item.Name == name) + { + assetId = item.AssetID; + } + } + m_host.TaskInventory.LockItemsForRead(false); + return assetId; + } /// /// Directly get an entire notecard at once. From 89676b8a48c30647f0150c7e2b0da0ba6c932265 Mon Sep 17 00:00:00 2001 From: teravus Date: Mon, 21 Jan 2013 21:32:48 -0500 Subject: [PATCH 16/26] * The fallthrough of FetchTexture was no longer resulting in a 404 response on missing textures. It was just waiting and no event was being provided. This re-enables the 404 response. --- .../Handlers/GetTexture/GetTextureHandler.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index 6437d0b7b0..f667b8f30a 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -176,8 +176,17 @@ namespace OpenSim.Capabilities.Handlers return true; } + response = new Hashtable(); + + response["int_response_code"] = 404; + response["str_response_string"] = "not found"; + response["content_type"] = "text/plain"; + response["keepalive"] = false; + response["reusecontext"] = false; + response["int_bytes"] = 0; + //WriteTextureData(request,response,null,format); // not found -// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); + //m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); return true; } From be60c0b0105e2d6929bb331ff86dfbcc45261221 Mon Sep 17 00:00:00 2001 From: teravus Date: Mon, 21 Jan 2013 22:08:51 -0500 Subject: [PATCH 17/26] * A better way to handle the last fix (This is in case the viewer provides a list of preferred formats, though, technically, the sim would pick the first provided format the old way). This just makes it more obvious what's happening. --- .../Handlers/GetTexture/GetTextureHandler.cs | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index f667b8f30a..68686c5648 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -99,12 +99,23 @@ namespace OpenSim.Capabilities.Handlers } // OK, we have an array with preferred formats, possibly with only one entry - + bool foundtexture = false; foreach (string f in formats) { - if (FetchTexture(request, ret, textureID, f)) + foundtexture = FetchTexture(request, ret, textureID, f); + if (foundtexture) break; } + if (!foundtexture) + { + ret["int_response_code"] = 404; + ret["error_status_text"] = "not found"; + ret["str_response_string"] = "not found"; + ret["content_type"] = "text/plain"; + ret["keepalive"] = false; + ret["reusecontext"] = false; + ret["int_bytes"] = 0; + } } else { @@ -176,18 +187,13 @@ namespace OpenSim.Capabilities.Handlers return true; } - response = new Hashtable(); + //response = new Hashtable(); - response["int_response_code"] = 404; - response["str_response_string"] = "not found"; - response["content_type"] = "text/plain"; - response["keepalive"] = false; - response["reusecontext"] = false; - response["int_bytes"] = 0; + //WriteTextureData(request,response,null,format); // not found //m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); - return true; + return false; } private void WriteTextureData(Hashtable request, Hashtable response, AssetBase texture, string format) From f667428283654f4fbe34ddf4cabaa1b991098258 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 23 Jan 2013 16:11:37 +0100 Subject: [PATCH 18/26] Guard against XMLRPC module ref being null, which will happen if it's disabled --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index fcb68b2896..58c2ac547e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7322,7 +7322,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); - if (xmlrpcMod.IsEnabled()) + if (xmlrpcMod != null && xmlrpcMod.IsEnabled()) { UUID channelID = xmlrpcMod.OpenXMLRPCChannel(m_host.LocalId, m_item.ItemID, UUID.Zero); IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface(); @@ -7354,6 +7354,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); ScriptSleep(3000); + if (xmlrpcMod == null) + return ""; return (xmlrpcMod.SendRemoteData(m_host.LocalId, m_item.ItemID, channel, dest, idata, sdata)).ToString(); } @@ -7361,7 +7363,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); - xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata); + if (xmlrpcMod != null) + xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata); ScriptSleep(3000); } @@ -7369,7 +7372,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); - xmlrpcMod.CloseXMLRPCChannel((UUID)channel); + if (xmlrpcMod != null) + xmlrpcMod.CloseXMLRPCChannel((UUID)channel); ScriptSleep(1000); } From 997d53e5320e016027eb915fb67de96b501752bb Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 23 Jan 2013 18:17:49 +0100 Subject: [PATCH 19/26] EXPERIMENTAL - Comment out the check for the agent already being in transit to prevent avatars being locked into their sim on a failed teleport. May have side effects and must be revisited to fix right. --- .../EntityTransfer/EntityTransferModule.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 0c8a2b17ad..cb09047ad8 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -402,14 +402,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection // of whether the destination region completes the teleport. - if (!m_entityTransferStateMachine.SetInTransit(sp.UUID)) - { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.", - sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); - - return; - } + m_entityTransferStateMachine.SetInTransit(sp.UUID); +// if (!m_entityTransferStateMachine.SetInTransit(sp.UUID)) +// { +// m_log.DebugFormat( +// "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.", +// sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); +// +// return; +// } if (reg == null || finalDestination == null) { From 47f18caa22fe6bfc6020c80d61c92e4ab8efa86f Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 23 Jan 2013 18:58:29 +0100 Subject: [PATCH 20/26] Remove the return value from llGiveMoney (it was a LSL extension of OpenSim) and make the function async so the script thread is not held up waiting for comms to an external server. --- .../Shared/Api/Implementation/LSL_Api.cs | 54 +++++++++---------- .../Shared/Api/Interface/ILSL_Api.cs | 2 +- .../Shared/Api/Runtime/LSL_Stub.cs | 4 +- 3 files changed, 29 insertions(+), 31 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 58c2ac547e..0562c7fcb4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3017,42 +3017,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return src.ToLower(); } - public LSL_Integer llGiveMoney(string destination, int amount) + public void llGiveMoney(string destination, int amount) { - m_host.AddScriptLPS(1); - - if (m_item.PermsGranter == UUID.Zero) - return 0; - - if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) + Util.FireAndForget(x => { - LSLError("No permissions to give money"); - return 0; - } + m_host.AddScriptLPS(1); - UUID toID = new UUID(); + if (m_item.PermsGranter == UUID.Zero) + return; - if (!UUID.TryParse(destination, out toID)) - { - LSLError("Bad key in llGiveMoney"); - return 0; - } + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) + { + LSLError("No permissions to give money"); + return; + } - IMoneyModule money = World.RequestModuleInterface(); + UUID toID = new UUID(); - if (money == null) - { - NotImplemented("llGiveMoney"); - return 0; - } + if (!UUID.TryParse(destination, out toID)) + { + LSLError("Bad key in llGiveMoney"); + return; + } - bool result = money.ObjectGiveMoney( - m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero); + IMoneyModule money = World.RequestModuleInterface(); - if (result) - return 1; + if (money == null) + { + NotImplemented("llGiveMoney"); + return; + } - return 0; + money.ObjectGiveMoney( + m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero); + }); } public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) @@ -12589,7 +12587,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } bool result = money.ObjectGiveMoney( - m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero); + m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn); if (result) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 9bf6f9b62c..8eeb4d200e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -208,7 +208,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Float llGetWallclock(); void llGiveInventory(string destination, string inventory); void llGiveInventoryList(string destination, string category, LSL_List inventory); - LSL_Integer llGiveMoney(string destination, int amount); + void llGiveMoney(string destination, int amount); LSL_String llTransferLindenDollars(string destination, int amount); void llGodLikeRezObject(string inventory, LSL_Vector pos); LSL_Float llGround(LSL_Vector offset); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index 8ecc4f86aa..ef71d7b7f6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -876,9 +876,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llGiveInventoryList(destination, category, inventory); } - public LSL_Integer llGiveMoney(string destination, int amount) + public void llGiveMoney(string destination, int amount) { - return m_LSL_Functions.llGiveMoney(destination, amount); + m_LSL_Functions.llGiveMoney(destination, amount); } public LSL_String llTransferLindenDollars(string destination, int amount) From c75508ec8d236b45c65c80d479ed7c24dd3343ce Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 23 Jan 2013 20:29:05 +0100 Subject: [PATCH 21/26] Fix a type (Suports => Supports). Also put the normal terrain collision check into the physics check patch for now since physics doesn't properly return land for some reason (as tested by Nebadon) --- OpenSim/Region/Framework/Scenes/Scene.cs | 4 ++-- OpenSim/Region/Physics/Manager/PhysicsScene.cs | 2 +- OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 2 +- .../Shared/Api/Implementation/LSL_Api.cs | 16 ++++++++-------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 9d07537973..e3bc8c7b36 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2065,11 +2065,11 @@ namespace OpenSim.Region.Framework.Scenes EventManager.TriggerPrimsLoaded(this); } - public bool SuportsRayCastFiltered() + public bool SupportsRayCastFiltered() { if (PhysicsScene == null) return false; - return PhysicsScene.SuportsRaycastWorldFiltered(); + return PhysicsScene.SupportsRaycastWorldFiltered(); } public object RayCastFiltered(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index d24ab2ac73..57e2d2045a 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -350,7 +350,7 @@ namespace OpenSim.Region.Physics.Manager return null; } - public virtual bool SuportsRaycastWorldFiltered() + public virtual bool SupportsRaycastWorldFiltered() { return false; } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 51132104ad..510cbe90af 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -2643,7 +2643,7 @@ namespace OpenSim.Region.Physics.OdePlugin } } - public override bool SuportsRaycastWorldFiltered() + public override bool SupportsRaycastWorldFiltered() { return true; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 0562c7fcb4..703c54d2db 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -12209,7 +12209,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); - if (World.SuportsRayCastFiltered()) + if (World.SupportsRayCastFiltered()) { if (dist == 0) return list; @@ -12272,13 +12272,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { - if (checkTerrain) - { - ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); - if (groundContact != null) - results.Add((ContactResult)groundContact); - } - if (checkAgents) { ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); @@ -12294,6 +12287,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + if (checkTerrain) + { + ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); + if (groundContact != null) + results.Add((ContactResult)groundContact); + } + results.Sort(delegate(ContactResult a, ContactResult b) { return a.Depth.CompareTo(b.Depth); From dd6ddcc7a53565cc540def336c5b4bd2307a1d63 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 23 Jan 2013 20:58:47 +0100 Subject: [PATCH 22/26] Prevent double ground collisions and prefer the physics result if there is one. ODE is known to not see the ground sometimes on raycast so the double test is needed. --- .../Shared/Api/Implementation/LSL_Api.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 703c54d2db..a8763ea992 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -12287,11 +12287,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + // Double check this if (checkTerrain) { - ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); - if (groundContact != null) - results.Add((ContactResult)groundContact); + bool skipGroundCheck = false; + + foreach (ContactResult c in results) + { + if (c.ConsumerID == 0) // Physics gave us a ground collision + skipGroundCheck = true; + } + + if (!skipGroundCheck) + { + ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); + if (groundContact != null) + results.Add((ContactResult)groundContact); + } } results.Sort(delegate(ContactResult a, ContactResult b) From 8c6984eac140ed48f10ac3f3db533d0c9b1d084a Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 23 Jan 2013 23:12:48 +0100 Subject: [PATCH 23/26] Implement get version RemoteAdmin call --- .../RemoteController/RemoteAdminPlugin.cs | 16 ++++++++++++++++ OpenSim/Framework/Servers/ServerBase.cs | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 9f3844bf38..49fc5663a5 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -70,6 +70,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController private string m_name = "RemoteAdminPlugin"; private string m_version = "0.0"; + private string m_openSimVersion; public string Version { @@ -89,6 +90,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController public void Initialise(OpenSimBase openSim) { + m_openSimVersion = openSim.GetVersionText(); + m_configSource = openSim.ConfigSource.Source; try { @@ -159,6 +162,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController // Misc availableMethods["admin_refresh_search"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshSearch); + availableMethods["admin_get_opensim_version"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetOpenSimVersion); // Either enable full remote functionality or just selected features string enabledMethods = m_config.GetString("enabled_methods", "all"); @@ -1977,6 +1981,18 @@ namespace OpenSim.ApplicationPlugins.RemoteController m_log.Info("[RADMIN]: Refresh Search Request complete"); } + private void XmlRpcGetOpenSimVersion(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: Received Get OpenSim Version Request"); + + Hashtable responseData = (Hashtable)response.Value; + + responseData["version"] = m_openSimVersion; + responseData["success"] = true; + + m_log.Info("[RADMIN]: Get OpenSim Version Request complete"); + } + /// /// Parse a float with the given parameter name from a request data hash table. /// diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs index c182a3abca..9eb2281914 100644 --- a/OpenSim/Framework/Servers/ServerBase.cs +++ b/OpenSim/Framework/Servers/ServerBase.cs @@ -531,7 +531,7 @@ namespace OpenSim.Framework.Servers } } - protected string GetVersionText() + public string GetVersionText() { return String.Format("Version: {0} (interface version {1})", m_version, VersionInfo.MajorInterfaceVersion); } @@ -563,4 +563,4 @@ namespace OpenSim.Framework.Servers m_console.OutputFormat(format, components); } } -} \ No newline at end of file +} From 9d2e832b85e35edea8bd177df9de4eb3ee18b004 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 24 Jan 2013 18:23:10 +0100 Subject: [PATCH 24/26] Null check the response body to make sure we're not crashing the script engine --- .../Scripting/HttpRequest/ScriptsHttpRequests.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index 708b99d6ea..0276267be8 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -533,6 +533,9 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest ResponseBody = e.Message; } + if (ResponseBody == null) + ResponseBody = String.Empty; + _finished = true; return; } @@ -546,6 +549,9 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest response.Close(); } + if (ResponseBody == null) + ResponseBody = String.Empty; + _finished = true; } From e785242c49dc5ff9fb64e26086d554a127415dde Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 24 Jan 2013 18:23:39 +0100 Subject: [PATCH 25/26] Reintroduce the return value of llGiveMoney. The grid will crash and burn without it. --- .../Shared/Api/Implementation/LSL_Api.cs | 18 +++++++++--------- .../Shared/Api/Interface/ILSL_Api.cs | 2 +- .../Shared/Api/Runtime/LSL_Stub.cs | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a8763ea992..4709c0bc3a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3017,19 +3017,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return src.ToLower(); } - public void llGiveMoney(string destination, int amount) + public LSL_Integer llGiveMoney(string destination, int amount) { - Util.FireAndForget(x => - { +// Util.FireAndForget(x => +// { m_host.AddScriptLPS(1); if (m_item.PermsGranter == UUID.Zero) - return; + return 0; if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) { LSLError("No permissions to give money"); - return; + return 0; } UUID toID = new UUID(); @@ -3037,7 +3037,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(destination, out toID)) { LSLError("Bad key in llGiveMoney"); - return; + return 0; } IMoneyModule money = World.RequestModuleInterface(); @@ -3045,12 +3045,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (money == null) { NotImplemented("llGiveMoney"); - return; + return 0; } - money.ObjectGiveMoney( + return money.ObjectGiveMoney( m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero); - }); +// }); } public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 8eeb4d200e..9bf6f9b62c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -208,7 +208,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Float llGetWallclock(); void llGiveInventory(string destination, string inventory); void llGiveInventoryList(string destination, string category, LSL_List inventory); - void llGiveMoney(string destination, int amount); + LSL_Integer llGiveMoney(string destination, int amount); LSL_String llTransferLindenDollars(string destination, int amount); void llGodLikeRezObject(string inventory, LSL_Vector pos); LSL_Float llGround(LSL_Vector offset); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index ef71d7b7f6..8ecc4f86aa 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -876,9 +876,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llGiveInventoryList(destination, category, inventory); } - public void llGiveMoney(string destination, int amount) + public LSL_Integer llGiveMoney(string destination, int amount) { - m_LSL_Functions.llGiveMoney(destination, amount); + return m_LSL_Functions.llGiveMoney(destination, amount); } public LSL_String llTransferLindenDollars(string destination, int amount) From 789e9901ddadf8c10a6296225a3fa50197ea43f0 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 24 Jan 2013 21:32:25 +0100 Subject: [PATCH 26/26] Make llGiveMoney async again. The return value is now the constant 1 to make scripts work properly. Scripts will no longer receive a failure indication through this return value; --- .../Shared/Api/Implementation/LSL_Api.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 4709c0bc3a..53c6e5cf20 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3019,17 +3019,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llGiveMoney(string destination, int amount) { -// Util.FireAndForget(x => -// { + Util.FireAndForget(x => + { m_host.AddScriptLPS(1); if (m_item.PermsGranter == UUID.Zero) - return 0; + return; if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) { LSLError("No permissions to give money"); - return 0; + return; } UUID toID = new UUID(); @@ -3037,7 +3037,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(destination, out toID)) { LSLError("Bad key in llGiveMoney"); - return 0; + return; } IMoneyModule money = World.RequestModuleInterface(); @@ -3045,12 +3045,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (money == null) { NotImplemented("llGiveMoney"); - return 0; + return; } - return money.ObjectGiveMoney( + money.ObjectGiveMoney( m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero); -// }); + }); + + return 0; } public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)