From 0d566aa3856f90bf6de13d206b85e1b6150ff70c Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 6 Apr 2012 21:52:48 -0700 Subject: Better Suitcase Inventory Service. --- .../HypergridService/HGSuitcaseInventoryService.cs | 103 +++++++++++---------- 1 file changed, 55 insertions(+), 48 deletions(-) diff --git a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs index b6ec558..6a6181a 100644 --- a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs +++ b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs @@ -109,7 +109,7 @@ namespace OpenSim.Services.HypergridService XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); XInventoryFolder root = GetRootXFolder(principalID); - List tree = GetFolderTree(suitcase.folderID); + List tree = GetFolderTree(principalID, suitcase.folderID); if (tree == null || (tree != null && tree.Count == 0)) return null; @@ -119,7 +119,7 @@ namespace OpenSim.Services.HypergridService folders.Add(ConvertToOpenSim(x)); } - SetAsRootFolder(suitcase, root); + SetAsNormalFolder(suitcase, root); folders.Add(ConvertToOpenSim(suitcase)); return folders; @@ -136,10 +136,10 @@ namespace OpenSim.Services.HypergridService XInventoryFolder suitcase = GetSuitcaseXFolder(userID); XInventoryFolder root = GetRootXFolder(userID); - List tree = GetFolderTree(suitcase.folderID); + List tree = GetFolderTree(userID, suitcase.folderID); if (tree == null || (tree != null && tree.Count == 0)) { - SetAsRootFolder(suitcase, root); + SetAsNormalFolder(suitcase, root); userInventory.Folders.Add(ConvertToOpenSim(suitcase)); return userInventory; } @@ -164,7 +164,7 @@ namespace OpenSim.Services.HypergridService userInventory.Items.AddRange(items); } - SetAsRootFolder(suitcase, root); + SetAsNormalFolder(suitcase, root); userInventory.Folders.Add(ConvertToOpenSim(suitcase)); m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetUserInventory for user {0} returning {1} folders and {2} items", @@ -175,8 +175,6 @@ namespace OpenSim.Services.HypergridService public override InventoryFolderBase GetRootFolder(UUID principalID) { m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetRootFolder for {0}", principalID); - if (m_Database == null) - m_log.ErrorFormat("[XXX]: m_Database is NULL!"); // Let's find out the local root folder XInventoryFolder root = GetRootXFolder(principalID); ; @@ -202,7 +200,7 @@ namespace OpenSim.Services.HypergridService CreateSystemFolders(principalID, suitcase.folderID); } - SetAsRootFolder(suitcase, root); + SetAsNormalFolder(suitcase, root); return ConvertToOpenSim(suitcase); } @@ -271,9 +269,8 @@ namespace OpenSim.Services.HypergridService public override InventoryCollection GetFolderContent(UUID principalID, UUID folderID) { InventoryCollection coll = null; - XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); - if (!IsWithinSuitcaseTree(folderID, suitcase)) + if (!IsWithinSuitcaseTree(principalID, folderID)) return new InventoryCollection(); coll = base.GetFolderContent(principalID, folderID); @@ -290,9 +287,7 @@ namespace OpenSim.Services.HypergridService { // Let's do a bit of sanity checking, more than the base service does // make sure the given folder exists under the suitcase tree of this user - XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); - - if (!IsWithinSuitcaseTree(folderID, suitcase)) + if (!IsWithinSuitcaseTree(principalID, folderID)) return new List(); return base.GetFolderItems(principalID, folderID); @@ -303,21 +298,27 @@ namespace OpenSim.Services.HypergridService m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: AddFolder {0} {1}", folder.Name, folder.ParentID); // Let's do a bit of sanity checking, more than the base service does // make sure the given folder's parent folder exists under the suitcase tree of this user - XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner); - if (!IsWithinSuitcaseTree(folder.ParentID, suitcase)) + if (!IsWithinSuitcaseTree(folder.Owner, folder.ParentID)) return false; // OK, it's legit - return base.AddFolder(folder); + if (base.AddFolder(folder)) + { + List tree; + if (m_SuitcaseTrees.TryGetValue(folder.Owner, out tree)) + tree.Add(ConvertFromOpenSim(folder)); + + return true; + } + + return false; } public override bool UpdateFolder(InventoryFolderBase folder) { - XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner); - m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Update folder {0}, version {1}", folder.ID, folder.Version); - if (!IsWithinSuitcaseTree(folder.ID, suitcase)) + if (!IsWithinSuitcaseTree(folder.Owner, folder.ID)) { m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: folder {0} not within Suitcase tree", folder.Name); return false; @@ -329,9 +330,8 @@ namespace OpenSim.Services.HypergridService public override bool MoveFolder(InventoryFolderBase folder) { - XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner); - - if (!IsWithinSuitcaseTree(folder.ID, suitcase) || !IsWithinSuitcaseTree(folder.ParentID, suitcase)) + if (!IsWithinSuitcaseTree(folder.Owner, folder.ID) || + !IsWithinSuitcaseTree(folder.Owner, folder.ParentID)) return false; return base.MoveFolder(folder); @@ -353,9 +353,7 @@ namespace OpenSim.Services.HypergridService { // Let's do a bit of sanity checking, more than the base service does // make sure the given folder's parent folder exists under the suitcase tree of this user - XInventoryFolder suitcase = GetSuitcaseXFolder(item.Owner); - - if (!IsWithinSuitcaseTree(item.Folder, suitcase)) + if (!IsWithinSuitcaseTree(item.Owner, item.Folder)) return false; // OK, it's legit @@ -365,9 +363,7 @@ namespace OpenSim.Services.HypergridService public override bool UpdateItem(InventoryItemBase item) { - XInventoryFolder suitcase = GetSuitcaseXFolder(item.Owner); - - if (!IsWithinSuitcaseTree(item.Folder, suitcase)) + if (!IsWithinSuitcaseTree(item.Owner, item.Folder)) return false; return base.UpdateItem(item); @@ -377,9 +373,7 @@ namespace OpenSim.Services.HypergridService { // Principal is b0rked. *sigh* - XInventoryFolder suitcase = GetSuitcaseXFolder(items[0].Owner); - - if (!IsWithinSuitcaseTree(items[0].Folder, suitcase)) + if (!IsWithinSuitcaseTree(items[0].Owner, items[0].Folder)) return false; return base.MoveItems(principalID, items); @@ -400,15 +394,8 @@ namespace OpenSim.Services.HypergridService item.Name, item.ID, item.Folder); return null; } - XInventoryFolder suitcase = GetSuitcaseXFolder(it.Owner); - if (suitcase == null) - { - m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Root or Suitcase are null for user {0}", - it.Owner); - return null; - } - if (!IsWithinSuitcaseTree(it.Folder, suitcase)) + if (!IsWithinSuitcaseTree(it.Owner, it.Folder)) { m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Item {0} (folder {1}) is not within Suitcase", it.Name, it.Folder); @@ -431,9 +418,7 @@ namespace OpenSim.Services.HypergridService if (f != null) { - XInventoryFolder suitcase = GetSuitcaseXFolder(f.Owner); - - if (!IsWithinSuitcaseTree(f.ID, suitcase)) + if (!IsWithinSuitcaseTree(f.Owner, f.ID)) return null; } @@ -481,22 +466,37 @@ namespace OpenSim.Services.HypergridService if (folders != null && folders.Length > 0) return folders[0]; + + // check to see if we have the old Suitcase folder + folders = m_Database.GetFolders( + new string[] { "agentID", "folderName", "parentFolderID" }, + new string[] { principalID.ToString(), "My Suitcase", UUID.Zero.ToString() }); + if (folders != null && folders.Length > 0) + { + // Move it to under the root folder + XInventoryFolder root = GetRootXFolder(principalID); + folders[0].parentFolderID = root.folderID; + folders[0].type = 100; + m_Database.StoreFolder(folders[0]); + return folders[0]; + } + return null; } - private void SetAsRootFolder(XInventoryFolder suitcase, XInventoryFolder root) + private void SetAsNormalFolder(XInventoryFolder suitcase, XInventoryFolder root) { suitcase.type = (short)AssetType.Folder; } - private List GetFolderTree(UUID folder) + private List GetFolderTree(UUID principalID, UUID folder) { List t = null; - if (m_SuitcaseTrees.TryGetValue(folder, out t)) + if (m_SuitcaseTrees.TryGetValue(principalID, out t)) return t; t = GetFolderTreeRecursive(folder); - m_SuitcaseTrees.AddOrUpdate(folder, t, 120); + m_SuitcaseTrees.AddOrUpdate(principalID, t, 5*60); // 5minutes return t; } @@ -528,11 +528,18 @@ namespace OpenSim.Services.HypergridService /// /// /// - private bool IsWithinSuitcaseTree(UUID folderID, XInventoryFolder suitcase) + private bool IsWithinSuitcaseTree(UUID principalID, UUID folderID) { + XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); + if (suitcase == null) + { + m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: User {0} does not have a Suitcase folder", principalID); + return false; + } + List tree = new List(); tree.Add(suitcase); // Warp! the tree is the real root folder plus the children of the suitcase folder - tree.AddRange(GetFolderTree(suitcase.folderID)); + tree.AddRange(GetFolderTree(principalID, suitcase.folderID)); XInventoryFolder f = tree.Find(delegate(XInventoryFolder fl) { if (fl.folderID == folderID) return true; -- cgit v1.1 From 7c534e558ddedc66be21efa72bfa9aa7087e6f8c Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 7 Apr 2012 14:38:32 -0700 Subject: Added gatekeeper and uas addresses to grid info, so that viewers can take advantage of that info. --- bin/Robust.HG.ini.example | 8 ++++++++ bin/config-include/StandaloneCommon.ini.example | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 2fd9f11..0eb8291 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -318,6 +318,14 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ; password help: optional: page providing password assistance for users of your grid ;password = http://127.0.0.1/password + + ; HG address of the gatekeeper, if you have one + ; this is the entry point for all the regions of the world + ; gatekeeper = http://127.0.0.1:8002/ + + ; HG user domain, if you have one + ; this is the entry point for all user-related HG services + ; uas = http://127.0.0.1:8002/ [GatekeeperService] LocalServiceModule = "OpenSim.Services.HypergridService.dll:GatekeeperService" diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 8d9842c..4f4f400 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -231,6 +231,14 @@ ; currently unused ;password = http://127.0.0.1/password + ; HG address of the gatekeeper, if you have one + ; this is the entry point for all the regions of the world + ; gatekeeper = http://127.0.0.1:9000/ + + ; HG user domain, if you have one + ; this is the entry point for all user-related HG services + ; uas = http://127.0.0.1:9000/ + [MapImageService] ; Set this if you want to change the default ; TilesStoragePath = "maptiles" -- cgit v1.1 From d4a370a5f2b010727b1a2fdcc6526b7b13c72962 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 7 Apr 2012 14:52:15 -0700 Subject: A few more minor improvements on Suitcase inventory service. --- .../Services/HypergridService/HGSuitcaseInventoryService.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs index 6a6181a..53fbea6 100644 --- a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs +++ b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs @@ -107,7 +107,6 @@ namespace OpenSim.Services.HypergridService public override List GetInventorySkeleton(UUID principalID) { XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); - XInventoryFolder root = GetRootXFolder(principalID); List tree = GetFolderTree(principalID, suitcase.folderID); if (tree == null || (tree != null && tree.Count == 0)) @@ -119,7 +118,7 @@ namespace OpenSim.Services.HypergridService folders.Add(ConvertToOpenSim(x)); } - SetAsNormalFolder(suitcase, root); + SetAsNormalFolder(suitcase); folders.Add(ConvertToOpenSim(suitcase)); return folders; @@ -134,12 +133,11 @@ namespace OpenSim.Services.HypergridService userInventory.Items = new List(); XInventoryFolder suitcase = GetSuitcaseXFolder(userID); - XInventoryFolder root = GetRootXFolder(userID); List tree = GetFolderTree(userID, suitcase.folderID); if (tree == null || (tree != null && tree.Count == 0)) { - SetAsNormalFolder(suitcase, root); + SetAsNormalFolder(suitcase); userInventory.Folders.Add(ConvertToOpenSim(suitcase)); return userInventory; } @@ -164,7 +162,7 @@ namespace OpenSim.Services.HypergridService userInventory.Items.AddRange(items); } - SetAsNormalFolder(suitcase, root); + SetAsNormalFolder(suitcase); userInventory.Folders.Add(ConvertToOpenSim(suitcase)); m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetUserInventory for user {0} returning {1} folders and {2} items", @@ -181,6 +179,7 @@ namespace OpenSim.Services.HypergridService if (root == null) { m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: Unable to retrieve local root folder for user {0}", principalID); + return null; } // Warp! Root folder for travelers is the suitcase folder @@ -200,7 +199,7 @@ namespace OpenSim.Services.HypergridService CreateSystemFolders(principalID, suitcase.folderID); } - SetAsNormalFolder(suitcase, root); + SetAsNormalFolder(suitcase); return ConvertToOpenSim(suitcase); } @@ -484,7 +483,7 @@ namespace OpenSim.Services.HypergridService return null; } - private void SetAsNormalFolder(XInventoryFolder suitcase, XInventoryFolder root) + private void SetAsNormalFolder(XInventoryFolder suitcase) { suitcase.type = (short)AssetType.Folder; } -- cgit v1.1 From 0f277dfa179ea220b6714d0659632bb3cf2724d0 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 8 Apr 2012 17:54:59 -0700 Subject: Addresses mantis #5846 --- OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 4d98f00..b8616e8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -156,7 +156,9 @@ namespace OpenSim.Region.Framework.Scenes // that the region position is cached or performance will degrade Utils.LongToUInts(regionHandle, out x, out y); GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y); -// bool v = true; + if (dest == null) + continue; + if (!simulatorList.Contains(dest.ServerURI)) { // we havent seen this simulator before, add it to the list -- cgit v1.1 From 78c0028179923710949fea349baad2e6bebc49bd Mon Sep 17 00:00:00 2001 From: Talun Date: Mon, 9 Apr 2012 19:58:07 +0100 Subject: Mantis5502 implementation of some of the new constants Signed-off-by: Melanie --- .../Framework/Interfaces/IEntityInventory.cs | 10 +++++ .../Region/Framework/Interfaces/IScriptModule.cs | 6 +++ .../Region/Framework/Scenes/SceneObjectGroup.cs | 28 +++++++++++- .../Framework/Scenes/SceneObjectPartInventory.cs | 51 +++++++++++++++++++++- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 38 ++++++++++++++++ .../Shared/Api/Implementation/LSL_Api.cs | 42 ++++++++++-------- 6 files changed, 155 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 1334905..f5dda34 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -226,6 +226,16 @@ namespace OpenSim.Region.Framework.Interfaces bool ContainsScripts(); /// + /// Returns the count of scripts contained + /// + int ScriptCount(); + + /// + /// Returns the count of running scripts contained + /// + int RunningScriptCount(); + + /// /// Get the uuids of all items in this inventory /// /// diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs index 9cab2e1..c0616ed 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs @@ -69,6 +69,12 @@ namespace OpenSim.Region.Framework.Interfaces ArrayList GetScriptErrors(UUID itemID); + /// + /// Returns true if a script is running. + /// + /// The item ID of the script. + bool GetScriptState(UUID itemID); + void SaveAllState(); /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 17f3be7..7d14814 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3255,7 +3255,33 @@ namespace OpenSim.Region.Framework.Scenes for (int i = 0; i < parts.Length; i++) parts[i].TriggerScriptChangedEvent(val); } - + + /// + /// Returns a count of the number of scripts in this groups parts. + /// + public int ScriptCount() + { + int count = 0; + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + count += parts[i].Inventory.ScriptCount(); + + return count; + } + + /// + /// Returns a count of the number of running scripts in this groups parts. + /// + public int RunningScriptCount() + { + int count = 0; + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + count += parts[i].Inventory.RunningScriptCount(); + + return count; + } + public override string ToString() { return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index f7e123b..9a04c65 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -1081,10 +1081,59 @@ namespace OpenSim.Region.Framework.Scenes } } } - + return false; } + /// + /// Returns the count of scripts in this parts inventory. + /// + /// + public int ScriptCount() + { + int count = 0; + lock (m_items) + { + foreach (TaskInventoryItem item in m_items.Values) + { + if (item.InvType == (int)InventoryType.LSL) + { + count++; + } + } + } + + return count; + } + /// + /// Returns the count of running scripts in this parts inventory. + /// + /// + public int RunningScriptCount() + { + IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces(); + if (engines.Length == 0) + return 0; + + int count = 0; + List scripts = GetInventoryScripts(); + + foreach (TaskInventoryItem item in scripts) + { + foreach (IScriptModule engine in engines) + { + if (engine != null) + { + if (engine.GetScriptState(item.ItemID)) + { + count++; + } + } + } + } + return count; + } + public List GetInventoryList() { List ret = new List(); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a21c66f..8863df1 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3418,6 +3418,44 @@ namespace OpenSim.Region.Framework.Scenes return m_attachments.Count > 0; } + /// + /// Returns the total count of scripts in all parts inventories. + /// + public int ScriptCount() + { + int count = 0; + lock (m_attachments) + { + foreach (SceneObjectGroup gobj in m_attachments) + { + if (gobj != null) + { + count += gobj.ScriptCount(); + } + } + } + return count; + } + + /// + /// Returns the total count of running scripts in all parts. + /// + public int RunningScriptCount() + { + int count = 0; + lock (m_attachments) + { + foreach (SceneObjectGroup gobj in m_attachments) + { + if (gobj != null) + { + count += gobj.RunningScriptCount(); + } + } + } + return count; + } + public bool HasScriptedAttachments() { lock (m_attachments) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 291f52e..c38a52e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10358,19 +10358,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api break; // For the following 8 see the Object version below case ScriptBaseClass.OBJECT_RUNNING_SCRIPT_COUNT: - ret.Add(new LSL_Integer(0)); + ret.Add(new LSL_Integer(av.RunningScriptCount())); break; case ScriptBaseClass.OBJECT_TOTAL_SCRIPT_COUNT: - ret.Add(new LSL_Integer(0)); + ret.Add(new LSL_Integer(av.ScriptCount())); break; case ScriptBaseClass.OBJECT_SCRIPT_MEMORY: - ret.Add(new LSL_Integer(0)); + ret.Add(new LSL_Integer(av.RunningScriptCount() * 16384)); break; case ScriptBaseClass.OBJECT_SCRIPT_TIME: ret.Add(new LSL_Float(0)); break; case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE: - ret.Add(new LSL_Integer(0)); + ret.Add(new LSL_Integer(1)); break; case ScriptBaseClass.OBJECT_SERVER_COST: ret.Add(new LSL_Float(0)); @@ -10422,24 +10422,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case ScriptBaseClass.OBJECT_CREATOR: ret.Add(new LSL_String(obj.CreatorID.ToString())); break; - // The following 8 I have intentionaly coded to return zero. They are part of - // "Land Impact" calculations. These calculations are probably not applicable - // to OpenSim, required figures (cpu/memory usage) are not currently tracked - // I have intentionally left these all at zero rather than return possibly - // missleading numbers case ScriptBaseClass.OBJECT_RUNNING_SCRIPT_COUNT: - // in SL this currently includes crashed scripts - ret.Add(new LSL_Integer(0)); + ret.Add(new LSL_Integer(obj.ParentGroup.RunningScriptCount())); break; case ScriptBaseClass.OBJECT_TOTAL_SCRIPT_COUNT: - ret.Add(new LSL_Integer(0)); + ret.Add(new LSL_Integer(obj.ParentGroup.ScriptCount())); break; case ScriptBaseClass.OBJECT_SCRIPT_MEMORY: // The value returned in SL for mono scripts is 65536 * number of active scripts - ret.Add(new LSL_Integer(0)); + // and 16384 * number of active scripts for LSO. since llGetFreememory + // is coded to give the LSO value use it here + ret.Add(new LSL_Integer(obj.ParentGroup.RunningScriptCount() * 16384)); break; case ScriptBaseClass.OBJECT_SCRIPT_TIME: - // Average cpu time per simulator frame expended on all scripts in the objetc + // Average cpu time per simulator frame expended on all scripts in the object + // Not currently available at Object level ret.Add(new LSL_Float(0)); break; case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE: @@ -10447,18 +10444,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // equivalent of the number of prims in a linkset if it does not // contain a mesh anywhere in the link set or is not a normal prim // The value returned in SL for normal prims is prim count - ret.Add(new LSL_Integer(0)); + ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); break; + // The following 3 costs I have intentionaly coded to return zero. They are part of + // "Land Impact" calculations. These calculations are probably not applicable + // to OpenSim and are not yet complete in SL case ScriptBaseClass.OBJECT_SERVER_COST: - // The value returned in SL for normal prims is prim count + // The linden calculation is here + // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight + // The value returned in SL for normal prims looks like the prim count ret.Add(new LSL_Float(0)); break; case ScriptBaseClass.OBJECT_STREAMING_COST: - // The value returned in SL for normal prims is prim count * 0.06 + // The linden calculation is here + // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost + // The value returned in SL for normal prims looks like the prim count * 0.06 ret.Add(new LSL_Float(0)); break; case ScriptBaseClass.OBJECT_PHYSICS_COST: - // The value returned in SL for normal prims is prim count + // The linden calculation is here + // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics + // The value returned in SL for normal prims looks like the prim count ret.Add(new LSL_Float(0)); break; default: -- cgit v1.1 From f9dd4ed89c7aff63191c3be0bfa9d24d15d1d4bc Mon Sep 17 00:00:00 2001 From: Snoopy Pfeffer Date: Tue, 10 Apr 2012 15:51:26 +0200 Subject: Do not timeout group member cache entry, as long as there are frequent group membership requests. These are caused by movements within the parcel boundaries. --- OpenSim/Region/CoreModules/World/Land/LandObject.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index ced7b52..7f44613 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -429,7 +429,10 @@ namespace OpenSim.Region.CoreModules.World.Land { bool isMember; if (m_groupMemberCache.TryGetValue(avatar, out isMember)) + { + m_groupMemberCache.Update(avatar, isMember, m_groupMemberCacheTimeout); return isMember; + } IGroupsModule groupsModule = m_scene.RequestModuleInterface(); if (groupsModule == null) -- cgit v1.1 From 2b339bfd9702d2d1c988b87bc806b7fe3bdbed69 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 10 Apr 2012 17:22:02 +0100 Subject: Correct max_listeners_per_region in OpenSimDefaults.ini to max_listens_per_region Value for this setting in OpenSimDefaults.ini (1000) is same as setting in code (1000) so this should have no effect Thanks to Ovi Chris Rouly for pointing this out. --- bin/OpenSimDefaults.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 45d604f..68a2ea3 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -1129,7 +1129,7 @@ ; Maximum number of llListen events we allow over the entire region. ; Set this to 0 to have no limit imposed - max_listeners_per_region = 1000 + max_listens_per_region = 1000 ; Maximum number of llListen events we allow per script ; Set this to 0 to have no limit imposed. -- cgit v1.1 From fb44e7b636f35a773c016dcfbd56318d6d337c57 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 10 Apr 2012 17:46:34 +0100 Subject: minor: convert tabs to spaces in config example files from recent 7c534e5 --- bin/Robust.HG.ini.example | 12 ++++++------ bin/config-include/StandaloneCommon.ini.example | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 0eb8291..4ea5ffd 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -319,13 +319,13 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ; password help: optional: page providing password assistance for users of your grid ;password = http://127.0.0.1/password - ; HG address of the gatekeeper, if you have one - ; this is the entry point for all the regions of the world - ; gatekeeper = http://127.0.0.1:8002/ + ; HG address of the gatekeeper, if you have one + ; this is the entry point for all the regions of the world + ; gatekeeper = http://127.0.0.1:8002/ - ; HG user domain, if you have one - ; this is the entry point for all user-related HG services - ; uas = http://127.0.0.1:8002/ + ; HG user domain, if you have one + ; this is the entry point for all user-related HG services + ; uas = http://127.0.0.1:8002/ [GatekeeperService] LocalServiceModule = "OpenSim.Services.HypergridService.dll:GatekeeperService" diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 4f4f400..8fe64df 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -231,13 +231,13 @@ ; currently unused ;password = http://127.0.0.1/password - ; HG address of the gatekeeper, if you have one - ; this is the entry point for all the regions of the world - ; gatekeeper = http://127.0.0.1:9000/ + ; HG address of the gatekeeper, if you have one + ; this is the entry point for all the regions of the world + ; gatekeeper = http://127.0.0.1:9000/ - ; HG user domain, if you have one - ; this is the entry point for all user-related HG services - ; uas = http://127.0.0.1:9000/ + ; HG user domain, if you have one + ; this is the entry point for all user-related HG services + ; uas = http://127.0.0.1:9000/ [MapImageService] ; Set this if you want to change the default -- cgit v1.1 From 4ab479bf58652573606fa08136e182260b180a0b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 10 Apr 2012 20:40:59 +0100 Subject: Add uri to various log messages when region registration fails. Upgrade some debug log messages to error. --- .../Connectors/Grid/GridServiceConnector.cs | 23 ++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs index 1599a56..34ed0d7 100644 --- a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs +++ b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs @@ -113,29 +113,36 @@ namespace OpenSim.Services.Connectors } else if (replyData.ContainsKey("Result")&& (replyData["Result"].ToString().ToLower() == "failure")) { - m_log.DebugFormat("[GRID CONNECTOR]: Registration failed: {0}", replyData["Message"].ToString()); + m_log.ErrorFormat( + "[GRID CONNECTOR]: Registration failed: {0} when contacting {1}", replyData["Message"], uri); + return replyData["Message"].ToString(); } else if (!replyData.ContainsKey("Result")) { - m_log.DebugFormat("[GRID CONNECTOR]: reply data does not contain result field"); + m_log.ErrorFormat( + "[GRID CONNECTOR]: reply data does not contain result field when contacting {0}", uri); } else { - m_log.DebugFormat("[GRID CONNECTOR]: unexpected result {0}", replyData["Result"].ToString()); - return "Unexpected result "+replyData["Result"].ToString(); + m_log.ErrorFormat( + "[GRID CONNECTOR]: unexpected result {0} when contacting {1}", replyData["Result"], uri); + + return "Unexpected result " + replyData["Result"].ToString(); } - } else - m_log.DebugFormat("[GRID CONNECTOR]: RegisterRegion received null reply"); + { + m_log.ErrorFormat( + "[GRID CONNECTOR]: RegisterRegion received null reply when contacting grid server at {0}", uri); + } } catch (Exception e) { - m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); + m_log.ErrorFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); } - return "Error communicating with grid service"; + return string.Format("Error communicating with the grid service at {0}", uri); } public bool DeregisterRegion(UUID regionID) -- cgit v1.1 From 78fd487a705c91720991a7572b860567f36366c4 Mon Sep 17 00:00:00 2001 From: Snoopy Pfeffer Date: Tue, 10 Apr 2012 21:49:43 +0200 Subject: New OS scripting functions osSetTerrainTexture and osSetTerrainHeight as originally proposed in SL Jira (https://jira.secondlife.com/browse/SVC-244). --- .../World/Estate/EstateManagementModule.cs | 15 +++++- .../Region/Framework/Interfaces/IEstateModule.cs | 3 ++ .../Shared/Api/Implementation/OSSL_Api.cs | 55 ++++++++++++++++++++++ .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 3 ++ .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 10 ++++ 5 files changed, 84 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index fc217b0..124f01c 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -157,12 +157,18 @@ namespace OpenSim.Region.CoreModules.World.Estate sendRegionInfoPacketToAll(); } - public void setEstateTerrainBaseTexture(IClientAPI remoteClient, int corner, UUID texture) + public void setEstateTerrainBaseTexture(int level, UUID texture) + { + setEstateTerrainBaseTexture(null, level, texture); + sendRegionHandshakeToAll(); + } + + public void setEstateTerrainBaseTexture(IClientAPI remoteClient, int level, UUID texture) { if (texture == UUID.Zero) return; - switch (corner) + switch (level) { case 0: Scene.RegionInfo.RegionSettings.TerrainTexture1 = texture; @@ -182,6 +188,11 @@ namespace OpenSim.Region.CoreModules.World.Estate sendRegionInfoPacketToAll(); } + public void setEstateTerrainTextureHeights(int corner, float lowValue, float highValue) + { + setEstateTerrainTextureHeights(null, corner, lowValue, highValue); + } + public void setEstateTerrainTextureHeights(IClientAPI client, int corner, float lowValue, float highValue) { switch (corner) diff --git a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs index 721f0ee..15cd238 100644 --- a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs @@ -45,5 +45,8 @@ namespace OpenSim.Region.Framework.Interfaces /// Tell all clients about the current state of the region (terrain textures, water height, etc.). /// void sendRegionHandshakeToAll(); + + void setEstateTerrainBaseTexture(int level, UUID texture); + void setEstateTerrainTextureHeights(int corner, float lowValue, float highValue); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index a5dcba4..339166b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -3049,5 +3049,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return ScriptBaseClass.TRUE; } + + /// + /// Sets terrain estate texture + /// + /// + /// + /// + public void osSetTerrainTexture(int level, LSL_Key texture) + { + CheckThreatLevel(ThreatLevel.High, "osSetTerrainTexture"); + + m_host.AddScriptLPS(1); + //Check to make sure that the script's owner is the estate manager/master + //World.Permissions.GenericEstatePermission( + if (World.Permissions.IsGod(m_host.OwnerID)) + { + if (level < 0 || level > 3) + return; + + UUID textureID = new UUID(); + if (!UUID.TryParse(texture, out textureID)) + return; + + // estate module is required + IEstateModule estate = World.RequestModuleInterface(); + if (estate != null) + estate.setEstateTerrainBaseTexture(level, textureID); + } + } + + /// + /// Sets terrain heights of estate + /// + /// + /// + /// + /// + public void osSetTerrainTextureHeight(int corner, double low, double high) + { + CheckThreatLevel(ThreatLevel.High, "osSetTerrainTextureHeight"); + + m_host.AddScriptLPS(1); + //Check to make sure that the script's owner is the estate manager/master + //World.Permissions.GenericEstatePermission( + if (World.Permissions.IsGod(m_host.OwnerID)) + { + if (corner < 0 || corner > 3) + return; + + // estate module is required + IEstateModule estate = World.RequestModuleInterface(); + if (estate != null) + estate.setEstateTerrainTextureHeights(corner, (float)low, (float)high); + } + } } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 30bd3ef..545bbee 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -234,5 +234,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Integer osInviteToGroup(LSL_Key agentId); LSL_Integer osEjectFromGroup(LSL_Key agentId); + + void osSetTerrainTexture(int level, LSL_Key texture); + void osSetTerrainTextureHeight(int corner, double low, double high); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 680cefb4..b94b9bf 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -878,5 +878,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_OSSL_Functions.osEjectFromGroup(agentId); } + + public void osSetTerrainTexture(int level, LSL_Key texture) + { + m_OSSL_Functions.osSetTerrainTexture(level, texture); + } + + public void osSetTerrainTextureHeight(int corner, double low, double high) + { + m_OSSL_Functions.osSetTerrainTextureHeight(corner, low, high); + } } } -- cgit v1.1 From f2ede8c7e09487436261b249ec093bfd01c3f971 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 11 Apr 2012 08:11:05 -0700 Subject: HGFriendsModule: add the scaffolding for supporting permissions pertaining to HG friendships. Snoopy take it from here. --- .../CoreModules/Avatar/Friends/FriendsModule.cs | 4 +-- .../CoreModules/Avatar/Friends/HGFriendsModule.cs | 30 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index f64c161..fc6325d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -162,7 +162,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } - protected void InitModule(IConfigSource config) + protected virtual void InitModule(IConfigSource config) { IConfig friendsConfig = config.Configs["Friends"]; if (friendsConfig != null) @@ -546,7 +546,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } - private void OnInstantMessage(IClientAPI client, GridInstantMessage im) + protected virtual void OnInstantMessage(IClientAPI client, GridInstantMessage im) { if ((InstantMessageDialog)im.dialog == InstantMessageDialog.FriendshipOffered) { diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index 9a6d277..ddb6a71 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -87,6 +87,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends m_StatusNotifier = new HGStatusNotifier(this); } + protected override void InitModule(IConfigSource config) + { + base.InitModule(config); + + // Additionally to the base method + IConfig friendsConfig = config.Configs["HGFriendsModule"]; + if (friendsConfig != null) + { + // TODO: read in all config variables pertaining to + // HG friendship permissions + } + } + #endregion #region IFriendsSimConnector @@ -105,6 +118,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends #endregion + protected override void OnInstantMessage(IClientAPI client, GridInstantMessage im) + { + if ((InstantMessageDialog)im.dialog == InstantMessageDialog.FriendshipOffered) + { + // we got a friendship offer + UUID principalID = new UUID(im.fromAgentID); + UUID friendID = new UUID(im.toAgentID); + + // TODO: CHECK IF friendID is foreigner and if principalID has the permission + // to request these kinds of friendships. If not, return immediately. + // Maybe you want to let the client know too with + // client.SendAlertMessage + } + + base.OnInstantMessage(client, im); + } + protected override void OnApproveFriendRequest(IClientAPI client, UUID friendID, List callingCardFolders) { // Update the local cache. Yes, we need to do it right here -- cgit v1.1 From 1f4d3d35822c5ad3dbdd5f363014f1bf9afebdc6 Mon Sep 17 00:00:00 2001 From: Snoopy Pfeffer Date: Wed, 11 Apr 2012 18:52:07 +0200 Subject: HGFriendsModule: Added optional user level based restriction to send friendship invitations to foreign users. --- .../CoreModules/Avatar/Friends/HGFriendsModule.cs | 24 ++++++++++++++++++---- bin/config-include/GridCommon.ini.example | 4 ++++ bin/config-include/StandaloneCommon.ini.example | 4 ++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index ddb6a71..f8fbbbb 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -50,6 +50,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private int m_levelHGFriends = 0; + IUserManagement m_uMan; public IUserManagement UserManagementModule { @@ -95,6 +97,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends IConfig friendsConfig = config.Configs["HGFriendsModule"]; if (friendsConfig != null) { + m_levelHGFriends = friendsConfig.GetInt("LevelHGFriends", 0); + // TODO: read in all config variables pertaining to // HG friendship permissions } @@ -126,10 +130,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends UUID principalID = new UUID(im.fromAgentID); UUID friendID = new UUID(im.toAgentID); - // TODO: CHECK IF friendID is foreigner and if principalID has the permission - // to request these kinds of friendships. If not, return immediately. - // Maybe you want to let the client know too with - // client.SendAlertMessage + // Check if friendID is foreigner and if principalID has the permission + // to request friendships with foreigners. If not, return immediately. + if (!UserManagementModule.IsLocalGridUser(friendID)) + { + ScenePresence avatar = null; + client.Scene.TryGetScenePresence(principalID, out avatar); + + if (avatar == null) + return; + + if (avatar.UserLevel < m_levelHGFriends) + { + client.SendAgentAlertMessage("Unable to send friendship invitation to foreigner. Insufficient permissions.", false); + return; + } + } } base.OnInstantMessage(client, im); diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index fa6f525..8d7f6fc 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -137,6 +137,10 @@ ;; uncomment the next line. You may want to do this on sims that have licensed content. ; OutboundPermission = False +[HGFriendsModule] + ; User level required to be able to send friendship invitations to foreign users + ;LevelHGFriends = 0; + [UserAgentService] ; ; === HG ONLY === diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 8fe64df..e4bc548 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -61,6 +61,10 @@ ;; uncomment the next line. You may want to do this on sims that have licensed content. ; OutboundPermission = False +[HGFriendsModule] + ; User level required to be able to send friendship invitations to foreign users + ;LevelHGFriends = 0; + [GridService] ;; For in-memory region storage (default) StorageProvider = "OpenSim.Data.Null.dll:NullRegionData" -- cgit v1.1 From 8be14095fed0d1d9f448d51fede20d13231c02db Mon Sep 17 00:00:00 2001 From: Snoopy Pfeffer Date: Wed, 11 Apr 2012 18:56:28 +0200 Subject: HGFriendsModule: Type casts to fix compile error --- OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index f8fbbbb..3728b85 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -135,7 +135,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (!UserManagementModule.IsLocalGridUser(friendID)) { ScenePresence avatar = null; - client.Scene.TryGetScenePresence(principalID, out avatar); + ((Scene)client.Scene).TryGetScenePresence(principalID, out avatar); if (avatar == null) return; -- cgit v1.1 From 30d8506bc2f04028c1bbdcf57cf5f45fedb3ae7a Mon Sep 17 00:00:00 2001 From: nebadon Date: Thu, 12 Apr 2012 18:27:14 -0700 Subject: make changes to FlotsamCache.ini.example as noted in mantis #5960 http://opensimulator.org/mantis/view.php?id=5960 --- bin/config-include/FlotsamCache.ini.example | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/config-include/FlotsamCache.ini.example b/bin/config-include/FlotsamCache.ini.example index cd39f8c..b9c6d84 100644 --- a/bin/config-include/FlotsamCache.ini.example +++ b/bin/config-include/FlotsamCache.ini.example @@ -36,7 +36,7 @@ ; How often {in hours} should the disk be checked for expired filed ; Specify 0 to disable expiration checking - FileCleanupTimer = .166 ;roughly every 10 minutes + FileCleanupTimer = 1.0 ;every hour ; If WAIT_ON_INPROGRESS_REQUESTS has been defined then this specifies how ; long (in miliseconds) to block a request thread while trying to complete @@ -60,4 +60,4 @@ ; cache, and request all assets that are found that are not already cached (this ; will cause those assets to be cached) ; - ; DeepScanBeforePurge = false + DeepScanBeforePurge = true -- cgit v1.1 From 08e509978d81cb3451c205ed59648e3f5da91344 Mon Sep 17 00:00:00 2001 From: Talun Date: Tue, 10 Apr 2012 21:25:05 +0100 Subject: Mantis 55025 Implement script time. Signed-off-by: nebadon --- .../Framework/Interfaces/IEntityInventory.cs | 12 +++- .../Region/Framework/Interfaces/IScriptModule.cs | 8 +++ .../Region/Framework/Scenes/SceneObjectGroup.cs | 39 ++++++++++ .../Framework/Scenes/SceneObjectPartInventory.cs | 14 ++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 19 +++++ .../Shared/Api/Implementation/LSL_Api.cs | 7 +- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 82 +++++++++++++--------- 7 files changed, 135 insertions(+), 46 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index f5dda34..30ed7d1 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -172,7 +172,17 @@ namespace OpenSim.Region.Framework.Interfaces /// If no inventory item has that name then an empty list is returned. /// List GetInventoryItems(string name); - + + /// + /// Get inventory items by type. + /// + /// + /// + /// A list of inventory items of that type. + /// If no inventory items of that type then an empty list is returned. + /// + List GetInventoryItems(InventoryType type); + /// /// Get the scene object referenced by an inventory item. /// diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs index c0616ed..0d488df 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs @@ -83,6 +83,14 @@ namespace OpenSim.Region.Framework.Interfaces void StartProcessing(); /// + /// Get the execution times of all scripts in the given array if they are currently running. + /// + /// + /// A float the value is a representative execution time in milliseconds of all scripts in that Array. + /// + float GetScriptExecutionTime(List itemIDs); + + /// /// Get the execution times of all scripts in each object. /// /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 7d14814..a49ed13 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3270,6 +3270,45 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// A float the value is a representative execution time in milliseconds of all scripts in the link set. + /// + public float ScriptExecutionTime() + { + IScriptModule[] engines = Scene.RequestModuleInterfaces(); + + if (engines.Length == 0) // No engine at all + return 0.0f; + + float time = 0.0f; + + // get all the scripts in all parts + SceneObjectPart[] parts = m_parts.GetArray(); + List scripts = new List(); + for (int i = 0; i < parts.Length; i++) + { + scripts.AddRange(parts[i].Inventory.GetInventoryItems(InventoryType.LSL)); + } + // extract the UUIDs + List ids = new List(scripts.Count); + foreach (TaskInventoryItem script in scripts) + { + if (!ids.Contains(script.ItemID)) + { + ids.Add(script.ItemID); + } + } + // Offer the list of script UUIDs to each engine found and accumulate the time + foreach (IScriptModule e in engines) + { + if (e != null) + { + time += e.GetScriptExecutionTime(ids); + } + } + return time; + } + + /// /// Returns a count of the number of running scripts in this groups parts. /// public int RunningScriptCount() diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 9a04c65..aacad98 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -222,7 +222,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) { - List scripts = GetInventoryScripts(); + List scripts = GetInventoryItems(InventoryType.LSL); foreach (TaskInventoryItem item in scripts) CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); } @@ -255,7 +255,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void RemoveScriptInstances(bool sceneObjectBeingDeleted) { - List scripts = GetInventoryScripts(); + List scripts = GetInventoryItems(InventoryType.LSL); foreach (TaskInventoryItem item in scripts) RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); } @@ -1116,7 +1116,7 @@ namespace OpenSim.Region.Framework.Scenes return 0; int count = 0; - List scripts = GetInventoryScripts(); + List scripts = GetInventoryItems(InventoryType.LSL); foreach (TaskInventoryItem item in scripts) { @@ -1157,14 +1157,14 @@ namespace OpenSim.Region.Framework.Scenes return ret; } - public List GetInventoryScripts() + public List GetInventoryItems(InventoryType type) { List ret = new List(); lock (m_items) { foreach (TaskInventoryItem item in m_items.Values) - if (item.InvType == (int)InventoryType.LSL) + if (item.InvType == (int)type) ret.Add(item); } @@ -1183,7 +1183,7 @@ namespace OpenSim.Region.Framework.Scenes if (engines.Length == 0) // No engine at all return ret; - List scripts = GetInventoryScripts(); + List scripts = GetInventoryItems(InventoryType.LSL); foreach (TaskInventoryItem item in scripts) { @@ -1211,7 +1211,7 @@ namespace OpenSim.Region.Framework.Scenes if (engines.Length == 0) return; - List scripts = GetInventoryScripts(); + List scripts = GetInventoryItems(InventoryType.LSL); foreach (TaskInventoryItem item in scripts) { diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 8863df1..641d742 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3438,6 +3438,25 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// A float the value is a representative execution time in milliseconds of all scripts in all attachments. + /// + public float ScriptExecutionTime() + { + float time = 0.0f; + lock (m_attachments) + { + foreach (SceneObjectGroup gobj in m_attachments) + { + if (gobj != null) + { + time += gobj.ScriptExecutionTime(); + } + } + } + return time; + } + + /// /// Returns the total count of running scripts in all parts. /// public int RunningScriptCount() diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c38a52e..078a22a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10367,7 +10367,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ret.Add(new LSL_Integer(av.RunningScriptCount() * 16384)); break; case ScriptBaseClass.OBJECT_SCRIPT_TIME: - ret.Add(new LSL_Float(0)); + ret.Add(new LSL_Float(av.ScriptExecutionTime() / 1000.0f)); break; case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE: ret.Add(new LSL_Integer(1)); @@ -10435,9 +10435,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ret.Add(new LSL_Integer(obj.ParentGroup.RunningScriptCount() * 16384)); break; case ScriptBaseClass.OBJECT_SCRIPT_TIME: - // Average cpu time per simulator frame expended on all scripts in the object - // Not currently available at Object level - ret.Add(new LSL_Float(0)); + // Average cpu time in seconds per simulator frame expended on all scripts in the object + ret.Add(new LSL_Float(obj.ParentGroup.ScriptExecutionTime() / 1000.0f)); break; case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE: // according to the SL wiki A prim or linkset will have prim diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 7712076..b7903d5 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1907,45 +1907,59 @@ namespace OpenSim.Region.ScriptEngine.XEngine if (!topScripts.ContainsKey(si.LocalID)) topScripts[si.RootLocalID] = 0; -// long ticksElapsed = tickNow - si.MeasurementPeriodTickStart; -// float framesElapsed = ticksElapsed / (18.1818 * TimeSpan.TicksPerMillisecond); - - // Execution time of the script adjusted by it's measurement period to make scripts started at - // different times comparable. -// float adjustedExecutionTime -// = (float)si.MeasurementPeriodExecutionTime -// / ((float)(tickNow - si.MeasurementPeriodTickStart) / ScriptInstance.MaxMeasurementPeriod) -// / TimeSpan.TicksPerMillisecond; - - long ticksElapsed = tickNow - si.MeasurementPeriodTickStart; - - // Avoid divide by zerp - if (ticksElapsed == 0) - ticksElapsed = 1; + topScripts[si.RootLocalID] += CalculateAdjustedExectionTime(si, tickNow); + } + } - // Scale execution time to the ideal 55 fps frame time for these reasons. - // - // 1) XEngine does not execute scripts per frame, unlike other script engines. Hence, there is no - // 'script execution time per frame', which is the original purpose of this value. - // - // 2) Giving the raw execution times is misleading since scripts start at different times, making - // it impossible to compare scripts. - // - // 3) Scaling the raw execution time to the time that the script has been running is better but - // is still misleading since a script that has just been rezzed may appear to have been running - // for much longer. - // - // 4) Hence, we scale execution time to an idealised frame time (55 fps). This is also not perfect - // since the figure does not represent actual execution time and very hard running scripts will - // never exceed 18ms (though this is a very high number for script execution so is a warning sign). - float adjustedExecutionTime - = ((float)si.MeasurementPeriodExecutionTime / ticksElapsed) * 18.1818f; + return topScripts; + } - topScripts[si.RootLocalID] += adjustedExecutionTime; + public float GetScriptExecutionTime(List itemIDs) + { + if (itemIDs == null|| itemIDs.Count == 0) + { + return 0.0f; + } + float time = 0.0f; + long tickNow = Util.EnvironmentTickCount(); + IScriptInstance si; + // Calculate the time for all scripts that this engine is executing + // Ignore any others + foreach (UUID id in itemIDs) + { + si = GetInstance(id); + if (si != null && si.Running) + { + time += CalculateAdjustedExectionTime(si, tickNow); } } + return time; + } - return topScripts; + private float CalculateAdjustedExectionTime(IScriptInstance si, long tickNow) + { + long ticksElapsed = tickNow - si.MeasurementPeriodTickStart; + + // Avoid divide by zero + if (ticksElapsed == 0) + ticksElapsed = 1; + + // Scale execution time to the ideal 55 fps frame time for these reasons. + // + // 1) XEngine does not execute scripts per frame, unlike other script engines. Hence, there is no + // 'script execution time per frame', which is the original purpose of this value. + // + // 2) Giving the raw execution times is misleading since scripts start at different times, making + // it impossible to compare scripts. + // + // 3) Scaling the raw execution time to the time that the script has been running is better but + // is still misleading since a script that has just been rezzed may appear to have been running + // for much longer. + // + // 4) Hence, we scale execution time to an idealised frame time (55 fps). This is also not perfect + // since the figure does not represent actual execution time and very hard running scripts will + // never exceed 18ms (though this is a very high number for script execution so is a warning sign). + return ((float)si.MeasurementPeriodExecutionTime / ticksElapsed) * 18.1818f; } public void SuspendScript(UUID itemID) -- cgit v1.1 From ab7c0e75472b354e34325fdf6280b77edb0567fe Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 13 Apr 2012 22:32:33 +0100 Subject: Remove hardcoded god requirement from osSetRegionWaterHeight, osSetRegionSunSettings and, osSetEstateSunSettings no matter the threat level. Change threat level on osSetRegionSunSettings and osSetEstateSunSettings from nuisance to high to match similar functions. If you had enabled these functions but had relied on the hardcoded god check in the code, then please adjust your OSSL permissions config. Thanks to Oren Hurvitz for pointing this out. --- .../Shared/Api/Implementation/OSSL_Api.cs | 61 +++++++++------------- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index a5dcba4..2c0de93 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -1179,12 +1179,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api CheckThreatLevel(ThreatLevel.High, "osSetRegionWaterHeight"); m_host.AddScriptLPS(1); - //Check to make sure that the script's owner is the estate manager/master - //World.Permissions.GenericEstatePermission( - if (World.Permissions.IsGod(m_host.OwnerID)) - { - World.EventManager.TriggerRequestChangeWaterHeight((float)height); - } + + World.EventManager.TriggerRequestChangeWaterHeight((float)height); } /// @@ -1195,27 +1191,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// The "Sun Hour" that is desired, 0...24, with 0 just after SunRise public void osSetRegionSunSettings(bool useEstateSun, bool sunFixed, double sunHour) { - CheckThreatLevel(ThreatLevel.Nuisance, "osSetRegionSunSettings"); + CheckThreatLevel(ThreatLevel.High, "osSetRegionSunSettings"); m_host.AddScriptLPS(1); - //Check to make sure that the script's owner is the estate manager/master - //World.Permissions.GenericEstatePermission( - if (World.Permissions.IsGod(m_host.OwnerID)) - { - while (sunHour > 24.0) - sunHour -= 24.0; - while (sunHour < 0) - sunHour += 24.0; + while (sunHour > 24.0) + sunHour -= 24.0; + while (sunHour < 0) + sunHour += 24.0; - World.RegionInfo.RegionSettings.UseEstateSun = useEstateSun; - World.RegionInfo.RegionSettings.SunPosition = sunHour + 6; // LL Region Sun Hour is 6 to 30 - World.RegionInfo.RegionSettings.FixedSun = sunFixed; - World.RegionInfo.RegionSettings.Save(); + World.RegionInfo.RegionSettings.UseEstateSun = useEstateSun; + World.RegionInfo.RegionSettings.SunPosition = sunHour + 6; // LL Region Sun Hour is 6 to 30 + World.RegionInfo.RegionSettings.FixedSun = sunFixed; + World.RegionInfo.RegionSettings.Save(); - World.EventManager.TriggerEstateToolsSunUpdate(World.RegionInfo.RegionHandle, sunFixed, useEstateSun, (float)sunHour); - } + World.EventManager.TriggerEstateToolsSunUpdate( + World.RegionInfo.RegionHandle, sunFixed, useEstateSun, (float)sunHour); } /// @@ -1225,26 +1217,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// The "Sun Hour" that is desired, 0...24, with 0 just after SunRise public void osSetEstateSunSettings(bool sunFixed, double sunHour) { - CheckThreatLevel(ThreatLevel.Nuisance, "osSetEstateSunSettings"); + CheckThreatLevel(ThreatLevel.High, "osSetEstateSunSettings"); m_host.AddScriptLPS(1); - //Check to make sure that the script's owner is the estate manager/master - //World.Permissions.GenericEstatePermission( - if (World.Permissions.IsGod(m_host.OwnerID)) - { - while (sunHour > 24.0) - sunHour -= 24.0; - while (sunHour < 0) - sunHour += 24.0; + while (sunHour > 24.0) + sunHour -= 24.0; - World.RegionInfo.EstateSettings.UseGlobalTime = !sunFixed; - World.RegionInfo.EstateSettings.SunPosition = sunHour; - World.RegionInfo.EstateSettings.FixedSun = sunFixed; - World.RegionInfo.EstateSettings.Save(); + while (sunHour < 0) + sunHour += 24.0; - World.EventManager.TriggerEstateToolsSunUpdate(World.RegionInfo.RegionHandle, sunFixed, World.RegionInfo.RegionSettings.UseEstateSun, (float)sunHour); - } + World.RegionInfo.EstateSettings.UseGlobalTime = !sunFixed; + World.RegionInfo.EstateSettings.SunPosition = sunHour; + World.RegionInfo.EstateSettings.FixedSun = sunFixed; + World.RegionInfo.EstateSettings.Save(); + + World.EventManager.TriggerEstateToolsSunUpdate( + World.RegionInfo.RegionHandle, sunFixed, World.RegionInfo.RegionSettings.UseEstateSun, (float)sunHour); } /// -- cgit v1.1 From eced0916894709e20c16ffc260599772913d7ff3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 13 Apr 2012 22:52:24 +0100 Subject: Change threat level of osNpcStopMoveToTarget from Low to High to match other NPC functions, and change OSSL permissions name to osNpcStopMoveToTarget instead of osNpcStopMoveTo Thanks to Oren Hurvitz for pointing out these mistakes. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 72c1bf6..2680ad0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2514,7 +2514,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcStopMoveToTarget(LSL_Key npc) { - CheckThreatLevel(ThreatLevel.VeryLow, "osNpcStopMoveTo"); + CheckThreatLevel(ThreatLevel.High, "osNpcStopMoveToTarget"); m_host.AddScriptLPS(1); INPCModule module = World.RequestModuleInterface(); -- cgit v1.1 From a366c05ae2fdfbcce1bc592166f89e3e286bcae4 Mon Sep 17 00:00:00 2001 From: Kevin Cozens Date: Fri, 10 Feb 2012 14:09:46 -0500 Subject: Added ability to exclude inventory items or folders when saving IAR files. --- .../Archiver/InventoryArchiveWriteRequest.cs | 88 ++++++++++----- .../Inventory/Archiver/InventoryArchiverModule.cs | 124 ++++++++++++--------- 2 files changed, 128 insertions(+), 84 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index a26c73a..0ee7606 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs @@ -91,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// Constructor /// public InventoryArchiveWriteRequest( - Guid id, InventoryArchiverModule module, Scene scene, + Guid id, InventoryArchiverModule module, Scene scene, UserAccount userInfo, string invPath, string savePath) : this( id, @@ -107,7 +107,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// Constructor /// public InventoryArchiveWriteRequest( - Guid id, InventoryArchiverModule module, Scene scene, + Guid id, InventoryArchiverModule module, Scene scene, UserAccount userInfo, string invPath, Stream saveStream) { m_id = id; @@ -125,7 +125,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { Exception reportedException = null; bool succeeded = true; - + try { m_archiveWriter.Close(); @@ -146,6 +146,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary options, IUserAccountService userAccountService) { + if (options.ContainsKey("exclude")) + { + if (((List)options["exclude"]).Contains(inventoryItem.Name) || + ((List)options["exclude"]).Contains(inventoryItem.ID.ToString())) + { + if (options.ContainsKey("verbose")) + { + m_log.InfoFormat( + "[INVENTORY ARCHIVER]: Skipping inventory item {0} {1} at {2}", + inventoryItem.Name, inventoryItem.ID, path); + } + return; + } + } + if (options.ContainsKey("verbose")) m_log.InfoFormat( "[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {2}", @@ -175,12 +190,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// /// protected void SaveInvFolder( - InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself, + InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself, Dictionary options, IUserAccountService userAccountService) { + if (options.ContainsKey("excludefolders")) + { + if (((List)options["excludefolders"]).Contains(inventoryFolder.Name) || + ((List)options["excludefolders"]).Contains(inventoryFolder.ID.ToString())) + { + if (options.ContainsKey("verbose")) + { + m_log.InfoFormat( + "[INVENTORY ARCHIVER]: Skipping folder {0} at {1}", + inventoryFolder.Name, path); + } + return; + } + } + if (options.ContainsKey("verbose")) m_log.InfoFormat("[INVENTORY ARCHIVER]: Saving folder {0}", inventoryFolder.Name); - + if (saveThisFolderItself) { path += CreateArchiveFolderName(inventoryFolder); @@ -189,7 +219,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver m_archiveWriter.WriteDir(path); } - InventoryCollection contents + InventoryCollection contents = m_scene.InventoryService.GetFolderContent(inventoryFolder.Owner, inventoryFolder.ID); foreach (InventoryFolderBase childFolder in contents.Folders) @@ -216,16 +246,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver InventoryFolderBase inventoryFolder = null; InventoryItemBase inventoryItem = null; InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID); - + bool saveFolderContentsOnly = false; - + // Eliminate double slashes and any leading / on the path. string[] components = m_invPath.Split( new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries); - + int maxComponentIndex = components.Length - 1; - + // If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the // folder itself. This may get more sophisicated later on if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD) @@ -233,13 +263,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver saveFolderContentsOnly = true; maxComponentIndex--; } - + m_invPath = String.Empty; for (int i = 0; i <= maxComponentIndex; i++) { m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER; } - + // Annoyingly Split actually returns the original string if the input string consists only of delimiters // Therefore if we still start with a / after the split, then we need the root folder if (m_invPath.Length == 0) @@ -249,25 +279,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver else { m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); - List candidateFolders + List candidateFolders = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath); if (candidateFolders.Count > 0) inventoryFolder = candidateFolders[0]; } - + // The path may point to an item instead if (inventoryFolder == null) inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath); - + if (null == inventoryFolder && null == inventoryItem) { - // We couldn't find the path indicated + // We couldn't find the path indicated string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath); Exception e = new InventoryArchiverException(errorMessage); m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e); throw e; } - + m_archiveWriter = new TarArchiveWriter(m_saveStream); m_log.InfoFormat("[INVENTORY ARCHIVER]: Adding control file to archive."); @@ -281,10 +311,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { m_log.DebugFormat( "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}", - inventoryFolder.Name, - inventoryFolder.ID, + inventoryFolder.Name, + inventoryFolder.ID, m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath); - + //recurse through all dirs getting dirs and files SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly, options, userAccountService); } @@ -293,10 +323,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver m_log.DebugFormat( "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}", inventoryItem.Name, inventoryItem.ID, m_invPath); - + SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH, options, userAccountService); } - + // Don't put all this profile information into the archive right now. //SaveUsers(); @@ -355,7 +385,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// /// These names are prepended with an inventory folder's UUID so that more than one folder can have the /// same name - /// + /// /// /// public static string CreateArchiveFolderName(InventoryFolderBase folder) @@ -369,7 +399,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// /// These names are prepended with an inventory item's UUID so that more than one item can have the /// same name - /// + /// /// /// public static string CreateArchiveItemName(InventoryItemBase item) @@ -415,7 +445,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver public string CreateControlFile(Dictionary options) { int majorVersion, minorVersion; - + if (options.ContainsKey("home")) { majorVersion = 1; @@ -425,10 +455,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { majorVersion = 0; minorVersion = 3; - } - + } + m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion); - + StringWriter sw = new StringWriter(); XmlTextWriter xtw = new XmlTextWriter(sw); xtw.Formatting = Formatting.Indented; @@ -450,4 +480,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver return s; } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index ac22c3f..cf87010 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs @@ -47,18 +47,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver public class InventoryArchiverModule : IRegionModule, IInventoryArchiverModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + public string Name { get { return "Inventory Archiver Module"; } } - + public bool IsSharedModule { get { return true; } } /// - /// Enable or disable checking whether the iar user is actually logged in + /// Enable or disable checking whether the iar user is actually logged in /// // public bool DisablePresenceChecks { get; set; } - + public event InventoryArchiveSaved OnInventoryArchiveSaved; - + /// /// The file to load and save inventory if no filename has been specified /// @@ -68,7 +68,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// Pending save completions initiated from the console /// protected List m_pendingConsoleSaves = new List(); - + /// /// All scenes that this module knows about /// @@ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { scene.RegisterModuleInterface(this); OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted; - + scene.AddCommand( "Archiving", this, "load iar", "load iar [-m|--merge] []", @@ -119,11 +119,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver + " is the filesystem path or URI from which to load the IAR." + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), HandleLoadInvConsoleCommand); - + scene.AddCommand( "Archiving", this, "save iar", - "save iar [-h|--home=] [--noassets] [] [-c|--creators] [-v|--verbose]", - "Save user inventory archive (IAR).", + "save iar [-h|--home=] [--noassets] [] [-c|--creators] [-e|--exclude=] [-f|--excludefolder=] [-v|--verbose]", + "Save user inventory archive (IAR).", " is the user's first name.\n" + " is the user's last name.\n" + " is the path inside the user's inventory for the folder/item to be saved.\n" @@ -131,32 +131,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver + string.Format(" If this is not given then the filename {0} in the current directory is used.\n", DEFAULT_INV_BACKUP_FILENAME) + "-h|--home= adds the url of the profile service to the saved user information.\n" + "-c|--creators preserves information about foreign creators.\n" + + "-e|--exclude= don't save the inventory item in archive" + Environment.NewLine + + "-f|--excludefolder= don't save contents of the folder in archive" + Environment.NewLine + "-v|--verbose extra debug messages.\n" + "--noassets stops assets being saved to the IAR.", HandleSaveInvConsoleCommand); m_aScene = scene; } - + m_scenes[scene.RegionInfo.RegionID] = scene; } public void PostInitialise() {} public void Close() {} - + /// /// Trigger the inventory archive saved event. /// protected internal void TriggerInventoryArchiveSaved( - Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, + Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, Exception reportedException) { InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved; if (handlerInventoryArchiveSaved != null) handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException); } - + public bool ArchiveInventory( Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream) { @@ -164,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver } public bool ArchiveInventory( - Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream, + Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream, Dictionary options) { if (m_scenes.Count > 0) @@ -188,7 +190,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver return false; } - + return true; // } // else @@ -202,15 +204,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver return false; } - + public bool ArchiveInventory( - Guid id, string firstName, string lastName, string invPath, string pass, string savePath, + Guid id, string firstName, string lastName, string invPath, string pass, string savePath, Dictionary options) { if (m_scenes.Count > 0) { UserAccount userInfo = GetUserInfo(firstName, lastName, pass); - + if (userInfo != null) { // if (CheckPresence(userInfo.PrincipalID)) @@ -228,7 +230,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver return false; } - + return true; // } // else @@ -239,7 +241,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // } } } - + return false; } @@ -247,9 +249,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary()); } - + public bool DearchiveInventory( - string firstName, string lastName, string invPath, string pass, Stream loadStream, + string firstName, string lastName, string invPath, string pass, Stream loadStream, Dictionary options) { if (m_scenes.Count > 0) @@ -295,22 +297,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver return false; } - + public bool DearchiveInventory( - string firstName, string lastName, string invPath, string pass, string loadPath, + string firstName, string lastName, string invPath, string pass, string loadPath, Dictionary options) { if (m_scenes.Count > 0) { UserAccount userInfo = GetUserInfo(firstName, lastName, pass); - + if (userInfo != null) { // if (CheckPresence(userInfo.PrincipalID)) // { InventoryArchiveReadRequest request; bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false); - + try { request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge); @@ -324,7 +326,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver return false; } - + UpdateClientWithLoadedNodes(userInfo, request.Execute()); return true; @@ -340,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver return false; } - + /// /// Load inventory from an inventory file archive /// @@ -351,26 +353,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { Dictionary options = new Dictionary(); OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; }); - + List mainParams = optionSet.Parse(cmdparams); - + if (mainParams.Count < 6) { m_log.Error( - "[INVENTORY ARCHIVER]: usage is load iar [-m|--merge] []"); + "[INVENTORY ARCHIVER]: usage is load iar [-m|--merge] []"); return; } - + string firstName = mainParams[2]; string lastName = mainParams[3]; string invPath = mainParams[4]; string pass = mainParams[5]; string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); - + m_log.InfoFormat( "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}", loadPath, invPath, firstName, lastName); - + if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options)) m_log.InfoFormat( "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}", @@ -381,7 +383,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); } } - + /// /// Save inventory to a file archive /// @@ -398,6 +400,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; }); ops.Add("c|creators", delegate(string v) { options["creators"] = v; }); ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); + ops.Add("e|exclude=", delegate(string v) + { + if (!options.ContainsKey("exclude")) + options["exclude"] = new List(); + ((List)options["exclude"]).Add(v); + }); + ops.Add("f|excludefolder=", delegate(string v) + { + if (!options.ContainsKey("excludefolders")) + options["excludefolders"] = new List(); + ((List)options["excludefolders"]).Add(v); + }); List mainParams = ops.Parse(cmdparams); @@ -406,10 +420,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver if (mainParams.Count < 6) { m_log.Error( - "[INVENTORY ARCHIVER]: usage is save iar [-h|--home=] [--noassets] [] [-c|--creators] [-v|--verbose]"); + "[INVENTORY ARCHIVER]: save iar [-h|--home=] [--noassets] [] [-c|--creators] [-e|--exclude=] [-f|--excludefolder=] [-v|--verbose]"); return; } - + if (options.ContainsKey("home")) m_log.WarnFormat("[INVENTORY ARCHIVER]: Please be aware that inventory archives with creator information are not compatible with OpenSim 0.7.0.2 and earlier. Do not use the -home option if you want to produce a compatible IAR"); @@ -418,7 +432,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver string invPath = mainParams[4]; string pass = mainParams[5]; string savePath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); - + m_log.InfoFormat( "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", savePath, invPath, firstName, lastName); @@ -433,9 +447,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); } } - + private void SaveInvConsoleCommandCompleted( - Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, + Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, Exception reportedException) { lock (m_pendingConsoleSaves) @@ -445,7 +459,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver else return; } - + if (succeeded) { m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive for {0} {1}", userInfo.FirstName, userInfo.LastName); @@ -453,11 +467,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver else { m_log.ErrorFormat( - "[INVENTORY ARCHIVER]: Archive save for {0} {1} failed - {2}", + "[INVENTORY ARCHIVER]: Archive save for {0} {1} failed - {2}", userInfo.FirstName, userInfo.LastName, reportedException.Message); } } - + /// /// Get user information for the given name. /// @@ -467,13 +481,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// protected UserAccount GetUserInfo(string firstName, string lastName, string pass) { - UserAccount account + UserAccount account = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, firstName, lastName); - + if (null == account) { m_log.ErrorFormat( - "[INVENTORY ARCHIVER]: Failed to find user info for {0} {1}", + "[INVENTORY ARCHIVER]: Failed to find user info for {0} {1}", firstName, lastName); return null; } @@ -488,7 +502,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver else { m_log.ErrorFormat( - "[INVENTORY ARCHIVER]: Password for user {0} {1} incorrect. Please try again.", + "[INVENTORY ARCHIVER]: Password for user {0} {1} incorrect. Please try again.", firstName, lastName); return null; } @@ -499,7 +513,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver return null; } } - + /// /// Notify the client of loaded nodes if they are logged in /// @@ -508,22 +522,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { if (loadedNodes.Count == 0) return; - + foreach (Scene scene in m_scenes.Values) { ScenePresence user = scene.GetScenePresence(userInfo.PrincipalID); - + if (user != null && !user.IsChildAgent) { foreach (InventoryNodeBase node in loadedNodes) { // m_log.DebugFormat( -// "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}", +// "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}", // user.Name, node.Name); - + user.ControllingClient.SendBulkUpdateInventory(node); } - + break; } } @@ -538,7 +552,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // { // if (DisablePresenceChecks) // return true; -// +// // foreach (Scene scene in m_scenes.Values) // { // ScenePresence p; -- cgit v1.1 From eeec1f32c6a8396b7714fc7448e56c4d4cc9b3ba Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 14 Apr 2012 01:01:28 +0100 Subject: Add very basic TestGetRootPartPosition() test --- .../Scenes/Tests/SceneObjectSpatialTests.cs | 65 ++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs new file mode 100644 index 0000000..10c78b5 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs @@ -0,0 +1,65 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using System.Threading; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.Framework.Scenes.Tests +{ + /// + /// Spatial scene object tests (will eventually cover root and child part position, rotation properties, etc.) + /// + [TestFixture] + public class SceneObjectSpatialTests + { + [Test] + public void TestGetRootPartPosition() + { + TestHelpers.InMethod(); + + Scene scene = SceneHelpers.SetupScene(); + UUID ownerId = TestHelpers.ParseTail(0x1); + Vector3 partPosition = new Vector3(10, 20, 30); + + SceneObjectGroup so + = SceneHelpers.CreateSceneObject(1, ownerId, "obj1", 0x10); + so.AbsolutePosition = partPosition; + scene.AddNewSceneObject(so, false); + + Assert.That(so.AbsolutePosition, Is.EqualTo(partPosition)); + Assert.That(so.RootPart.AbsolutePosition, Is.EqualTo(partPosition)); + } + } +} \ No newline at end of file -- cgit v1.1 From 4bdd9d51bc0ccfa5b15a6e77228f69dafada03b7 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 14 Apr 2012 01:04:26 +0100 Subject: Correct whitespace error introduced by previous commit --- OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 11b21d4..69df392 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -148,7 +148,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Rotation llGetLocalRot(); LSL_Float llGetMass(); LSL_Integer llGetMemoryLimit(); - void llGetNextEmail(string address, string subject); + void llGetNextEmail(string address, string subject); LSL_String llGetNotecardLine(string name, int line); LSL_Key llGetNumberOfNotecardLines(string name); LSL_Integer llGetNumberOfPrims(); -- cgit v1.1 From 4d652c704186e9e399ffc6fc1bdf1f1dca056370 Mon Sep 17 00:00:00 2001 From: Talun Date: Sat, 14 Apr 2012 00:37:55 +0100 Subject: Missing or unimplemented LSL memory functions. Implemented to behave as if scripts were LSO. Signed-off-by: nebadon --- .../Shared/Api/Implementation/LSL_Api.cs | 40 +++++++++++++++------- .../ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | 7 +++- .../Shared/Api/Runtime/LSL_Constants.cs | 3 ++ .../ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs | 25 ++++++++++++++ 4 files changed, 62 insertions(+), 13 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 078a22a..a19427d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10949,34 +10949,50 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return 1; } - #region Not Implemented - // - // Listing the unimplemented lsl functions here, please move - // them from this region as they are completed - // + public LSL_Integer llGetMemoryLimit() + { + m_host.AddScriptLPS(1); + // The value returned for LSO scripts in SL + return 16384; + } - public void llGetEnv(LSL_String name) + public LSL_Integer llSetMemoryLimit(LSL_Integer limit) { m_host.AddScriptLPS(1); - NotImplemented("llGetEnv"); + // Treat as an LSO script + return ScriptBaseClass.FALSE; } - public void llGetSPMaxMemory() + public LSL_Integer llGetSPMaxMemory() { m_host.AddScriptLPS(1); - NotImplemented("llGetSPMaxMemory"); + // The value returned for LSO scripts in SL + return 16384; } - public void llGetUsedMemory() + public LSL_Integer llGetUsedMemory() { m_host.AddScriptLPS(1); - NotImplemented("llGetUsedMemory"); + // The value returned for LSO scripts in SL + return 16384; } public void llScriptProfiler(LSL_Integer flags) { m_host.AddScriptLPS(1); - NotImplemented("llScriptProfiler"); + // This does nothing for LSO scripts in SL + } + + #region Not Implemented + // + // Listing the unimplemented lsl functions here, please move + // them from this region as they are completed + // + + public void llGetEnv(LSL_String name) + { + m_host.AddScriptLPS(1); + NotImplemented("llGetEnv"); } public void llSetSoundQueueing(int queue) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 0f53bc3..11b21d4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -147,7 +147,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Vector llGetLocalPos(); LSL_Rotation llGetLocalRot(); LSL_Float llGetMass(); - void llGetNextEmail(string address, string subject); + LSL_Integer llGetMemoryLimit(); + void llGetNextEmail(string address, string subject); LSL_String llGetNotecardLine(string name, int line); LSL_Key llGetNumberOfNotecardLines(string name); LSL_Integer llGetNumberOfPrims(); @@ -185,6 +186,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_String llGetScriptName(); LSL_Integer llGetScriptState(string name); LSL_String llGetSimulatorHostname(); + LSL_Integer llGetSPMaxMemory(); LSL_Integer llGetStartParameter(); LSL_Integer llGetStatus(int status); LSL_String llGetSubString(string src, int start, int end); @@ -198,6 +200,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_String llGetTimestamp(); LSL_Vector llGetTorque(); LSL_Integer llGetUnixTime(); + LSL_Integer llGetUsedMemory(); LSL_Vector llGetVel(); LSL_Float llGetWallclock(); void llGiveInventory(string destination, string inventory); @@ -319,6 +322,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llSay(int channelID, string text); void llScaleTexture(double u, double v, int face); LSL_Integer llScriptDanger(LSL_Vector pos); + void llScriptProfiler(LSL_Integer flag); LSL_Key llSendRemoteData(string channel, string dest, int idata, string sdata); void llSensor(string name, string id, int type, double range, double arc); void llSensorRemove(); @@ -342,6 +346,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llSetLinkTexture(int linknumber, string texture, int face); void llSetLinkTextureAnim(int linknum, int mode, int face, int sizex, int sizey, double start, double length, double rate); void llSetLocalRot(LSL_Rotation rot); + LSL_Integer llSetMemoryLimit(LSL_Integer limit); void llSetObjectDesc(string desc); void llSetObjectName(string name); void llSetObjectPermMask(int mask, int value); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index f58f9d6..fd7c41e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -381,6 +381,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int PRIM_SCULPT_FLAG_INVERT = 64; public const int PRIM_SCULPT_FLAG_MIRROR = 128; + public const int PROFILE_NONE = 0; + public const int PROFILE_SCRIPT_MEMORY = 1; + public const int MASK_BASE = 0; public const int MASK_OWNER = 1; public const int MASK_GROUP = 2; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index f8e3c36..3c2f7bd 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -569,6 +569,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_LSL_Functions.llGetMass(); } + public LSL_Integer llGetMemoryLimit() + { + return m_LSL_Functions.llGetMemoryLimit(); + } + public void llGetNextEmail(string address, string subject) { m_LSL_Functions.llGetNextEmail(address, subject); @@ -759,6 +764,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_LSL_Functions.llGetSimulatorHostname(); } + public LSL_Integer llGetSPMaxMemory() + { + return m_LSL_Functions.llGetSPMaxMemory(); + } + public LSL_Integer llGetStartParameter() { return m_LSL_Functions.llGetStartParameter(); @@ -824,6 +834,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_LSL_Functions.llGetUnixTime(); } + public LSL_Integer llGetUsedMemory() + { + return m_LSL_Functions.llGetUsedMemory(); + } + public LSL_Vector llGetVel() { return m_LSL_Functions.llGetVel(); @@ -1423,6 +1438,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_LSL_Functions.llScriptDanger(pos); } + public void llScriptProfiler(LSL_Integer flags) + { + m_LSL_Functions.llScriptProfiler(flags); + } + public LSL_Key llSendRemoteData(string channel, string dest, int idata, string sdata) { return m_LSL_Functions.llSendRemoteData(channel, dest, idata, sdata); @@ -1533,6 +1553,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llSetLocalRot(rot); } + public LSL_Integer llSetMemoryLimit(LSL_Integer limit) + { + return m_LSL_Functions.llSetMemoryLimit(limit); + } + public void llSetObjectDesc(string desc) { m_LSL_Functions.llSetObjectDesc(desc); -- cgit v1.1 From 2254a718c83df18746be1c9ccfad48928eb48cb3 Mon Sep 17 00:00:00 2001 From: nebadon Date: Fri, 13 Apr 2012 17:09:23 -0700 Subject: Add Talun to the CONTRIBUTORS.txt, Thank you for the great patches Talun --- CONTRIBUTORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 287073b..1370449 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -144,6 +144,7 @@ what it is today. * SignpostMarv * SpotOn3D * Strawberry Fride +* Talun * tglion * tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud) * tyre -- cgit v1.1 From 3ae98611f2efd7c8fb7acc172f9252241dd5c918 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 14 Apr 2012 01:43:03 +0100 Subject: Add simple RelativePosition and OffsetPosition checks to TestGetRootPartPosition --- OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs index 10c78b5..19526c0 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs @@ -60,6 +60,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(so.AbsolutePosition, Is.EqualTo(partPosition)); Assert.That(so.RootPart.AbsolutePosition, Is.EqualTo(partPosition)); + Assert.That(so.RootPart.OffsetPosition, Is.EqualTo(Vector3.Zero)); + Assert.That(so.RootPart.RelativePosition, Is.EqualTo(partPosition)); } } } \ No newline at end of file -- cgit v1.1 From 317aebcce6618cacbe3afd831c3e100b96665be2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 14 Apr 2012 01:47:56 +0100 Subject: refactor: put SOG position test in a separate TestSceneObjectGroupPosition() --- .../Framework/Scenes/Tests/SceneObjectSpatialTests.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs index 19526c0..3509de1 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs @@ -45,6 +45,23 @@ namespace OpenSim.Region.Framework.Scenes.Tests public class SceneObjectSpatialTests { [Test] + public void TestSceneObjectGroupPosition() + { + TestHelpers.InMethod(); + + Scene scene = SceneHelpers.SetupScene(); + UUID ownerId = TestHelpers.ParseTail(0x1); + Vector3 position = new Vector3(10, 20, 30); + + SceneObjectGroup so + = SceneHelpers.CreateSceneObject(1, ownerId, "obj1", 0x10); + so.AbsolutePosition = position; + scene.AddNewSceneObject(so, false); + + Assert.That(so.AbsolutePosition, Is.EqualTo(position)); + } + + [Test] public void TestGetRootPartPosition() { TestHelpers.InMethod(); @@ -58,7 +75,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests so.AbsolutePosition = partPosition; scene.AddNewSceneObject(so, false); - Assert.That(so.AbsolutePosition, Is.EqualTo(partPosition)); Assert.That(so.RootPart.AbsolutePosition, Is.EqualTo(partPosition)); Assert.That(so.RootPart.OffsetPosition, Is.EqualTo(Vector3.Zero)); Assert.That(so.RootPart.RelativePosition, Is.EqualTo(partPosition)); -- cgit v1.1 From f61b2342524023b89725e3473b8332fe6a8e71ca Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 14 Apr 2012 01:52:16 +0100 Subject: refactor: move common init code into SetUp() in SceneObjectSpatialTests --- .../Scenes/Tests/SceneObjectSpatialTests.cs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs index 3509de1..69b5b1f 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs @@ -44,19 +44,26 @@ namespace OpenSim.Region.Framework.Scenes.Tests [TestFixture] public class SceneObjectSpatialTests { + TestScene m_scene; + UUID m_ownerId = TestHelpers.ParseTail(0x1); + + [SetUp] + public void SetUp() + { + m_scene = SceneHelpers.SetupScene(); + } + [Test] public void TestSceneObjectGroupPosition() { TestHelpers.InMethod(); - Scene scene = SceneHelpers.SetupScene(); - UUID ownerId = TestHelpers.ParseTail(0x1); Vector3 position = new Vector3(10, 20, 30); SceneObjectGroup so - = SceneHelpers.CreateSceneObject(1, ownerId, "obj1", 0x10); + = SceneHelpers.CreateSceneObject(1, m_ownerId, "obj1", 0x10); so.AbsolutePosition = position; - scene.AddNewSceneObject(so, false); + m_scene.AddNewSceneObject(so, false); Assert.That(so.AbsolutePosition, Is.EqualTo(position)); } @@ -66,14 +73,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests { TestHelpers.InMethod(); - Scene scene = SceneHelpers.SetupScene(); - UUID ownerId = TestHelpers.ParseTail(0x1); Vector3 partPosition = new Vector3(10, 20, 30); SceneObjectGroup so - = SceneHelpers.CreateSceneObject(1, ownerId, "obj1", 0x10); + = SceneHelpers.CreateSceneObject(1, m_ownerId, "obj1", 0x10); so.AbsolutePosition = partPosition; - scene.AddNewSceneObject(so, false); + m_scene.AddNewSceneObject(so, false); Assert.That(so.RootPart.AbsolutePosition, Is.EqualTo(partPosition)); Assert.That(so.RootPart.OffsetPosition, Is.EqualTo(Vector3.Zero)); -- cgit v1.1 From da342d0b21b867061a3f3a502256331c609e1564 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 14 Apr 2012 01:53:40 +0100 Subject: minor: make test names consistent --- OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs index 69b5b1f..c38a22d 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs @@ -54,7 +54,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests } [Test] - public void TestSceneObjectGroupPosition() + public void TestGetSceneObjectGroupPosition() { TestHelpers.InMethod(); -- cgit v1.1 From 2c74e1bba8d93a1c3b95da913bc3de0aae6dca4a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 14 Apr 2012 01:57:09 +0100 Subject: Add GroupPosition and GetWorldPosition() checks to TestGetRootPartPosition() --- OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs index c38a22d..7a3b362 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs @@ -81,8 +81,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests m_scene.AddNewSceneObject(so, false); Assert.That(so.RootPart.AbsolutePosition, Is.EqualTo(partPosition)); - Assert.That(so.RootPart.OffsetPosition, Is.EqualTo(Vector3.Zero)); + Assert.That(so.RootPart.GroupPosition, Is.EqualTo(partPosition)); + Assert.That(so.RootPart.GetWorldPosition(), Is.EqualTo(partPosition)); Assert.That(so.RootPart.RelativePosition, Is.EqualTo(partPosition)); + Assert.That(so.RootPart.OffsetPosition, Is.EqualTo(Vector3.Zero)); } } } \ No newline at end of file -- cgit v1.1 From f213f55586b9af66955fdfccdd50237febaf98ca Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 17 Apr 2012 00:02:58 +0100 Subject: Fix bug in WebStatsModule where an exception would always be output on update if the user teleported to another region on that simulator. This was because update was looking for an existing stats record unique in session id, agent id and region id. But if the user teleports to another region then region id changes. WebStatsModule promptly doesn't find the existing record and tries to insert a new one, but only session id is the primary key and that's still the same, which makes things go bang. This makes the update search only on the unique session id. This is only an issue with simulators that have multiple regions where the webstats module is enabled. --- OpenSim/Region/UserStatistics/WebStatsModule.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index b9ba4bc..dbe9b3f 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -446,7 +446,7 @@ namespace OpenSim.Region.UserStatistics { // m_log.DebugFormat("[WEB STATS MODULE]: Received viewer starts report from {0}", agentID); - UpdateUserStats(ParseViewerStats(request,agentID), dbConn); + UpdateUserStats(ParseViewerStats(request, agentID), dbConn); return String.Empty; } @@ -654,8 +654,6 @@ namespace OpenSim.Region.UserStatistics updatecmd.Parameters.Add(new SqliteParameter(":f_send_packet", uid.session_data.f_send_packet)); updatecmd.Parameters.Add(new SqliteParameter(":session_key", uid.session_data.session_id.ToString())); - updatecmd.Parameters.Add(new SqliteParameter(":agent_key", uid.session_data.agent_id.ToString())); - updatecmd.Parameters.Add(new SqliteParameter(":region_key", uid.session_data.region_id.ToString())); // m_log.DebugFormat("[WEB STATS MODULE]: Database stats update for {0}", uid.session_data.agent_id); @@ -667,11 +665,18 @@ namespace OpenSim.Region.UserStatistics updatecmd.CommandText = SQL_STATS_TABLE_INSERT; +// StringBuilder parameters = new StringBuilder(); +// SqliteParameterCollection spc = updatecmd.Parameters; +// foreach (SqliteParameter sp in spc) +// parameters.AppendFormat("{0}={1},", sp.ParameterName, sp.Value); +// +// m_log.DebugFormat("[WEB STATS MODULE]: Parameters {0}", parameters); + try { updatecmd.ExecuteNonQuery(); } - catch (Exception e) + catch (SqliteExecutionException e) { m_log.WarnFormat( "[WEB STATS MODULE]: failed to write stats for {0}, storage Execution Exception {1}{2}", @@ -801,7 +806,7 @@ set session_id=:session_id, f_off_circuit=:f_off_circuit, f_resent=:f_resent, f_send_packet=:f_send_packet -WHERE session_id=:session_key AND agent_id=:agent_key AND region_id=:region_key"; +WHERE session_id=:session_key"; #endregion } -- cgit v1.1 From 1bb387333868e223c90519d18fa18b84bd1a4324 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 17 Apr 2012 00:19:36 +0100 Subject: Simplify WebStatsModule by removing the uncompleted migrations section. Use "create table if not exists" instead. Client stats data is transitory data that it is not worth migrating. --- OpenSim/Region/UserStatistics/WebStatsModule.cs | 32 +++---------------------- 1 file changed, 3 insertions(+), 29 deletions(-) diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index dbe9b3f..e593ecd 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -90,7 +90,7 @@ namespace OpenSim.Region.UserStatistics dbConn = new SqliteConnection("URI=file:LocalUserStatistics.db,version=3"); dbConn.Open(); - CheckAndUpdateDatabase(dbConn); + CreateTables(dbConn); Prototype_distributor protodep = new Prototype_distributor(); Updater_distributor updatedep = new Updater_distributor(); @@ -237,36 +237,12 @@ namespace OpenSim.Region.UserStatistics return responsedata; } - - public void CheckAndUpdateDatabase(SqliteConnection db) - { - lock (db) - { - // TODO: FIXME: implement stats migrations - const string SQL = @"SELECT * FROM migrations LIMIT 1"; - - using (SqliteCommand cmd = new SqliteCommand(SQL, db)) - { - try - { - cmd.ExecuteNonQuery(); - } - catch (SqliteSyntaxException) - { - CreateTables(db); - } - } - } - } public void CreateTables(SqliteConnection db) { using (SqliteCommand createcmd = new SqliteCommand(SQL_STATS_TABLE_CREATE, db)) { createcmd.ExecuteNonQuery(); - - createcmd.CommandText = SQL_MIGRA_TABLE_CREATE; - createcmd.ExecuteNonQuery(); } } @@ -688,9 +664,7 @@ namespace OpenSim.Region.UserStatistics } #region SQL - private const string SQL_MIGRA_TABLE_CREATE = @"create table migrations(name varchar(100), version int)"; - - private const string SQL_STATS_TABLE_CREATE = @"CREATE TABLE stats_session_data ( + private const string SQL_STATS_TABLE_CREATE = @"CREATE TABLE IF NOT EXISTS stats_session_data ( session_id VARCHAR(36) NOT NULL PRIMARY KEY, agent_id VARCHAR(36) NOT NULL DEFAULT '', region_id VARCHAR(36) NOT NULL DEFAULT '', @@ -807,8 +781,8 @@ set session_id=:session_id, f_resent=:f_resent, f_send_packet=:f_send_packet WHERE session_id=:session_key"; - #endregion } + #endregion public static class UserSessionUtil { -- cgit v1.1 From 572440cd23cdd5737979a2140b9d782b836fb952 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 17 Apr 2012 00:33:23 +0100 Subject: correct bug where f_invalid was being inserted on a webstats update for an existing session rather than d_world_kb --- OpenSim/Region/UserStatistics/WebStatsModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index e593ecd..cc041d1 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -718,7 +718,7 @@ namespace OpenSim.Region.UserStatistics session_id, agent_id, region_id, last_updated, remote_ip, name_f, name_l, avg_agents_in_view, min_agents_in_view, max_agents_in_view, mode_agents_in_view, avg_fps, min_fps, max_fps, mode_fps, a_language, mem_use, meters_traveled, avg_ping, min_ping, max_ping, mode_ping, regions_visited, run_time, avg_sim_fps, min_sim_fps, max_sim_fps, mode_sim_fps, start_time, client_version, s_cpu, s_gpu, s_os, s_ram, -d_object_kb, d_texture_kb, n_in_kb, n_in_pk, n_out_kb, n_out_pk, f_dropped, f_failed_resends, f_invalid, f_invalid, f_off_circuit, +d_object_kb, d_texture_kb, d_world_kb, n_in_kb, n_in_pk, n_out_kb, n_out_pk, f_dropped, f_failed_resends, f_invalid, f_off_circuit, f_resent, f_send_packet ) VALUES @@ -726,7 +726,7 @@ VALUES :session_id, :agent_id, :region_id, :last_updated, :remote_ip, :name_f, :name_l, :avg_agents_in_view, :min_agents_in_view, :max_agents_in_view, :mode_agents_in_view, :avg_fps, :min_fps, :max_fps, :mode_fps, :a_language, :mem_use, :meters_traveled, :avg_ping, :min_ping, :max_ping, :mode_ping, :regions_visited, :run_time, :avg_sim_fps, :min_sim_fps, :max_sim_fps, :mode_sim_fps, :start_time, :client_version, :s_cpu, :s_gpu, :s_os, :s_ram, -:d_object_kb, :d_texture_kb, :n_in_kb, :n_in_pk, :n_out_kb, :n_out_pk, :f_dropped, :f_failed_resends, :f_invalid, :f_invalid, :f_off_circuit, +:d_object_kb, :d_texture_kb, :d_world_kb, :n_in_kb, :n_in_pk, :n_out_kb, :n_out_pk, :f_dropped, :f_failed_resends, :f_invalid, :f_off_circuit, :f_resent, :f_send_packet ) "; -- cgit v1.1 From e6ec83125b9d77db833e18bbbdb396a31fb7b871 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 17 Apr 2012 00:46:43 +0100 Subject: Use INSERT OR REPLACE INTO sql in WebStatsModule for session update rather than separate insert and update statements --- OpenSim/Region/UserStatistics/WebStatsModule.cs | 84 +++---------------------- 1 file changed, 7 insertions(+), 77 deletions(-) diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index cc041d1..a00955a 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -575,7 +575,7 @@ namespace OpenSim.Region.UserStatistics lock (db) { - using (SqliteCommand updatecmd = new SqliteCommand(SQL_STATS_TABLE_UPDATE, db)) + using (SqliteCommand updatecmd = new SqliteCommand(SQL_STATS_TABLE_INSERT, db)) { updatecmd.Parameters.Add(new SqliteParameter(":session_id", uid.session_data.session_id.ToString())); updatecmd.Parameters.Add(new SqliteParameter(":agent_id", uid.session_data.agent_id.ToString())); @@ -624,22 +624,9 @@ namespace OpenSim.Region.UserStatistics updatecmd.Parameters.Add(new SqliteParameter(":f_dropped", uid.session_data.f_dropped)); updatecmd.Parameters.Add(new SqliteParameter(":f_failed_resends", uid.session_data.f_failed_resends)); updatecmd.Parameters.Add(new SqliteParameter(":f_invalid", uid.session_data.f_invalid)); - updatecmd.Parameters.Add(new SqliteParameter(":f_off_circuit", uid.session_data.f_off_circuit)); updatecmd.Parameters.Add(new SqliteParameter(":f_resent", uid.session_data.f_resent)); updatecmd.Parameters.Add(new SqliteParameter(":f_send_packet", uid.session_data.f_send_packet)); - - updatecmd.Parameters.Add(new SqliteParameter(":session_key", uid.session_data.session_id.ToString())); - -// m_log.DebugFormat("[WEB STATS MODULE]: Database stats update for {0}", uid.session_data.agent_id); - - int result = updatecmd.ExecuteNonQuery(); - - if (result == 0) - { -// m_log.DebugFormat("[WEB STATS MODULE]: Database stats insert for {0}", uid.session_data.agent_id); - - updatecmd.CommandText = SQL_STATS_TABLE_INSERT; // StringBuilder parameters = new StringBuilder(); // SqliteParameterCollection spc = updatecmd.Parameters; @@ -648,17 +635,9 @@ namespace OpenSim.Region.UserStatistics // // m_log.DebugFormat("[WEB STATS MODULE]: Parameters {0}", parameters); - try - { - updatecmd.ExecuteNonQuery(); - } - catch (SqliteExecutionException e) - { - m_log.WarnFormat( - "[WEB STATS MODULE]: failed to write stats for {0}, storage Execution Exception {1}{2}", - uid.session_data.agent_id, e.Message, e.StackTrace); - } - } +// m_log.DebugFormat("[WEB STATS MODULE]: Database stats update for {0}", uid.session_data.agent_id); + + updatecmd.ExecuteNonQuery(); } } } @@ -714,7 +693,7 @@ namespace OpenSim.Region.UserStatistics f_send_packet INT NOT NULL DEFAULT '0' );"; - private const string SQL_STATS_TABLE_INSERT = @"INSERT INTO stats_session_data ( + private const string SQL_STATS_TABLE_INSERT = @"INSERT OR REPLACE INTO stats_session_data ( session_id, agent_id, region_id, last_updated, remote_ip, name_f, name_l, avg_agents_in_view, min_agents_in_view, max_agents_in_view, mode_agents_in_view, avg_fps, min_fps, max_fps, mode_fps, a_language, mem_use, meters_traveled, avg_ping, min_ping, max_ping, mode_ping, regions_visited, run_time, avg_sim_fps, min_sim_fps, max_sim_fps, mode_sim_fps, start_time, client_version, s_cpu, s_gpu, s_os, s_ram, @@ -731,59 +710,10 @@ VALUES ) "; - private const string SQL_STATS_TABLE_UPDATE = @" -UPDATE stats_session_data -set session_id=:session_id, - agent_id=:agent_id, - region_id=:region_id, - last_updated=:last_updated, - remote_ip=:remote_ip, - name_f=:name_f, - name_l=:name_l, - avg_agents_in_view=:avg_agents_in_view, - min_agents_in_view=:min_agents_in_view, - max_agents_in_view=:max_agents_in_view, - mode_agents_in_view=:mode_agents_in_view, - avg_fps=:avg_fps, - min_fps=:min_fps, - max_fps=:max_fps, - mode_fps=:mode_fps, - a_language=:a_language, - mem_use=:mem_use, - meters_traveled=:meters_traveled, - avg_ping=:avg_ping, - min_ping=:min_ping, - max_ping=:max_ping, - mode_ping=:mode_ping, - regions_visited=:regions_visited, - run_time=:run_time, - avg_sim_fps=:avg_sim_fps, - min_sim_fps=:min_sim_fps, - max_sim_fps=:max_sim_fps, - mode_sim_fps=:mode_sim_fps, - start_time=:start_time, - client_version=:client_version, - s_cpu=:s_cpu, - s_gpu=:s_gpu, - s_os=:s_os, - s_ram=:s_ram, - d_object_kb=:d_object_kb, - d_texture_kb=:d_texture_kb, - d_world_kb=:d_world_kb, - n_in_kb=:n_in_kb, - n_in_pk=:n_in_pk, - n_out_kb=:n_out_kb, - n_out_pk=:n_out_pk, - f_dropped=:f_dropped, - f_failed_resends=:f_failed_resends, - f_invalid=:f_invalid, - f_off_circuit=:f_off_circuit, - f_resent=:f_resent, - f_send_packet=:f_send_packet -WHERE session_id=:session_key"; - } #endregion + } + public static class UserSessionUtil { public static UserSessionData newUserSessionData() -- cgit v1.1 From 5655239f440dce36cdf9288db70be567aef2d565 Mon Sep 17 00:00:00 2001 From: Talun Date: Mon, 16 Apr 2012 20:24:56 +0100 Subject: Null reference in llGetObjectMass on a seated avatar. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a19427d..5581727 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9255,7 +9255,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // child agents have a mass of 1.0 return 1; else - return (double)avatar.PhysicsActor.Mass; + return (double)avatar.GetMass(); } catch (KeyNotFoundException) { -- cgit v1.1 From 24a0cc5261f1fd1a1d8779c8fb5e7d7fba98ed68 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 17 Apr 2012 01:25:41 +0100 Subject: refactor: Rename EstateSettings.IsEstateManager() to EstateSettings.IsEstateManagerOrOwner() to reflect what it actually does. This makes it consistent with other parts of OpenSimulator that are treating ESTATE_MANAGER and ESTATE_OWNER as different entities. As per opensim-dev mailing list. --- OpenSim/Framework/EstateSettings.cs | 4 ++-- OpenSim/Framework/Tests/MundaneFrameworkTests.cs | 4 ++-- OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | 2 +- OpenSim/Region/CoreModules/World/Land/LandObject.cs | 4 ++-- OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 +++--- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs | 6 +++--- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/OpenSim/Framework/EstateSettings.cs b/OpenSim/Framework/EstateSettings.cs index 98604f2..a92abbf 100644 --- a/OpenSim/Framework/EstateSettings.cs +++ b/OpenSim/Framework/EstateSettings.cs @@ -322,7 +322,7 @@ namespace OpenSim.Framework l_EstateManagers.Remove(avatarID); } - public bool IsEstateManager(UUID avatarID) + public bool IsEstateManagerOrOwner(UUID avatarID) { if (IsEstateOwner(avatarID)) return true; @@ -368,7 +368,7 @@ namespace OpenSim.Framework public bool HasAccess(UUID user) { - if (IsEstateManager(user)) + if (IsEstateManagerOrOwner(user)) return true; return l_EstateAccess.Contains(user); diff --git a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs index 76de6be..672847d 100644 --- a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs +++ b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs @@ -227,10 +227,10 @@ namespace OpenSim.Framework.Tests es.AddEstateManager(UUID.Zero); es.AddEstateManager(bannedUserId); - Assert.IsTrue(es.IsEstateManager(bannedUserId), "bannedUserId should be EstateManager but isn't."); + Assert.IsTrue(es.IsEstateManagerOrOwner(bannedUserId), "bannedUserId should be EstateManager but isn't."); es.RemoveEstateManager(bannedUserId); - Assert.IsFalse(es.IsEstateManager(bannedUserId), "bannedUserID is estateManager but shouldn't be"); + Assert.IsFalse(es.IsEstateManagerOrOwner(bannedUserId), "bannedUserID is estateManager but shouldn't be"); Assert.IsFalse(es.HasAccess(bannedUserId), "bannedUserID has access but shouldn't"); diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 124f01c..58bbd24 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -967,7 +967,7 @@ namespace OpenSim.Region.CoreModules.World.Estate { RegionHandshakeArgs args = new RegionHandshakeArgs(); - args.isEstateManager = Scene.RegionInfo.EstateSettings.IsEstateManager(remoteClient.AgentId); + args.isEstateManager = Scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(remoteClient.AgentId); if (Scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero && Scene.RegionInfo.EstateSettings.EstateOwner == remoteClient.AgentId) args.isEstateManager = true; diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 7f44613..0536f6e 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -469,7 +469,7 @@ namespace OpenSim.Region.CoreModules.World.Land if (m_scene.Permissions.IsAdministrator(avatar)) return false; - if (m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar)) + if (m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(avatar)) return false; if (avatar == LandData.OwnerID) @@ -499,7 +499,7 @@ namespace OpenSim.Region.CoreModules.World.Land if (m_scene.Permissions.IsAdministrator(avatar)) return false; - if (m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar)) + if (m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(avatar)) return false; if (avatar == LandData.OwnerID) diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 64759a7..2032905 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -503,7 +503,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions { if (user == UUID.Zero) return false; - return m_scene.RegionInfo.EstateSettings.IsEstateManager(user); + return m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(user); } #endregion diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 641d742..b5f789b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3832,7 +3832,7 @@ namespace OpenSim.Region.Framework.Scenes land.LandData.UserLocation != Vector3.Zero && land.LandData.OwnerID != m_uuid && (!m_scene.Permissions.IsGod(m_uuid)) && - (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) + (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid))) { float curr = Vector3.Distance(AbsolutePosition, pos); if (Vector3.Distance(land.LandData.UserLocation, pos) < curr) @@ -3852,7 +3852,7 @@ namespace OpenSim.Region.Framework.Scenes { if (GodLevel < 200 && ((!m_scene.Permissions.IsGod(m_uuid) && - !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || + !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) { @@ -3920,7 +3920,7 @@ namespace OpenSim.Region.Framework.Scenes GodLevel < 200 && ((land.LandData.OwnerID != m_uuid && !m_scene.Permissions.IsGod(m_uuid) && - !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || + !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 5581727..36c9d5e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10887,7 +10887,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api bool isAccount = false; bool isGroup = false; - if (!estate.IsEstateOwner(m_host.OwnerID) || !estate.IsEstateManager(m_host.OwnerID)) + if (!estate.IsEstateOwner(m_host.OwnerID) || !estate.IsEstateManagerOrOwner(m_host.OwnerID)) return 0; UUID id = new UUID(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index 77a784d..df20126 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs @@ -449,7 +449,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSShoutError("LightShare functions are not enabled."); return 0; } - if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) + if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) { LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); return 0; @@ -477,7 +477,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSShoutError("LightShare functions are not enabled."); return; } - if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) + if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) { LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); return; @@ -500,7 +500,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSShoutError("LightShare functions are not enabled."); return 0; } - if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) + if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) { LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners."); return 0; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 2680ad0..fe94b79 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -369,7 +369,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("ESTATE_MANAGER")) { //Only Estate Managers may use the function - if (World.RegionInfo.EstateSettings.IsEstateManager(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID) + if (World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID) { return; } -- cgit v1.1 From 7e1ab216e3c8b7ade3f007d352451c9d9d742b5c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 17 Apr 2012 01:33:55 +0100 Subject: Move some public methods on WebStatsModule to private to reduce some static analysis complexity. There's no obvious reason for these methods to be public. --- OpenSim/Region/UserStatistics/WebStatsModule.cs | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index a00955a..4248035 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -131,7 +131,7 @@ namespace OpenSim.Region.UserStatistics } } - public void ReceiveClassicSimStatsPacket(SimStats stats) + private void ReceiveClassicSimStatsPacket(SimStats stats) { if (!enabled) { @@ -163,7 +163,7 @@ namespace OpenSim.Region.UserStatistics } } - public Hashtable HandleUnknownCAPSRequest(Hashtable request) + private Hashtable HandleUnknownCAPSRequest(Hashtable request) { //string regpath = request["uri"].ToString(); int response_code = 200; @@ -178,7 +178,7 @@ namespace OpenSim.Region.UserStatistics return responsedata; } - public Hashtable HandleStatsRequest(Hashtable request) + private Hashtable HandleStatsRequest(Hashtable request) { lastHit = System.Environment.TickCount; Hashtable responsedata = new Hashtable(); @@ -238,7 +238,7 @@ namespace OpenSim.Region.UserStatistics return responsedata; } - public void CreateTables(SqliteConnection db) + private void CreateTables(SqliteConnection db) { using (SqliteCommand createcmd = new SqliteCommand(SQL_STATS_TABLE_CREATE, db)) { @@ -277,7 +277,7 @@ namespace OpenSim.Region.UserStatistics get { return true; } } - public void OnRegisterCaps(UUID agentID, Caps caps) + private void OnRegisterCaps(UUID agentID, Caps caps) { // m_log.DebugFormat("[WEB STATS MODULE]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps); @@ -292,7 +292,7 @@ namespace OpenSim.Region.UserStatistics })); } - public void OnDeRegisterCaps(UUID agentID, Caps caps) + private void OnDeRegisterCaps(UUID agentID, Caps caps) { } @@ -312,7 +312,7 @@ namespace OpenSim.Region.UserStatistics } } - public void OnMakeRootAgent(ScenePresence agent) + private void OnMakeRootAgent(ScenePresence agent) { UUID regionUUID = GetRegionUUIDFromHandle(agent.RegionHandle); @@ -341,11 +341,11 @@ namespace OpenSim.Region.UserStatistics } } - public void OnMakeChildAgent(ScenePresence agent) + private void OnMakeChildAgent(ScenePresence agent) { } - public void OnClientClosed(UUID agentID, Scene scene) + private void OnClientClosed(UUID agentID, Scene scene) { lock (m_sessions) { @@ -356,7 +356,7 @@ namespace OpenSim.Region.UserStatistics } } - public string readLogLines(int amount) + private string readLogLines(int amount) { Encoding encoding = Encoding.ASCII; int sizeOfChar = encoding.GetByteCount("\n"); @@ -394,7 +394,7 @@ namespace OpenSim.Region.UserStatistics return encoding.GetString(buffer); } - public UUID GetRegionUUIDFromHandle(ulong regionhandle) + private UUID GetRegionUUIDFromHandle(ulong regionhandle) { lock (m_scenes) { @@ -417,7 +417,7 @@ namespace OpenSim.Region.UserStatistics /// /// /// - public string ViewerStatsReport(string request, string path, string param, + private string ViewerStatsReport(string request, string path, string param, UUID agentID, Caps caps) { // m_log.DebugFormat("[WEB STATS MODULE]: Received viewer starts report from {0}", agentID); @@ -427,7 +427,7 @@ namespace OpenSim.Region.UserStatistics return String.Empty; } - public UserSessionID ParseViewerStats(string request, UUID agentID) + private UserSessionID ParseViewerStats(string request, UUID agentID) { UserSessionID uid = new UserSessionID(); UserSessionData usd; @@ -568,7 +568,7 @@ namespace OpenSim.Region.UserStatistics return uid; } - public void UpdateUserStats(UserSessionID uid, SqliteConnection db) + private void UpdateUserStats(UserSessionID uid, SqliteConnection db) { if (uid.session_id == UUID.Zero) return; -- cgit v1.1 From 2f2181683c9b3963da5e1cfd7fa1c6491d8a2ac0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 17 Apr 2012 01:51:13 +0100 Subject: Add test TestGetChildPartPosition() --- .../Scenes/Tests/SceneObjectSpatialTests.cs | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs index 7a3b362..fffa3bd 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs @@ -86,5 +86,33 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(so.RootPart.RelativePosition, Is.EqualTo(partPosition)); Assert.That(so.RootPart.OffsetPosition, Is.EqualTo(Vector3.Zero)); } + + [Test] + public void TestGetChildPartPosition() + { + TestHelpers.InMethod(); + + Vector3 rootPartPosition = new Vector3(10, 20, 30); + Vector3 childOffsetPosition = new Vector3(2, 3, 4); + + SceneObjectGroup so + = SceneHelpers.CreateSceneObject(2, m_ownerId, "obj1", 0x10); + so.AbsolutePosition = rootPartPosition; + so.Parts[1].OffsetPosition = childOffsetPosition; + + m_scene.AddNewSceneObject(so, false); + + // Calculate child absolute position. + Vector3 childPosition = new Vector3(rootPartPosition + childOffsetPosition); + + SceneObjectPart childPart = so.Parts[1]; + Assert.That(childPart.AbsolutePosition, Is.EqualTo(childPosition)); + Assert.That(childPart.GroupPosition, Is.EqualTo(rootPartPosition)); + Assert.That(childPart.GetWorldPosition(), Is.EqualTo(childPosition)); + Assert.That(childPart.RelativePosition, Is.EqualTo(childOffsetPosition)); + Assert.That(childPart.OffsetPosition, Is.EqualTo(childOffsetPosition)); + + // TODO: Write test for child part position after rotation. + } } } \ No newline at end of file -- cgit v1.1 From cca6b6bd0d679e817cbcb8b51de82577a15e2ff0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 17 Apr 2012 02:14:10 +0100 Subject: Add TestGetChildPartPositionAfterObjectRotation() --- .../Scenes/Tests/SceneObjectSpatialTests.cs | 38 +++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs index fffa3bd..9fea3c6 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs @@ -111,8 +111,44 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(childPart.GetWorldPosition(), Is.EqualTo(childPosition)); Assert.That(childPart.RelativePosition, Is.EqualTo(childOffsetPosition)); Assert.That(childPart.OffsetPosition, Is.EqualTo(childOffsetPosition)); + } + + [Test] + public void TestGetChildPartPositionAfterObjectRotation() + { + TestHelpers.InMethod(); + + Vector3 rootPartPosition = new Vector3(10, 20, 30); + Vector3 childOffsetPosition = new Vector3(2, 3, 4); + + SceneObjectGroup so + = SceneHelpers.CreateSceneObject(2, m_ownerId, "obj1", 0x10); + so.AbsolutePosition = rootPartPosition; + so.Parts[1].OffsetPosition = childOffsetPosition; + + m_scene.AddNewSceneObject(so, false); + + so.UpdateGroupRotationR(Quaternion.CreateFromEulers(0, 0, -90 * Utils.DEG_TO_RAD)); + + // Calculate child absolute position. + Vector3 rotatedChildOffsetPosition + = new Vector3(childOffsetPosition.Y, -childOffsetPosition.X, childOffsetPosition.Z); + + Vector3 childPosition = new Vector3(rootPartPosition + rotatedChildOffsetPosition); + + SceneObjectPart childPart = so.Parts[1]; - // TODO: Write test for child part position after rotation. + // FIXME: Should be childPosition after rotation? + Assert.That(childPart.AbsolutePosition, Is.EqualTo(rootPartPosition + childOffsetPosition)); + + Assert.That(childPart.GroupPosition, Is.EqualTo(rootPartPosition)); + Assert.That(childPart.GetWorldPosition(), Is.EqualTo(childPosition)); + + // Relative to root part as (0, 0, 0) + Assert.That(childPart.RelativePosition, Is.EqualTo(childOffsetPosition)); + + // Relative to root part as (0, 0, 0) + Assert.That(childPart.OffsetPosition, Is.EqualTo(childOffsetPosition)); } } } \ No newline at end of file -- cgit v1.1 From 4bb72c9ffef9a54a46b7059ba4785c939c791ac4 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Tue, 17 Apr 2012 13:45:03 -0700 Subject: make the namespace for the ScriptModuleComms consistent with its file system location --- .../Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index cab30de..74a85e2 100644 --- a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs @@ -38,7 +38,7 @@ using OpenMetaverse; using System.Linq; using System.Linq.Expressions; -namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms +namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")] class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms -- cgit v1.1 From 5ff2bda587a50b73f470ba778348645953b6b4b0 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Tue, 17 Apr 2012 13:45:27 -0700 Subject: This commit adds a new optional region module, JsonStore, that provides structured storage (dictionaries and arrays of string values) for scripts and region modules. In addition, there are operations on the storage that enable "real" distributed computation between scripts through operations similar to those of a tuple space. Scripts can share task queues, implement shared locks or semaphores, etc. The structured store is limited to the current region and is not currently persisted. However, script operations are defined to initialize a store from a notecard and to serialize the store to a notecard. Documentation will be posted to the opensim wiki soon. --- .../Framework/Interfaces/IJsonStoreModule.cs | 48 ++ .../Scripting/JsonStore/JsonStore.cs | 498 +++++++++++++++++++++ .../Scripting/JsonStore/JsonStoreModule.cs | 429 ++++++++++++++++++ .../Scripting/JsonStore/JsonStoreScriptModule.cs | 489 ++++++++++++++++++++ 4 files changed, 1464 insertions(+) create mode 100644 OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs create mode 100644 OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs create mode 100644 OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs create mode 100644 OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs diff --git a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs new file mode 100644 index 0000000..baac6e8 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs @@ -0,0 +1,48 @@ +/* + * Copyright (c) Contributors + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using OpenMetaverse; + +namespace OpenSim.Region.Framework.Interfaces +{ + public delegate void TakeValueCallback(string s); + + public interface IJsonStoreModule + { + bool CreateStore(string value, out UUID result); + bool DestroyStore(UUID storeID); + bool TestPath(UUID storeID, string path, bool useJson); + bool SetValue(UUID storeID, string path, string value, bool useJson); + bool RemoveValue(UUID storeID, string path); + bool GetValue(UUID storeID, string path, bool useJson, out string value); + + void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback); + void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback); + } +} diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs new file mode 100644 index 0000000..49556b6 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs @@ -0,0 +1,498 @@ +/* + * Copyright (c) Contributors + * 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 OpenSim 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 Mono.Addins; + +using System; +using System.Reflection; +using System.Threading; +using System.Text; +using System.Net; +using System.Net.Sockets; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace OpenSim.Region.OptionalModules.Scripting.JsonStore +{ + public class JsonStore + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private OSD m_ValueStore; + + protected class TakeValueCallbackClass + { + public string Path { get; set; } + public bool UseJson { get; set; } + public TakeValueCallback Callback { get; set; } + + public TakeValueCallbackClass(string spath, bool usejson, TakeValueCallback cback) + { + Path = spath; + UseJson = usejson; + Callback = cback; + } + } + + protected List m_TakeStore; + protected List m_ReadStore; + + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public JsonStore(string value = "") + { + m_TakeStore = new List(); + m_ReadStore = new List(); + + if (String.IsNullOrEmpty(value)) + m_ValueStore = new OSDMap(); + else + m_ValueStore = OSDParser.DeserializeJson(value); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public bool TestPath(string expr, bool useJson) + { + Stack path = ParsePathExpression(expr); + OSD result = ProcessPathExpression(m_ValueStore,path); + + if (result == null) + return false; + + if (useJson || result.Type == OSDType.String) + return true; + + return false; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public bool GetValue(string expr, out string value, bool useJson) + { + Stack path = ParsePathExpression(expr); + OSD result = ProcessPathExpression(m_ValueStore,path); + return ConvertOutputValue(result,out value,useJson); + } + + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public bool RemoveValue(string expr) + { + return SetValueFromExpression(expr,null); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public bool SetValue(string expr, string value, bool useJson) + { + OSD ovalue = useJson ? OSDParser.DeserializeJson(value) : new OSDString(value); + return SetValueFromExpression(expr,ovalue); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public bool TakeValue(string expr, bool useJson, TakeValueCallback cback) + { + Stack path = ParsePathExpression(expr); + string pexpr = PathExpressionToKey(path); + + OSD result = ProcessPathExpression(m_ValueStore,path); + if (result == null) + { + m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); + return false; + } + + string value = String.Empty; + if (! ConvertOutputValue(result,out value,useJson)) + { + // the structure does not match the request so i guess we'll wait + m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); + return false; + } + + SetValueFromExpression(expr,null); + cback(value); + + return true; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public bool ReadValue(string expr, bool useJson, TakeValueCallback cback) + { + Stack path = ParsePathExpression(expr); + string pexpr = PathExpressionToKey(path); + + OSD result = ProcessPathExpression(m_ValueStore,path); + if (result == null) + { + m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); + return false; + } + + string value = String.Empty; + if (! ConvertOutputValue(result,out value,useJson)) + { + // the structure does not match the request so i guess we'll wait + m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); + return false; + } + + cback(value); + + return true; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected bool SetValueFromExpression(string expr, OSD ovalue) + { + Stack path = ParsePathExpression(expr); + if (path.Count == 0) + { + m_ValueStore = ovalue; + return true; + } + + string pkey = path.Pop(); + string pexpr = PathExpressionToKey(path); + if (pexpr != "") + pexpr += "."; + + OSD result = ProcessPathExpression(m_ValueStore,path); + if (result == null) + return false; + + Regex aPattern = new Regex("\\[([0-9]+|\\+)\\]"); + MatchCollection amatches = aPattern.Matches(pkey,0); + + if (amatches.Count > 0) + { + if (result.Type != OSDType.Array) + return false; + + OSDArray amap = result as OSDArray; + + Match match = amatches[0]; + GroupCollection groups = match.Groups; + string akey = groups[1].Value; + + if (akey == "+") + { + string npkey = String.Format("[{0}]",amap.Count); + + amap.Add(ovalue); + InvokeNextCallback(pexpr + npkey); + return true; + } + + int aval = Convert.ToInt32(akey); + if (0 <= aval && aval < amap.Count) + { + if (ovalue == null) + amap.RemoveAt(aval); + else + { + amap[aval] = ovalue; + InvokeNextCallback(pexpr + pkey); + } + return true; + } + + return false; + } + + Regex hPattern = new Regex("{([^}]+)}"); + MatchCollection hmatches = hPattern.Matches(pkey,0); + + if (hmatches.Count > 0) + { + Match match = hmatches[0]; + GroupCollection groups = match.Groups; + string hkey = groups[1].Value; + + if (result is OSDMap) + { + OSDMap hmap = result as OSDMap; + if (ovalue != null) + { + hmap[hkey] = ovalue; + InvokeNextCallback(pexpr + pkey); + } + else if (hmap.ContainsKey(hkey)) + hmap.Remove(hkey); + + return true; + } + + return false; + } + + // Shouldn't get here if the path was checked correctly + m_log.WarnFormat("[JsonStore] invalid path expression"); + return false; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected bool InvokeNextCallback(string pexpr) + { + // Process all of the reads that match the expression first + List reads = + m_ReadStore.FindAll(delegate(TakeValueCallbackClass tb) { return pexpr.StartsWith(tb.Path); }); + + foreach (TakeValueCallbackClass readcb in reads) + { + m_ReadStore.Remove(readcb); + ReadValue(readcb.Path,readcb.UseJson,readcb.Callback); + } + + // Process one take next + TakeValueCallbackClass takecb = + m_TakeStore.Find(delegate(TakeValueCallbackClass tb) { return pexpr.StartsWith(tb.Path); }); + + if (takecb != null) + { + m_TakeStore.Remove(takecb); + TakeValue(takecb.Path,takecb.UseJson,takecb.Callback); + + return true; + } + + return false; + } + + // ----------------------------------------------------------------- + /// + /// Parse the path expression and put the components into a stack. We + /// use a stack because we process the path in inverse order later + /// + // ----------------------------------------------------------------- + protected static Stack ParsePathExpression(string path) + { + Stack m_path = new Stack(); + + // add front and rear separators + path = "." + path + "."; + + // add separators for quoted paths + Regex pass1 = new Regex("{[^}]+}"); + path = pass1.Replace(path,".$0.",-1,0); + + // add separators for array references + Regex pass2 = new Regex("(\\[[0-9]+\\]|\\[\\+\\])"); + path = pass2.Replace(path,".$0.",-1,0); + + // add quotes to bare identifier + Regex pass3 = new Regex("\\.([a-zA-Z]+)"); + path = pass3.Replace(path,".{$1}",-1,0); + + // remove extra separators + Regex pass4 = new Regex("\\.+"); + path = pass4.Replace(path,".",-1,0); + + Regex validate = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)+$"); + if (validate.IsMatch(path)) + { + Regex parser = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\]+)"); + MatchCollection matches = parser.Matches(path,0); + foreach (Match match in matches) + m_path.Push(match.Groups[1].Value); + } + + return m_path; + } + + // ----------------------------------------------------------------- + /// + /// + /// + /// path is a stack where the top level of the path is at the bottom of the stack + // ----------------------------------------------------------------- + protected static OSD ProcessPathExpression(OSD map, Stack path) + { + if (path.Count == 0) + return map; + + string pkey = path.Pop(); + + OSD rmap = ProcessPathExpression(map,path); + if (rmap == null) + return null; + + // ---------- Check for an array index ---------- + Regex aPattern = new Regex("\\[([0-9]+)\\]"); + MatchCollection amatches = aPattern.Matches(pkey,0); + + if (amatches.Count > 0) + { + if (rmap.Type != OSDType.Array) + { + m_log.WarnFormat("[JsonStore] wrong type for key {2}, expecting {0}, got {1}",OSDType.Array,rmap.Type,pkey); + return null; + } + + OSDArray amap = rmap as OSDArray; + + Match match = amatches[0]; + GroupCollection groups = match.Groups; + string akey = groups[1].Value; + int aval = Convert.ToInt32(akey); + + if (aval < amap.Count) + return (OSD) amap[aval]; + + return null; + } + + // ---------- Check for a hash index ---------- + Regex hPattern = new Regex("{([^}]+)}"); + MatchCollection hmatches = hPattern.Matches(pkey,0); + + if (hmatches.Count > 0) + { + if (rmap.Type != OSDType.Map) + { + m_log.WarnFormat("[JsonStore] wrong type for key {2}, expecting {0}, got {1}",OSDType.Map,rmap.Type,pkey); + return null; + } + + OSDMap hmap = rmap as OSDMap; + + Match match = hmatches[0]; + GroupCollection groups = match.Groups; + string hkey = groups[1].Value; + + if (hmap.ContainsKey(hkey)) + return (OSD) hmap[hkey]; + + return null; + } + + // Shouldn't get here if the path was checked correctly + m_log.WarnFormat("[JsonStore] Path type (unknown) does not match the structure"); + return null; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected static bool ConvertOutputValue(OSD result, out string value, bool useJson) + { + value = String.Empty; + + // If we couldn't process the path + if (result == null) + return false; + + if (useJson) + { + // The path pointed to an intermediate hash structure + if (result.Type == OSDType.Map) + { + value = OSDParser.SerializeJsonString(result as OSDMap); + return true; + } + + // The path pointed to an intermediate hash structure + if (result.Type == OSDType.Array) + { + value = OSDParser.SerializeJsonString(result as OSDArray); + return true; + } + + value = "'" + result.AsString() + "'"; + return true; + } + + if (result.Type == OSDType.String) + { + value = result.AsString(); + return true; + } + + return false; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected static string PathExpressionToKey(Stack path) + { + if (path.Count == 0) + return ""; + + string pkey = ""; + foreach (string k in path) + pkey = (pkey == "") ? k : (k + "." + pkey); + + return pkey; + } + } +} diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs new file mode 100644 index 0000000..6dae956 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs @@ -0,0 +1,429 @@ +/* + * Copyright (c) Contributors + * 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 OpenSim 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 Mono.Addins; + +using System; +using System.Reflection; +using System.Threading; +using System.Text; +using System.Net; +using System.Net.Sockets; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using System.Collections.Generic; +using System.Text.RegularExpressions; + + +namespace OpenSim.Region.OptionalModules.Scripting.JsonStore +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "JsonStoreModule")] + + public class JsonStoreModule : INonSharedRegionModule, IJsonStoreModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private IConfig m_config = null; + private bool m_enabled = false; + private Scene m_scene = null; + + private Dictionary m_JsonValueStore; + private UUID m_sharedStore; + +#region IRegionModule Members + + // ----------------------------------------------------------------- + /// + /// Name of this shared module is it's class name + /// + // ----------------------------------------------------------------- + public string Name + { + get { return this.GetType().Name; } + } + + // ----------------------------------------------------------------- + /// + /// Initialise this shared module + /// + /// this region is getting initialised + /// nini config, we are not using this + // ----------------------------------------------------------------- + public void Initialise(IConfigSource config) + { + try + { + if ((m_config = config.Configs["JsonStore"]) == null) + { + // There is no configuration, the module is disabled + m_log.InfoFormat("[JsonStore] no configuration info"); + return; + } + + m_enabled = m_config.GetBoolean("Enabled", m_enabled); + } + catch (Exception e) + { + m_log.ErrorFormat("[JsonStore] initialization error: {0}",e.Message); + return; + } + + m_log.InfoFormat("[JsonStore] module {0} enabled",(m_enabled ? "is" : "is not")); + } + + // ----------------------------------------------------------------- + /// + /// everything is loaded, perform post load configuration + /// + // ----------------------------------------------------------------- + public void PostInitialise() + { + } + + // ----------------------------------------------------------------- + /// + /// Nothing to do on close + /// + // ----------------------------------------------------------------- + public void Close() + { + } + + // ----------------------------------------------------------------- + /// + /// + // ----------------------------------------------------------------- + public void AddRegion(Scene scene) + { + if (m_enabled) + { + m_scene = scene; + m_scene.RegisterModuleInterface(this); + + m_sharedStore = UUID.Zero; + m_JsonValueStore = new Dictionary(); + m_JsonValueStore.Add(m_sharedStore,new JsonStore("")); + } + } + + // ----------------------------------------------------------------- + /// + /// + // ----------------------------------------------------------------- + public void RemoveRegion(Scene scene) + { + // need to remove all references to the scene in the subscription + // list to enable full garbage collection of the scene object + } + + // ----------------------------------------------------------------- + /// + /// Called when all modules have been added for a region. This is + /// where we hook up events + /// + // ----------------------------------------------------------------- + public void RegionLoaded(Scene scene) + { + if (m_enabled) {} + } + + /// ----------------------------------------------------------------- + /// + /// + // ----------------------------------------------------------------- + public Type ReplaceableInterface + { + get { return null; } + } + +#endregion + +#region ScriptInvocationInteface + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public bool CreateStore(string value, out UUID result) + { + result = UUID.Zero; + + if (! m_enabled) return false; + + UUID uuid = UUID.Random(); + JsonStore map = null; + + try + { + map = new JsonStore(value); + } + catch (Exception e) + { + m_log.InfoFormat("[JsonStore] Unable to initialize store from {0}; {1}",value,e.Message); + return false; + } + + lock (m_JsonValueStore) + m_JsonValueStore.Add(uuid,map); + + result = uuid; + return true; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public bool DestroyStore(UUID storeID) + { + if (! m_enabled) return false; + + lock (m_JsonValueStore) + m_JsonValueStore.Remove(storeID); + + return true; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public bool TestPath(UUID storeID, string path, bool useJson) + { + if (! m_enabled) return false; + + JsonStore map = null; + lock (m_JsonValueStore) + { + if (! m_JsonValueStore.TryGetValue(storeID,out map)) + { + m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); + return true; + } + } + + try + { + lock (map) + return map.TestPath(path,useJson); + } + catch (Exception e) + { + m_log.InfoFormat("[JsonStore] Path test failed for {0} in {1}; {2}",path,storeID,e.Message); + } + + return false; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public bool SetValue(UUID storeID, string path, string value, bool useJson) + { + if (! m_enabled) return false; + + JsonStore map = null; + lock (m_JsonValueStore) + { + if (! m_JsonValueStore.TryGetValue(storeID,out map)) + { + m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); + return false; + } + } + + try + { + lock (map) + if (map.SetValue(path,value,useJson)) + return true; + } + catch (Exception e) + { + m_log.InfoFormat("[JsonStore] Unable to assign {0} to {1} in {2}; {3}",value,path,storeID,e.Message); + } + + return false; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public bool RemoveValue(UUID storeID, string path) + { + if (! m_enabled) return false; + + JsonStore map = null; + lock (m_JsonValueStore) + { + if (! m_JsonValueStore.TryGetValue(storeID,out map)) + { + m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); + return false; + } + } + + try + { + lock (map) + if (map.RemoveValue(path)) + return true; + } + catch (Exception e) + { + m_log.InfoFormat("[JsonStore] Unable to remove {0} in {1}; {2}",path,storeID,e.Message); + } + + return false; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public bool GetValue(UUID storeID, string path, bool useJson, out string value) + { + value = String.Empty; + + if (! m_enabled) return false; + + JsonStore map = null; + lock (m_JsonValueStore) + { + if (! m_JsonValueStore.TryGetValue(storeID,out map)) + return false; + } + + try + { + lock (map) + { + return map.GetValue(path, out value, useJson); + } + } + catch (Exception e) + { + m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.Message); + } + + return false; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback) + { + if (! m_enabled) + { + cback(String.Empty); + return; + } + + JsonStore map = null; + lock (m_JsonValueStore) + { + if (! m_JsonValueStore.TryGetValue(storeID,out map)) + { + cback(String.Empty); + return; + } + } + + try + { + lock (map) + { + map.TakeValue(path, useJson, cback); + return; + } + } + catch (Exception e) + { + m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString()); + } + + cback(String.Empty); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback) + { + if (! m_enabled) + { + cback(String.Empty); + return; + } + + JsonStore map = null; + lock (m_JsonValueStore) + { + if (! m_JsonValueStore.TryGetValue(storeID,out map)) + { + cback(String.Empty); + return; + } + } + + try + { + lock (map) + { + map.ReadValue(path, useJson, cback); + return; + } + } + catch (Exception e) + { + m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString()); + } + + cback(String.Empty); + } + +#endregion + } +} diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs new file mode 100644 index 0000000..7aba860 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -0,0 +1,489 @@ +/* + * Copyright (c) Contributors + * 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 OpenSim 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 Mono.Addins; + +using System; +using System.Reflection; +using System.Threading; +using System.Text; +using System.Net; +using System.Net.Sockets; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace OpenSim.Region.OptionalModules.Scripting.JsonStore +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "JsonStoreScriptModule")] + + public class JsonStoreScriptModule : INonSharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private IConfig m_config = null; + private bool m_enabled = false; + private Scene m_scene = null; + + private IScriptModuleComms m_comms; + private IJsonStoreModule m_store; + +#region IRegionModule Members + + // ----------------------------------------------------------------- + /// + /// Name of this shared module is it's class name + /// + // ----------------------------------------------------------------- + public string Name + { + get { return this.GetType().Name; } + } + + // ----------------------------------------------------------------- + /// + /// Initialise this shared module + /// + /// this region is getting initialised + /// nini config, we are not using this + // ----------------------------------------------------------------- + public void Initialise(IConfigSource config) + { + try + { + if ((m_config = config.Configs["JsonStore"]) == null) + { + // There is no configuration, the module is disabled + m_log.InfoFormat("[JsonStoreScripts] no configuration info"); + return; + } + + m_enabled = m_config.GetBoolean("Enabled", m_enabled); + } + catch (Exception e) + { + m_log.ErrorFormat("[JsonStoreScripts] initialization error: {0}",e.Message); + return; + } + + m_log.InfoFormat("[JsonStoreScripts] module {0} enabled",(m_enabled ? "is" : "is not")); + } + + // ----------------------------------------------------------------- + /// + /// everything is loaded, perform post load configuration + /// + // ----------------------------------------------------------------- + public void PostInitialise() + { + } + + // ----------------------------------------------------------------- + /// + /// Nothing to do on close + /// + // ----------------------------------------------------------------- + public void Close() + { + } + + // ----------------------------------------------------------------- + /// + /// + // ----------------------------------------------------------------- + public void AddRegion(Scene scene) + { + } + + // ----------------------------------------------------------------- + /// + /// + // ----------------------------------------------------------------- + public void RemoveRegion(Scene scene) + { + // need to remove all references to the scene in the subscription + // list to enable full garbage collection of the scene object + } + + // ----------------------------------------------------------------- + /// + /// Called when all modules have been added for a region. This is + /// where we hook up events + /// + // ----------------------------------------------------------------- + public void RegionLoaded(Scene scene) + { + if (m_enabled) + { + m_scene = scene; + m_comms = m_scene.RequestModuleInterface(); + if (m_comms == null) + { + m_log.ErrorFormat("[JsonStoreScripts] ScriptModuleComms interface not defined"); + m_enabled = false; + return; + } + + m_store = m_scene.RequestModuleInterface(); + if (m_store == null) + { + m_log.ErrorFormat("[JsonStoreScripts] JsonModule interface not defined"); + m_enabled = false; + return; + } + + m_comms.RegisterScriptInvocation(this,"JsonCreateStore"); + m_comms.RegisterScriptInvocation(this,"JsonDestroyStore"); + + m_comms.RegisterScriptInvocation(this,"JsonReadNotecard"); + m_comms.RegisterScriptInvocation(this,"JsonWriteNotecard"); + + m_comms.RegisterScriptInvocation(this,"JsonTestPath"); + m_comms.RegisterScriptInvocation(this,"JsonTestPathJson"); + + m_comms.RegisterScriptInvocation(this,"JsonGetValue"); + m_comms.RegisterScriptInvocation(this,"JsonGetValueJson"); + + m_comms.RegisterScriptInvocation(this,"JsonTakeValue"); + m_comms.RegisterScriptInvocation(this,"JsonTakeValueJson"); + + m_comms.RegisterScriptInvocation(this,"JsonReadValue"); + m_comms.RegisterScriptInvocation(this,"JsonReadValueJson"); + + m_comms.RegisterScriptInvocation(this,"JsonSetValue"); + m_comms.RegisterScriptInvocation(this,"JsonSetValueJson"); + + m_comms.RegisterScriptInvocation(this,"JsonRemoveValue"); + } + } + + /// ----------------------------------------------------------------- + /// + /// + // ----------------------------------------------------------------- + public Type ReplaceableInterface + { + get { return null; } + } + +#endregion + +#region ScriptInvocationInteface + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected void GenerateRuntimeError(string msg) + { + throw new Exception("JsonStore Runtime Error: " + msg); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected UUID JsonCreateStore(UUID hostID, UUID scriptID, string value) + { + UUID uuid = UUID.Zero; + if (! m_store.CreateStore(value, out uuid)) + GenerateRuntimeError("Failed to create Json store"); + + return uuid; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID) + { + return m_store.DestroyStore(storeID) ? 1 : 0; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) + { + UUID reqID = UUID.Random(); + Util.FireAndForget(delegate(object o) { DoJsonReadNotecard(reqID,hostID,scriptID,storeID,path,assetID); }); + return reqID; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name) + { + UUID reqID = UUID.Random(); + Util.FireAndForget(delegate(object o) { DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name); }); + return reqID; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected int JsonTestPath(UUID hostID, UUID scriptID, UUID storeID, string path) + { + return m_store.TestPath(storeID,path,false) ? 1 : 0; + } + + protected int JsonTestPathJson(UUID hostID, UUID scriptID, UUID storeID, string path) + { + return m_store.TestPath(storeID,path,true) ? 1 : 0; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value) + { + return m_store.SetValue(storeID,path,value,false) ? 1 : 0; + } + + protected int JsonSetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value) + { + return m_store.SetValue(storeID,path,value,true) ? 1 : 0; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path) + { + return m_store.RemoveValue(storeID,path) ? 1 : 0; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path) + { + string value = String.Empty; + m_store.GetValue(storeID,path,false,out value); + return value; + } + + protected string JsonGetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) + { + string value = String.Empty; + m_store.GetValue(storeID,path,true, out value); + return value; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path) + { + UUID reqID = UUID.Random(); + Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,false); }); + return reqID; + } + + protected UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) + { + UUID reqID = UUID.Random(); + Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,true); }); + return reqID; + } + + private void DoJsonTakeValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) + { + try + { + m_store.TakeValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); + return; + } + catch (Exception e) + { + m_log.InfoFormat("[JsonStoreScripts] unable to retrieve value; {0}",e.ToString()); + } + + DispatchValue(scriptID,reqID,String.Empty); + } + + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path) + { + UUID reqID = UUID.Random(); + Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,false); }); + return reqID; + } + + protected UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) + { + UUID reqID = UUID.Random(); + Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,true); }); + return reqID; + } + + private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) + { + try + { + m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); + return; + } + catch (Exception e) + { + m_log.InfoFormat("[JsonStoreScripts] unable to retrieve value; {0}",e.ToString()); + } + + DispatchValue(scriptID,reqID,String.Empty); + } + +#endregion + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected void DispatchValue(UUID scriptID, UUID reqID, string value) + { + m_comms.DispatchReply(scriptID,1,value,reqID.ToString()); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + private void DoJsonReadNotecard(UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) + { + AssetBase a = m_scene.AssetService.Get(assetID.ToString()); + if (a == null) + GenerateRuntimeError(String.Format("Unable to find notecard asset {0}",assetID)); + + if (a.Type != (sbyte)AssetType.Notecard) + GenerateRuntimeError(String.Format("Invalid notecard asset {0}",assetID)); + + m_log.DebugFormat("[JsonStoreScripts] read notecard in context {0}",storeID); + + try + { + System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); + string jsondata = SLUtil.ParseNotecardToString(enc.GetString(a.Data)); + int result = m_store.SetValue(storeID,path,jsondata,true) ? 1 : 0; + m_comms.DispatchReply(scriptID,result,"",reqID.ToString()); + return; + } + catch (Exception e) + { + m_log.WarnFormat("[JsonStoreScripts] Json parsing failed; {0}",e.Message); + } + + GenerateRuntimeError(String.Format("Json parsing failed for {0}",assetID.ToString())); + m_comms.DispatchReply(scriptID,0,"",reqID.ToString()); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + private void DoJsonWriteNotecard(UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, string name) + { + string data; + if (! m_store.GetValue(storeID,path,true, out data)) + { + m_comms.DispatchReply(scriptID,0,UUID.Zero.ToString(),reqID.ToString()); + return; + } + + SceneObjectPart host = m_scene.GetSceneObjectPart(hostID); + + // Create new asset + UUID assetID = UUID.Random(); + AssetBase asset = new AssetBase(assetID, name, (sbyte)AssetType.Notecard, host.OwnerID.ToString()); + asset.Description = "Json store"; + + int textLength = data.Length; + data = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length " + + textLength.ToString() + "\n" + data + "}\n"; + + asset.Data = Util.UTF8.GetBytes(data); + m_scene.AssetService.Store(asset); + + // Create Task Entry + TaskInventoryItem taskItem = new TaskInventoryItem(); + + taskItem.ResetIDs(host.UUID); + taskItem.ParentID = host.UUID; + taskItem.CreationDate = (uint)Util.UnixTimeSinceEpoch(); + taskItem.Name = asset.Name; + taskItem.Description = asset.Description; + taskItem.Type = (int)AssetType.Notecard; + taskItem.InvType = (int)InventoryType.Notecard; + taskItem.OwnerID = host.OwnerID; + taskItem.CreatorID = host.OwnerID; + taskItem.BasePermissions = (uint)PermissionMask.All; + taskItem.CurrentPermissions = (uint)PermissionMask.All; + taskItem.EveryonePermissions = 0; + taskItem.NextPermissions = (uint)PermissionMask.All; + taskItem.GroupID = host.GroupID; + taskItem.GroupPermissions = 0; + taskItem.Flags = 0; + taskItem.PermsGranter = UUID.Zero; + taskItem.PermsMask = 0; + taskItem.AssetID = asset.FullID; + + host.Inventory.AddInventoryItem(taskItem, false); + + m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString()); + } + } +} -- cgit v1.1 From 2d45ba47ac91646901701df8eec4eb86a0fddabf Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Tue, 17 Apr 2012 13:55:00 -0700 Subject: add configuration for jsonstore module, disabled by default --- bin/OpenSimDefaults.ini | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 68a2ea3..3f2f131 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -1561,6 +1561,12 @@ RefreshTime = 3600 ;; +;; JsonStore module provides structured store for scripts +;; +[JsonStore] +Enabled = False + +;; ;; These are defaults that are overwritten below in [Architecture]. ;; These defaults allow OpenSim to work out of the box with ;; zero configuration -- cgit v1.1 From 4db518b9a30122f662a40252d3674ea272d6dcc1 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Tue, 17 Apr 2012 14:15:17 -0700 Subject: Fix the Csharp 3.0 vs 4.0 problem in JsonStore initialization. Cut down on the logging spam. --- OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs | 4 +++- OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs | 4 ++-- .../OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index 49556b6..34894ba 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs @@ -74,7 +74,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - public JsonStore(string value = "") + public JsonStore() : this("") {} + + public JsonStore(string value) { m_TakeStore = new List(); m_ReadStore = new List(); diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs index 6dae956..26bc615 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs @@ -85,7 +85,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore if ((m_config = config.Configs["JsonStore"]) == null) { // There is no configuration, the module is disabled - m_log.InfoFormat("[JsonStore] no configuration info"); + // m_log.InfoFormat("[JsonStore] no configuration info"); return; } @@ -97,7 +97,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore return; } - m_log.InfoFormat("[JsonStore] module {0} enabled",(m_enabled ? "is" : "is not")); + m_log.DebugFormat("[JsonStore] module {0} enabled",(m_enabled ? "is" : "is not")); } // ----------------------------------------------------------------- diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index 7aba860..c619d0d 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -84,7 +84,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore if ((m_config = config.Configs["JsonStore"]) == null) { // There is no configuration, the module is disabled - m_log.InfoFormat("[JsonStoreScripts] no configuration info"); + // m_log.InfoFormat("[JsonStoreScripts] no configuration info"); return; } @@ -96,7 +96,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore return; } - m_log.InfoFormat("[JsonStoreScripts] module {0} enabled",(m_enabled ? "is" : "is not")); + m_log.DebugFormat("[JsonStoreScripts] module {0} enabled",(m_enabled ? "is" : "is not")); } // ----------------------------------------------------------------- -- cgit v1.1 From 84891930aa73a013493ec511b13f7c8954d20770 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Tue, 17 Apr 2012 14:23:43 -0700 Subject: clean up some more logging spam in the jsonstore modules --- OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs | 3 ++- .../OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs index 26bc615..311531c 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs @@ -97,7 +97,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore return; } - m_log.DebugFormat("[JsonStore] module {0} enabled",(m_enabled ? "is" : "is not")); + if (m_enabled) + m_log.DebugFormat("[JsonStore] module is enabled"); } // ----------------------------------------------------------------- diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index c619d0d..eda2aef 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -96,7 +96,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore return; } - m_log.DebugFormat("[JsonStoreScripts] module {0} enabled",(m_enabled ? "is" : "is not")); + if (m_enabled) + m_log.DebugFormat("[JsonStoreScripts] module is enabled"); } // ----------------------------------------------------------------- -- cgit v1.1 From 859646ef5cf016eecfefb53b2b388fe880c39a3a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 17 Apr 2012 23:54:51 +0100 Subject: minor: Add some method doc. Add warnings since calling SOG link/delink methods directly rather than through Scene may allow race conditions. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 3 +++ OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 0098add..67eb0fe 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -91,6 +91,9 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal Dictionary SceneObjectGroupsByLocalPartID = new Dictionary(); + /// + /// Lock to prevent object group update, linking and delinking operations from running concurrently. + /// private Object m_updateLock = new Object(); #endregion diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index a49ed13..8e786c1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1962,6 +1962,10 @@ namespace OpenSim.Region.Framework.Scenes /// /// Link the prims in a given group to this group /// + /// + /// Do not call this method directly - use Scene.LinkObjects() instead to avoid races between threads. + /// FIXME: There are places where scripts call these methods directly without locking. This is a potential race condition. + /// /// The group of prims which should be linked to this group public void LinkToGroup(SceneObjectGroup objectGroup) { @@ -2045,6 +2049,11 @@ namespace OpenSim.Region.Framework.Scenes /// Delink the given prim from this group. The delinked prim is established as /// an independent SceneObjectGroup. /// + /// + /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race + /// condition. But currently there is no + /// alternative method that does take a lonk to delink a single prim. + /// /// /// The object group of the newly delinked prim. Null if part could not be found public SceneObjectGroup DelinkFromGroup(uint partID) @@ -2056,6 +2065,11 @@ namespace OpenSim.Region.Framework.Scenes /// Delink the given prim from this group. The delinked prim is established as /// an independent SceneObjectGroup. /// + /// + /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race + /// condition. But currently there is no + /// alternative method that does take a lonk to delink a single prim. + /// /// /// /// The object group of the newly delinked prim. Null if part could not be found @@ -2081,6 +2095,11 @@ namespace OpenSim.Region.Framework.Scenes /// Delink the given prim from this group. The delinked prim is established as /// an independent SceneObjectGroup. /// + /// + /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race + /// condition. But currently there is no + /// alternative method that does take a lonk to delink a single prim. + /// /// /// /// The object group of the newly delinked prim. -- cgit v1.1 From c85f9d681a7e9cb09e8cf4de97643eadc7a9d4d8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 18 Apr 2012 00:39:39 +0100 Subject: On "show part" command, show link number. This replaces the Parts count which was rather pointless for a prim (it was either 1 if a child or the number of parts if the root). This information is still avaliable on the "show object" command. --- .../Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index f5a5c92..06fea58 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -282,7 +282,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands sb.AppendFormat("Location: {0} @ {1}\n", sop.AbsolutePosition, sop.ParentGroup.Scene.RegionInfo.RegionName); sb.AppendFormat("Parent: {0}", sop.IsRoot ? "Is Root\n" : string.Format("{0} {1}\n", sop.ParentGroup.Name, sop.ParentGroup.UUID)); - sb.AppendFormat("Parts: {0}\n", !sop.IsRoot ? "1" : sop.ParentGroup.PrimCount.ToString());; + sb.AppendFormat("Link number: {0}\n", sop.LinkNum); return sb; } -- cgit v1.1 From ea73a035531a0e957f54fe897f3a3ff7ca3dc22d Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 18 Apr 2012 20:01:41 +0100 Subject: Don't re-add the assembly resolver for each script if not creating the appdomain --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index b7903d5..ad2f12e 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1021,11 +1021,18 @@ namespace OpenSim.Region.ScriptEngine.XEngine AppDomain sandbox; if (m_AppDomainLoading) + { sandbox = AppDomain.CreateDomain( m_Scene.RegionInfo.RegionID.ToString(), evidence, appSetup); + m_AppDomains[appDomain].AssemblyResolve += + new ResolveEventHandler( + AssemblyResolver.OnAssemblyResolve); + } else + { sandbox = AppDomain.CurrentDomain; + } //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); @@ -1037,9 +1044,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_AppDomains[appDomain] = sandbox; - m_AppDomains[appDomain].AssemblyResolve += - new ResolveEventHandler( - AssemblyResolver.OnAssemblyResolve); m_DomainScripts[appDomain] = new List(); } catch (Exception e) @@ -1984,4 +1988,4 @@ namespace OpenSim.Region.ScriptEngine.XEngine // m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); } } -} \ No newline at end of file +} -- cgit v1.1 From c2be894330385ac55d3c62349ba9af4b2c9e86b4 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 18 Apr 2012 23:23:01 +0100 Subject: Fx up estate settings --- OpenSim/Framework/EstateSettings.cs | 2 +- prebuild.xml | 192 ++++++++++++++++++------------------ 2 files changed, 97 insertions(+), 97 deletions(-) diff --git a/OpenSim/Framework/EstateSettings.cs b/OpenSim/Framework/EstateSettings.cs index 1caf04a..9020761 100644 --- a/OpenSim/Framework/EstateSettings.cs +++ b/OpenSim/Framework/EstateSettings.cs @@ -368,7 +368,7 @@ namespace OpenSim.Framework if (ban.BannedUserID == avatarID) return true; - if (!IsEstateManager(avatarID) && !HasAccess(avatarID)) + if (!IsEstateManagerOrOwner(avatarID) && !HasAccess(avatarID)) { if (DenyMinors) { diff --git a/prebuild.xml b/prebuild.xml index f9b26ef..b908649 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -34,7 +34,7 @@ - + ../../bin/ @@ -77,7 +77,7 @@ - + ../../bin/ @@ -112,7 +112,7 @@ - + ../../../../bin/ @@ -150,7 +150,7 @@ - + ../../../bin/ @@ -177,7 +177,7 @@ - + ../../../bin/ @@ -205,7 +205,7 @@ - + ../../../bin/ @@ -234,7 +234,7 @@ - + ../../../bin/ @@ -258,7 +258,7 @@ - + ../../bin/ @@ -287,7 +287,7 @@ - + ../../../../bin/ @@ -312,7 +312,7 @@ - + ../../../../bin/ @@ -339,7 +339,7 @@ - + ../../../../bin/ @@ -364,7 +364,7 @@ - + ../../../../bin/ @@ -390,7 +390,7 @@ - + ../../../../bin/ @@ -416,7 +416,7 @@ - + ../../../bin/ @@ -448,7 +448,7 @@ - + ../../../../bin/ @@ -476,7 +476,7 @@ - + ../../../../bin/Physics/ @@ -499,7 +499,7 @@ - + ../../../../bin/Physics/ @@ -522,7 +522,7 @@ - + ../../../../bin/Physics/ @@ -552,7 +552,7 @@ - + ../../../../bin/ @@ -577,7 +577,7 @@ - + ../../../../bin/Physics/ @@ -608,7 +608,7 @@ - + ../../../../bin/Physics/ @@ -639,7 +639,7 @@ - + ../../../../bin/Physics/ @@ -672,7 +672,7 @@ - + ../../../../bin/Physics/ @@ -703,7 +703,7 @@ - + ../../../../bin/Physics/ @@ -735,7 +735,7 @@ - + ../../bin/ @@ -770,7 +770,7 @@ - + ../../../bin/ @@ -811,7 +811,7 @@ - + ../../../bin/ @@ -864,7 +864,7 @@ - + ../../../bin/ @@ -894,7 +894,7 @@ - + ../../../bin/ @@ -921,7 +921,7 @@ - + ../../../bin/ @@ -952,7 +952,7 @@ - + ../../../bin/ @@ -983,7 +983,7 @@ - + ../../../bin/ @@ -1022,7 +1022,7 @@ - + ../../../bin/ @@ -1053,7 +1053,7 @@ - + ../../../bin/ @@ -1084,7 +1084,7 @@ - + ../../../bin/ @@ -1116,7 +1116,7 @@ - + ../../../bin/ @@ -1149,7 +1149,7 @@ - + ../../../bin/ @@ -1183,7 +1183,7 @@ - + ../../../bin/ @@ -1214,7 +1214,7 @@ - + ../../../bin/ @@ -1245,7 +1245,7 @@ - + ../../../bin/ @@ -1278,7 +1278,7 @@ - + ../../../bin/ @@ -1311,7 +1311,7 @@ - + ../../../bin/ @@ -1349,7 +1349,7 @@ - + ../../../bin/ @@ -1379,7 +1379,7 @@ - + ../../../bin/ @@ -1418,7 +1418,7 @@ - + ../../../bin/ @@ -1459,7 +1459,7 @@ - + ../../bin/ @@ -1492,7 +1492,7 @@ - + ../../bin/ @@ -1524,7 +1524,7 @@ - + ../../../bin/ @@ -1589,7 +1589,7 @@ - + ../../../bin/ @@ -1627,7 +1627,7 @@ - + ../../../bin/ @@ -1662,7 +1662,7 @@ - + ../../../../../bin/ @@ -1705,7 +1705,7 @@ - + ../../../../../bin/ @@ -1747,7 +1747,7 @@ - + ../../../bin/ @@ -1804,7 +1804,7 @@ - + ../../../bin/ @@ -1832,7 +1832,7 @@ - + ../../../bin/ @@ -1876,7 +1876,7 @@ - + ../../../bin/ @@ -1911,7 +1911,7 @@ - + ../../../bin/ @@ -1941,7 +1941,7 @@ - + ../../../bin/ @@ -1982,7 +1982,7 @@ - + ../../../bin/ @@ -2017,7 +2017,7 @@ - + ../../../../bin/ @@ -2054,7 +2054,7 @@ - + ../../../../bin/ @@ -2098,7 +2098,7 @@ - + ../../../bin/ @@ -2135,7 +2135,7 @@ - + ../../../bin/ @@ -2173,7 +2173,7 @@ - + ../../../bin/ @@ -2207,7 +2207,7 @@ - + ../../../bin/ @@ -2248,7 +2248,7 @@ - + ../../../../bin/ @@ -2286,7 +2286,7 @@ - + ../../../../../../bin/ @@ -2319,7 +2319,7 @@ - + ../../../../../../../bin/ @@ -2351,7 +2351,7 @@ - + ../../../../../../bin/ @@ -2390,7 +2390,7 @@ - + ../../../../../bin/ @@ -2421,7 +2421,7 @@ - + ../../../../../bin/ @@ -2459,7 +2459,7 @@ - + ../../../../bin/ @@ -2502,7 +2502,7 @@ - + ../../../bin/ @@ -2553,7 +2553,7 @@ - + ../../../bin/ @@ -2580,7 +2580,7 @@ - + ../../../bin/ @@ -2607,7 +2607,7 @@ - + ../../../bin/ @@ -2631,7 +2631,7 @@ - + ../../../../bin/ @@ -2658,7 +2658,7 @@ - + ../../../../bin/ @@ -2685,7 +2685,7 @@ - + ../../../../bin/ @@ -2712,7 +2712,7 @@ - + ../../../../bin/ @@ -2740,7 +2740,7 @@ - + ../../../bin/ @@ -2784,7 +2784,7 @@ - + ../../bin/ @@ -2807,7 +2807,7 @@ - + ../../../bin/ @@ -2857,7 +2857,7 @@ - + ../../../bin/ @@ -2899,7 +2899,7 @@ - + ../../../bin/ @@ -2930,7 +2930,7 @@ - + ../../../../bin/ @@ -2961,7 +2961,7 @@ - + ../../../../bin/ @@ -2991,7 +2991,7 @@ - + ../../../bin/ @@ -3062,7 +3062,7 @@ - + ../../../bin/ @@ -3121,7 +3121,7 @@ - + ../../../bin/ @@ -3179,7 +3179,7 @@ - + ../../../../../bin/ @@ -3216,7 +3216,7 @@ - + ../../../../../../bin/ @@ -3252,7 +3252,7 @@ - + ../../../bin/ @@ -3306,7 +3306,7 @@ TODO: this is kind of lame, we basically build a duplicate assembly but with tests added in, just because we can't resolve cross-bin-dir-refs. --> - + ../../../../../bin/ @@ -3336,7 +3336,7 @@ - + ../../../bin/ -- cgit v1.1 From beb7b8d189a99b4385392b2209930e20b489a0c9 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 18 Apr 2012 23:23:37 +0100 Subject: Fix a logic error in app domain creation --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index ad2f12e..23a4cf9 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1025,7 +1025,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine sandbox = AppDomain.CreateDomain( m_Scene.RegionInfo.RegionID.ToString(), evidence, appSetup); - m_AppDomains[appDomain].AssemblyResolve += + sandbox.AssemblyResolve += new ResolveEventHandler( AssemblyResolver.OnAssemblyResolve); } -- cgit v1.1 From 2b98e2f106f8a017cbaefcb2c21cc1bc9addde81 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 20 Apr 2012 02:50:36 +0100 Subject: Stop teleports from dropping tall avatars through or embedding them in the floor when lured by short avatars. This involves giving the ceiling of the Z-component in a lure rather than the floor. Ideally we would give the exact float compensating for relative avatar height but it looks like that isn't possible with the parcel id format used in lures --- OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs index d295384..2d4cffd 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs @@ -151,11 +151,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure Scene scene = (Scene)(client.Scene); ScenePresence presence = scene.GetScenePresence(client.AgentId); + // Round up Z co-ordinate rather than round-down by casting. This stops tall avatars from being given + // a teleport Z co-ordinate by short avatars that drops them through or embeds them in thin floors on + // arrival. + // + // Ideally we would give the exact float position adjusting for the relative height of the two avatars + // but it looks like a float component isn't possible with a parcel ID. UUID dest = Util.BuildFakeParcelID( scene.RegionInfo.RegionHandle, (uint)presence.AbsolutePosition.X, (uint)presence.AbsolutePosition.Y, - (uint)presence.AbsolutePosition.Z); + (uint)Math.Ceiling(presence.AbsolutePosition.Z)); m_log.DebugFormat("TP invite with message {0}", message); -- cgit v1.1 From f3dda2d85d5b72aa880a399805d052b241d3abef Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 20 Apr 2012 03:12:25 +0100 Subject: Add more exception detail to Exception and IOException throws in BaseHttpServer.HandleRequest() --- OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 9d8561b..0fbf90a 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -662,11 +662,11 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (IOException e) { - m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e); + m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}{1}", e.Message, e.StackTrace); } catch (Exception e) { - m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e.StackTrace); + m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}{1}", e.Message, e.StackTrace); SendHTML500(response); } finally -- cgit v1.1 From 63cda3a6d0910b74680cd343ab7bc07a6651f1cb Mon Sep 17 00:00:00 2001 From: Garmin Kawaguichi Date: Thu, 19 Apr 2012 15:47:56 +0200 Subject: concerns GenericSystemDrawing.cs in OpenSim\Region\CoreModules\World\Terrain\FileLoaders\GenericSystemDrawing.cs Ln 67 Apply Justin's solution Signed-off-by: Garmin Kawaguichi --- .../World/Terrain/FileLoaders/GenericSystemDrawing.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs index da81dc1..cd46276 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs @@ -64,18 +64,19 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders public virtual ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int w, int h) { - Bitmap bitmap = new Bitmap(filename); - ITerrainChannel retval = new TerrainChannel(true); - - for (int x = 0; x < retval.Width; x++) + using (Bitmap bitmap = new Bitmap(filename)) { - for (int y = 0; y < retval.Height; y++) + ITerrainChannel retval = new TerrainChannel(true); + + for (int x = 0; x < retval.Width; x++) { - retval[x, y] = bitmap.GetPixel(offsetX * retval.Width + x, (bitmap.Height - (retval.Height * (offsetY + 1))) + retval.Height - y - 1).GetBrightness() * 128; + for (int y = 0; y < retval.Height; y++) + { + retval[x, y] = bitmap.GetPixel(offsetX * retval.Width + x, (bitmap.Height - (retval.Height * (offsetY + 1))) + retval.Height - y - 1).GetBrightness() * 128; + } } + return retval; } - - return retval; } public virtual ITerrainChannel LoadStream(Stream stream) -- cgit v1.1 From 4ac2f839bdba84569877f5ab8c2e9ea0cfe87413 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 20 Apr 2012 03:32:38 +0100 Subject: Remember to dispose of the bitmap opened from a file in GatekeeperServiceConnector.GetMapImage() --- .../Connectors/Hypergrid/GatekeeperServiceConnector.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs index 0430ef6..19dffc3 100644 --- a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs @@ -154,7 +154,7 @@ namespace OpenSim.Services.Connectors.Hypergrid UUID mapTile = m_HGMapImage; string filename = string.Empty; - Bitmap bitmap = null; + try { WebClient c = new WebClient(); @@ -167,11 +167,18 @@ namespace OpenSim.Services.Connectors.Hypergrid c.DownloadFile(imageURL, filename); } else + { m_log.DebugFormat("[GATEKEEPER SERVICE CONNECTOR]: using cached image"); + } + + byte[] imageData = null; - bitmap = new Bitmap(filename); - //m_log.Debug("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width); - byte[] imageData = OpenJPEG.EncodeFromImage(bitmap, true); + using (Bitmap bitmap = new Bitmap(filename)) + { + //m_log.Debug("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width); + imageData = OpenJPEG.EncodeFromImage(bitmap, true); + } + AssetBase ass = new AssetBase(UUID.Random(), "region " + name, (sbyte)AssetType.Texture, regionID.ToString()); // !!! for now -- cgit v1.1 From cba64ebc79eaec9cd432d90b8cc48e22272d31f0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 20 Apr 2012 03:46:09 +0100 Subject: Explicitly dispose of bitmaps opened from files in GenericSystemDrawing and JPEG.cs --- .../Terrain/FileLoaders/GenericSystemDrawing.cs | 28 ++++++++++++++-------- .../CoreModules/World/Terrain/FileLoaders/JPEG.cs | 21 +++++++++------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs index cd46276..3921bf9 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs @@ -59,7 +59,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders /// A terrain channel generated from the image. public virtual ITerrainChannel LoadFile(string filename) { - return LoadBitmap(new Bitmap(filename)); + using (Bitmap b = new Bitmap(filename)) + return LoadBitmap(b); } public virtual ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int w, int h) @@ -75,13 +76,15 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders retval[x, y] = bitmap.GetPixel(offsetX * retval.Width + x, (bitmap.Height - (retval.Height * (offsetY + 1))) + retval.Height - y - 1).GetBrightness() * 128; } } + return retval; } } public virtual ITerrainChannel LoadStream(Stream stream) { - return LoadBitmap(new Bitmap(stream)); + using (Bitmap b = new Bitmap(stream)) + return LoadBitmap(b); } protected virtual ITerrainChannel LoadBitmap(Bitmap bitmap) @@ -227,16 +230,21 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders /// A System.Drawing.Bitmap containing a coloured image protected static Bitmap CreateBitmapFromMap(ITerrainChannel map) { - Bitmap gradientmapLd = new Bitmap("defaultstripe.png"); - - int pallete = gradientmapLd.Height; - - Bitmap bmp = new Bitmap(map.Width, map.Height); - Color[] colours = new Color[pallete]; + int pallete; + Bitmap bmp; + Color[] colours; - for (int i = 0; i < pallete; i++) + using (Bitmap gradientmapLd = new Bitmap("defaultstripe.png")) { - colours[i] = gradientmapLd.GetPixel(0, i); + pallete = gradientmapLd.Height; + + bmp = new Bitmap(map.Width, map.Height); + colours = new Color[pallete]; + + for (int i = 0; i < pallete; i++) + { + colours[i] = gradientmapLd.GetPixel(0, i); + } } for (int y = 0; y < map.Height; y++) diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs index 699d67a..9cc767a 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs @@ -99,16 +99,21 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders private static Bitmap CreateBitmapFromMap(ITerrainChannel map) { - Bitmap gradientmapLd = new Bitmap("defaultstripe.png"); + int pallete; + Bitmap bmp; + Color[] colours; - int pallete = gradientmapLd.Height; - - Bitmap bmp = new Bitmap(map.Width, map.Height); - Color[] colours = new Color[pallete]; - - for (int i = 0; i < pallete; i++) + using (Bitmap gradientmapLd = new Bitmap("defaultstripe.png")) { - colours[i] = gradientmapLd.GetPixel(0, i); + pallete = gradientmapLd.Height; + + bmp = new Bitmap(map.Width, map.Height); + colours = new Color[pallete]; + + for (int i = 0; i < pallete; i++) + { + colours[i] = gradientmapLd.GetPixel(0, i); + } } for (int y = 0; y < map.Height; y++) -- cgit v1.1 From 75f117484b8e45d0db4273f37cc993bf02f00fcb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 20 Apr 2012 03:57:22 +0100 Subject: Always dispose of existing opened bitmap from file in SaveFile(), instead of simply dropping the reference if the existing file didn't contain a bitmap of the same size. --- .../Terrain/FileLoaders/GenericSystemDrawing.cs | 59 ++++++++++++++-------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs index 3921bf9..039c3fa 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs @@ -138,35 +138,50 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders // "Saving the image to the same file it was constructed from is not allowed and throws an exception." string tempName = Path.GetTempFileName(); - Bitmap entireBitmap = null; - Bitmap thisBitmap = null; - if (File.Exists(filename)) + Bitmap existingBitmap = null; + Bitmap thisBitmap; + Bitmap newBitmap; + + try { - File.Copy(filename, tempName, true); - entireBitmap = new Bitmap(tempName); - if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY) + if (File.Exists(filename)) { - // old file, let's overwrite it - entireBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY); + File.Copy(filename, tempName, true); + existingBitmap = new Bitmap(tempName); + if (existingBitmap.Width != fileWidth * regionSizeX || existingBitmap.Height != fileHeight * regionSizeY) + { + // old file, let's overwrite it + newBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY); + } + else + { + newBitmap = existingBitmap; + } } + else + { + newBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY); + } + + thisBitmap = CreateGrayscaleBitmapFromMap(m_channel); + // Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY); + for (int x = 0; x < regionSizeX; x++) + for (int y = 0; y < regionSizeY; y++) + newBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y)); + + Save(newBitmap, filename); } - else + finally { - entireBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY); - } - - thisBitmap = CreateGrayscaleBitmapFromMap(m_channel); -// Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY); - for (int x = 0; x < regionSizeX; x++) - for (int y = 0; y < regionSizeY; y++) - entireBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y)); + if (existingBitmap != null) + existingBitmap.Dispose(); - Save(entireBitmap, filename); - thisBitmap.Dispose(); - entireBitmap.Dispose(); + thisBitmap.Dispose(); + newBitmap.Dispose(); - if (File.Exists(tempName)) - File.Delete(tempName); + if (File.Exists(tempName)) + File.Delete(tempName); + } } protected virtual void Save(Bitmap bmp, string filename) -- cgit v1.1 From 566327a9482506f2965e06b37172dc42f66cd6e5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 20 Apr 2012 23:24:24 +0100 Subject: If a physical prim is manually moved (e.g. by a user) then set the geometry position as well as the body position This is necessary to stop the moved prim snapping back to the original position on deselection if moved only once This resolves http://opensimulator.org/mantis/view.php?id=5966 --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 1f79cd8..7d67da3 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -1579,23 +1579,21 @@ Console.WriteLine(" JointCreateFixed"); //m_log.Debug("[BUG]: race!"); //} } - else - { - // string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); - // int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); -// _parent_scene.waitForSpaceUnlock(m_targetSpace); - IntPtr tempspace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace); - m_targetSpace = tempspace; + // string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); + // int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); +// _parent_scene.waitForSpaceUnlock(m_targetSpace); + + IntPtr tempspace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace); + m_targetSpace = tempspace; // _parent_scene.waitForSpaceUnlock(m_targetSpace); - if (prim_geom != IntPtr.Zero) - { - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + if (prim_geom != IntPtr.Zero) + { + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); // _parent_scene.waitForSpaceUnlock(m_targetSpace); - d.SpaceAdd(m_targetSpace, prim_geom); - } + d.SpaceAdd(m_targetSpace, prim_geom); } changeSelectedStatus(); -- cgit v1.1 From c8307cdf1e1f06f68fdf3f36d1facd295c77e88d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 20 Apr 2012 23:35:11 +0100 Subject: Improve bitmap disposal to do null checks and not to potentially try disposal of uninitialized variables. This issue doesn't cause the mono 2.10.5 compiler to fail but appears to cause the windows compiler to fail. Resolves http://opensimulator.org/mantis/view.php?id=5973 --- .../World/Terrain/FileLoaders/GenericSystemDrawing.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs index 039c3fa..d78ade5 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs @@ -139,8 +139,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders string tempName = Path.GetTempFileName(); Bitmap existingBitmap = null; - Bitmap thisBitmap; - Bitmap newBitmap; + Bitmap thisBitmap = null; + Bitmap newBitmap = null; try { @@ -176,8 +176,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders if (existingBitmap != null) existingBitmap.Dispose(); - thisBitmap.Dispose(); - newBitmap.Dispose(); + if (thisBitmap != null) + thisBitmap.Dispose(); + + if (newBitmap != null) + newBitmap.Dispose(); if (File.Exists(tempName)) File.Delete(tempName); -- cgit v1.1 From 7a574be3fd28ffbd9bce4cfa08451d705728fa20 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 21 Apr 2012 00:12:07 +0100 Subject: Remove redundant prim_geom != IntPtr.Zero checks in ODEPrim. prim_geom == IntPtr.Zero only before a new add prim taint is processed (which is the first taint) or in operations such as scale change which are done in taint or under lock. Therefore, we can remove these checks which were not consistently applied anyway. If there is a genuine problem, better to see it quickly in a NullReferenceException than hide the bug. --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 204 ++++++++++++---------------- 1 file changed, 88 insertions(+), 116 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 7d67da3..0a8cf75 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -156,7 +156,15 @@ namespace OpenSim.Region.Physics.OdePlugin /// public IntPtr m_targetSpace = IntPtr.Zero; + /// + /// The prim geometry, used for collision detection. + /// + /// + /// This is never null except for a brief period when the geometry needs to be replaced (due to resizing or + /// mesh change) or when the physical prim is being removed from the scene. + /// public IntPtr prim_geom { get; private set; } + public IntPtr _triMeshData { get; private set; } private IntPtr _linkJointGroup = IntPtr.Zero; @@ -325,14 +333,11 @@ namespace OpenSim.Region.Physics.OdePlugin { prim_geom = geom; //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name); - if (prim_geom != IntPtr.Zero) - { - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); - _parent_scene.geom_name_map[prim_geom] = Name; - _parent_scene.actor_name_map[prim_geom] = this; - } + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + + _parent_scene.geom_name_map[prim_geom] = Name; if (childPrim) { @@ -765,11 +770,8 @@ namespace OpenSim.Region.Physics.OdePlugin m_collisionCategories &= ~CollisionCategories.Body; m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); - if (prim_geom != IntPtr.Zero) - { - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); - } + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); d.BodyDestroy(Body); lock (childrenPrim) @@ -793,11 +795,8 @@ namespace OpenSim.Region.Physics.OdePlugin m_collisionCategories &= ~CollisionCategories.Body; m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); - if (prim_geom != IntPtr.Zero) - { - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); - } + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); Body = IntPtr.Zero; } @@ -864,10 +863,7 @@ namespace OpenSim.Region.Physics.OdePlugin // _parent_scene.waitForSpaceUnlock(m_targetSpace); try { - if (prim_geom == IntPtr.Zero) - { - SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null)); - } + SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null)); } catch (AccessViolationException) { @@ -890,73 +886,67 @@ namespace OpenSim.Region.Physics.OdePlugin #if SPAM Console.WriteLine("ZProcessTaints for " + Name); #endif + + // This must be processed as the very first taint so that later operations have a prim_geom to work with + // if this is a new prim. if (m_taintadd) - { changeadd(); - } - - if (prim_geom != IntPtr.Zero) - { - if (!_position.ApproxEquals(m_taintposition, 0f)) - changemove(); - if (m_taintrot != _orientation) - { - if (childPrim && IsPhysical) // For physical child prim... - { - rotate(); - // KF: ODE will also rotate the parent prim! - // so rotate the root back to where it was - OdePrim parent = (OdePrim)_parent; - parent.rotate(); - } - else - { - //Just rotate the prim - rotate(); - } + if (!_position.ApproxEquals(m_taintposition, 0f)) + changemove(); + + if (m_taintrot != _orientation) + { + if (childPrim && IsPhysical) // For physical child prim... + { + rotate(); + // KF: ODE will also rotate the parent prim! + // so rotate the root back to where it was + OdePrim parent = (OdePrim)_parent; + parent.rotate(); } - - if (m_taintPhysics != IsPhysical && !(m_taintparent != _parent)) - changePhysicsStatus(); + else + { + //Just rotate the prim + rotate(); + } + } + + if (m_taintPhysics != IsPhysical && !(m_taintparent != _parent)) + changePhysicsStatus(); - if (!_size.ApproxEquals(m_taintsize, 0f)) - changesize(); + if (!_size.ApproxEquals(m_taintsize, 0f)) + changesize(); - if (m_taintshape) - changeshape(); + if (m_taintshape) + changeshape(); - if (m_taintforce) - changeAddForce(); + if (m_taintforce) + changeAddForce(); - if (m_taintaddangularforce) - changeAddAngularForce(); + if (m_taintaddangularforce) + changeAddAngularForce(); - if (!m_taintTorque.ApproxEquals(Vector3.Zero, 0.001f)) - changeSetTorque(); + if (!m_taintTorque.ApproxEquals(Vector3.Zero, 0.001f)) + changeSetTorque(); - if (m_taintdisable) - changedisable(); + if (m_taintdisable) + changedisable(); - if (m_taintselected != m_isSelected) - changeSelectedStatus(); + if (m_taintselected != m_isSelected) + changeSelectedStatus(); - if (!m_taintVelocity.ApproxEquals(Vector3.Zero, 0.001f)) - changevelocity(); + if (!m_taintVelocity.ApproxEquals(Vector3.Zero, 0.001f)) + changevelocity(); - if (m_taintparent != _parent) - changelink(); + if (m_taintparent != _parent) + changelink(); - if (m_taintCollidesWater != m_collidesWater) - changefloatonwater(); + if (m_taintCollidesWater != m_collidesWater) + changefloatonwater(); - if (!m_angularlock.ApproxEquals(m_taintAngularLock,0f)) - changeAngularLock(); - } - else - { - m_log.ErrorFormat("[PHYSICS]: The scene reused a disposed PhysActor for {0}! *waves finger*, Don't be evil. A couple of things can cause this. An improper prim breakdown(be sure to set prim_geom to zero after d.GeomDestroy! An improper buildup (creating the geom failed). Or, the Scene Reused a physics actor after disposing it.)", Name); - } + if (!m_angularlock.ApproxEquals(m_taintAngularLock,0f)) + changeAngularLock(); } /// @@ -1093,18 +1083,10 @@ Console.WriteLine("ZProcessTaints for " + Name); prm.m_collisionCategories |= CollisionCategories.Body; prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); - if (prm.prim_geom == IntPtr.Zero) - { - m_log.WarnFormat( - "[PHYSICS]: Unable to link one of the linkset elements {0} for parent {1}. No geom yet", - prm.Name, prim.Name); - continue; - } //Console.WriteLine(" GeomSetCategoryBits 1: " + prm.prim_geom + " - " + (int)prm.m_collisionCategories + " for " + Name); d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); - d.Quaternion quat = new d.Quaternion(); quat.W = prm._orientation.W; quat.X = prm._orientation.X; @@ -1303,11 +1285,8 @@ Console.WriteLine("ZProcessTaints for " + Name); disableBodySoft(); } - if (prim_geom != IntPtr.Zero) - { - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); - } + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); if (IsPhysical) { @@ -1328,11 +1307,8 @@ Console.WriteLine("ZProcessTaints for " + Name); if (m_collidesWater) m_collisionFlags |= CollisionCategories.Water; - if (prim_geom != IntPtr.Zero) - { - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); - } + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); if (IsPhysical) { @@ -1472,6 +1448,9 @@ Console.WriteLine("CreateGeom:"); } else { + m_log.WarnFormat( + "[ODE PRIM]: Called RemoveGeom() on {0} {1} where geometry was already null.", Name, LocalID); + return false; } } @@ -1505,16 +1484,13 @@ Console.WriteLine("changeadd 1"); #endif CreateGeom(m_targetSpace, mesh); - if (prim_geom != IntPtr.Zero) - { - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); - d.Quaternion myrot = new d.Quaternion(); - myrot.X = _orientation.X; - myrot.Y = _orientation.Y; - myrot.Z = _orientation.Z; - myrot.W = _orientation.W; - d.GeomSetQuaternion(prim_geom, ref myrot); - } + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + d.Quaternion myrot = new d.Quaternion(); + myrot.X = _orientation.X; + myrot.Y = _orientation.Y; + myrot.Z = _orientation.Z; + myrot.W = _orientation.W; + d.GeomSetQuaternion(prim_geom, ref myrot); if (IsPhysical && Body == IntPtr.Zero) enableBody(); @@ -1588,13 +1564,11 @@ Console.WriteLine(" JointCreateFixed"); m_targetSpace = tempspace; // _parent_scene.waitForSpaceUnlock(m_targetSpace); - if (prim_geom != IntPtr.Zero) - { - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); // _parent_scene.waitForSpaceUnlock(m_targetSpace); - d.SpaceAdd(m_targetSpace, prim_geom); - } + d.SpaceAdd(m_targetSpace, prim_geom); changeSelectedStatus(); @@ -2045,18 +2019,16 @@ Console.WriteLine(" JointCreateFixed"); { m_collidesWater = m_taintCollidesWater; - if (prim_geom != IntPtr.Zero) + if (m_collidesWater) { - if (m_collidesWater) - { - m_collisionFlags |= CollisionCategories.Water; - } - else - { - m_collisionFlags &= ~CollisionCategories.Water; - } - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + m_collisionFlags |= CollisionCategories.Water; + } + else + { + m_collisionFlags &= ~CollisionCategories.Water; } + + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } /// -- cgit v1.1 From 06552f217ebd9301fd487c788a13fd75d61a46de Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 21 Apr 2012 00:54:48 +0100 Subject: Add TestSetPhysics() to SOP status tests --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 9 ++++++--- .../Framework/Scenes/Tests/SceneObjectStatusTests.cs | 20 ++++++++++++++++++++ OpenSim/Tests/Common/Helpers/SceneHelpers.cs | 2 +- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 046553b..d2cd37d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1706,6 +1706,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew) { + if (ParentGroup.Scene == null) + return; + if (!ParentGroup.Scene.PhysicalPrims && UsePhysics) return; @@ -4161,7 +4164,7 @@ namespace OpenSim.Region.Framework.Scenes // For now, we use the NINJA naming scheme for identifying joints. // In the future, we can support other joint specification schemes such as a // custom checkbox in the viewer GUI. - if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) + if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) { string hingeString = "hingejoint"; return (Name.Length >= hingeString.Length && Name.Substring(0, hingeString.Length) == hingeString); @@ -4177,7 +4180,7 @@ namespace OpenSim.Region.Framework.Scenes // For now, we use the NINJA naming scheme for identifying joints. // In the future, we can support other joint specification schemes such as a // custom checkbox in the viewer GUI. - if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) + if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) { string ballString = "balljoint"; return (Name.Length >= ballString.Length && Name.Substring(0, ballString.Length) == ballString); @@ -4193,7 +4196,7 @@ namespace OpenSim.Region.Framework.Scenes // For now, we use the NINJA naming scheme for identifying joints. // In the future, we can support other joint specification schemes such as a // custom checkbox in the viewer GUI. - if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) + if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) { return IsHingeJoint() || IsBallJoint(); } diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index 2a342d5..16e8b63 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -62,5 +62,25 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); } + + [Test] + public void TestSetPhysics() + { + TestHelpers.InMethod(); + +// Scene scene = SceneSetupHelpers.SetupScene(); + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, UUID.Zero); + SceneObjectPart rootPart = so.RootPart; + Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); + + so.ScriptSetPhysicsStatus(true); + +// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags); + Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Physics)); + + so.ScriptSetPhysicsStatus(false); + + Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); + } } } \ No newline at end of file diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index 318758d..7a6b1cf 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs @@ -153,7 +153,7 @@ namespace OpenSim.Tests.Common PhysicsPluginManager physicsPluginManager = new PhysicsPluginManager(); physicsPluginManager.LoadPluginsFromAssembly("Physics/OpenSim.Region.Physics.BasicPhysicsPlugin.dll"); testScene.PhysicsScene - = physicsPluginManager.GetPhysicsScene("basicphysics", "ZeroMesher", new IniConfigSource(), "test"); + = physicsPluginManager.GetPhysicsScene("basicphysics", "ZeroMesher", new IniConfigSource(), "test"); testScene.RegionInfo.EstateSettings = new EstateSettings(); testScene.LoginsDisabled = false; -- cgit v1.1 From 71900968b221b89860d1cef162f3b0d1236e1c73 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 21 Apr 2012 01:01:24 +0100 Subject: refactor: extract common setup code in SceneObjectStatusTests --- .../Scenes/Tests/SceneObjectStatusTests.cs | 26 +++++++++++++--------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index 16e8b63..b8e1b92 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -43,22 +43,30 @@ namespace OpenSim.Region.Framework.Scenes.Tests [TestFixture] public class SceneObjectStatusTests { + private TestScene m_scene; + private SceneObjectGroup m_so1; + + [SetUp] + public void Init() + { + m_scene = SceneHelpers.SetupScene(); + SceneObjectGroup m_so1 = SceneHelpers.CreateSceneObject(1, UUID.Zero); + } + [Test] public void TestSetPhantom() { TestHelpers.InMethod(); -// Scene scene = SceneSetupHelpers.SetupScene(); - SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, UUID.Zero); - SceneObjectPart rootPart = so.RootPart; + SceneObjectPart rootPart = m_so1.RootPart; Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); - so.ScriptSetPhantomStatus(true); + m_so1.ScriptSetPhantomStatus(true); // Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags); Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom)); - so.ScriptSetPhantomStatus(false); + m_so1.ScriptSetPhantomStatus(false); Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); } @@ -68,17 +76,15 @@ namespace OpenSim.Region.Framework.Scenes.Tests { TestHelpers.InMethod(); -// Scene scene = SceneSetupHelpers.SetupScene(); - SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, UUID.Zero); - SceneObjectPart rootPart = so.RootPart; + SceneObjectPart rootPart = m_so1.RootPart; Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); - so.ScriptSetPhysicsStatus(true); + m_so1.ScriptSetPhysicsStatus(true); // Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags); Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Physics)); - so.ScriptSetPhysicsStatus(false); + m_so1.ScriptSetPhysicsStatus(false); Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); } -- cgit v1.1 From 17bf2a62db39ba58ca691a6754bf79fe6b3ee474 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 21 Apr 2012 01:09:19 +0100 Subject: Add test for correct physics status on linking two physics objects Also fixes last build break. --- .../Scenes/Tests/SceneObjectStatusTests.cs | 28 ++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index b8e1b92..6270ac1 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -26,6 +26,7 @@ */ using System; +using System.Collections.Generic; using System.Reflection; using NUnit.Framework; using OpenMetaverse; @@ -44,13 +45,16 @@ namespace OpenSim.Region.Framework.Scenes.Tests public class SceneObjectStatusTests { private TestScene m_scene; + private UUID m_ownerId = TestHelpers.ParseTail(0x1); private SceneObjectGroup m_so1; + private SceneObjectGroup m_so2; [SetUp] public void Init() { m_scene = SceneHelpers.SetupScene(); - SceneObjectGroup m_so1 = SceneHelpers.CreateSceneObject(1, UUID.Zero); + m_so1 = SceneHelpers.CreateSceneObject(1, m_ownerId, "so1", 0x10); + m_so2 = SceneHelpers.CreateSceneObject(1, m_ownerId, "so2", 0x20); } [Test] @@ -86,7 +90,27 @@ namespace OpenSim.Region.Framework.Scenes.Tests m_so1.ScriptSetPhysicsStatus(false); - Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); + Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); + } + + /// + /// Test that linking results in the correct physical status for all linkees. + /// + [Test] + public void TestLinkPhysicsBothPhysical() + { + TestHelpers.InMethod(); + + m_scene.AddSceneObject(m_so1); + m_scene.AddSceneObject(m_so2); + + m_so1.ScriptSetPhysicsStatus(true); + m_so2.ScriptSetPhysicsStatus(true); + + m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List() { m_so2.LocalId }); + + Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics)); + Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics)); } } } \ No newline at end of file -- cgit v1.1 From 9ac48b2aff2ddd00821b7e6ecd71ce134f7a0f25 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 21 Apr 2012 01:43:09 +0100 Subject: Fix a bug where linking a non-physical prim with a physical prim as root would make the non-physical prim phantom rather than part of the physics object. On region restart, the whole object would become physical as expected. Observed behaviour from elsewhere is that all prims in a new linkset should take on the status of the root prim. Add regression test for this behaviour. --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 3 +++ .../Framework/Scenes/Tests/SceneObjectStatusTests.cs | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 8e786c1..49a3485 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2010,6 +2010,7 @@ namespace OpenSim.Region.Framework.Scenes linkPart.CreateSelected = true; linkPart.LinkNum = linkNum++; + linkPart.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect); SceneObjectPart[] ogParts = objectGroup.Parts; Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b) @@ -2220,6 +2221,8 @@ namespace OpenSim.Region.Framework.Scenes oldRot = part.RotationOffset; Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot; part.RotationOffset = newRot; + + part.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect); } /// diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index 6270ac1..91f4a34 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -112,5 +112,24 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics)); Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics)); } + + /// + /// Test that linking results in the correct physical status for all linkees. + /// + [Test] + public void TestLinkPhysicsRootPhysicalOnly() + { + TestHelpers.InMethod(); + + m_scene.AddSceneObject(m_so1); + m_scene.AddSceneObject(m_so2); + + m_so1.ScriptSetPhysicsStatus(true); + + m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List() { m_so2.LocalId }); + + Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics)); + Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics)); + } } } \ No newline at end of file -- cgit v1.1 From d5c724e5b8cc15ce278b80070238e72a2e4ea0e8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 21 Apr 2012 01:51:57 +0100 Subject: Add regression test for prim status when root prim in a new linkset is non-physical --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- .../Framework/Scenes/Tests/SceneObjectStatusTests.cs | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index d2cd37d..1592131 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1708,7 +1708,7 @@ namespace OpenSim.Region.Framework.Scenes { if (ParentGroup.Scene == null) return; - + if (!ParentGroup.Scene.PhysicalPrims && UsePhysics) return; diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index 91f4a34..8cdd645 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -131,5 +131,24 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics)); Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics)); } + + /// + /// Test that linking results in the correct physical status for all linkees. + /// + [Test] + public void TestLinkPhysicsChildPhysicalOnly() + { + TestHelpers.InMethod(); + + m_scene.AddSceneObject(m_so1); + m_scene.AddSceneObject(m_so2); + + m_so2.ScriptSetPhysicsStatus(true); + + m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List() { m_so2.LocalId }); + + Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.None)); + Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.None)); + } } } \ No newline at end of file -- cgit v1.1 From 77a7de87e1c89385bc906d1b409ec1c94c41b9e6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 21 Apr 2012 02:45:16 +0100 Subject: Add test for setting physics in a linkset --- .../Scenes/Tests/SceneObjectStatusTests.cs | 30 ++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index 8cdd645..882031c 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests } [Test] - public void TestSetPhantom() + public void TestSetPhantomSinglePrim() { TestHelpers.InMethod(); @@ -76,7 +76,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests } [Test] - public void TestSetPhysics() + public void TestSetPhysicsSinglePrim() { TestHelpers.InMethod(); @@ -92,6 +92,32 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); } + + [Test] + public void TestSetPhysicsLinkset() + { + TestHelpers.InMethod(); + + m_scene.AddSceneObject(m_so1); + m_scene.AddSceneObject(m_so2); + + m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List() { m_so2.LocalId }); + + m_so1.ScriptSetPhysicsStatus(true); + + Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics)); + Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics)); + + m_so1.ScriptSetPhysicsStatus(false); + + Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.None)); + Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.None)); + + m_so1.ScriptSetPhysicsStatus(true); + + Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics)); + Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics)); + } /// /// Test that linking results in the correct physical status for all linkees. -- cgit v1.1 From f60959459574b1473dbe35d780aa0fbe4d688580 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 21 Apr 2012 03:23:51 +0100 Subject: refactor: Simplify ODEPrim.AddChildPrim() by returning early where appropriate. --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 232 ++++++++++++++-------------- 1 file changed, 117 insertions(+), 115 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 0a8cf75..cbb49ac 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -1042,142 +1042,144 @@ Console.WriteLine("ZProcessTaints for " + Name); /// Child prim private void AddChildPrim(OdePrim prim) { -//Console.WriteLine("AddChildPrim " + Name); - if (LocalID != prim.LocalID) + if (LocalID == prim.LocalID) + return; + + if (Body == IntPtr.Zero) { - if (Body == IntPtr.Zero) + Body = d.BodyCreate(_parent_scene.world); + setMass(); + } + + lock (childrenPrim) + { + if (childrenPrim.Contains(prim)) + return; + +//Console.WriteLine("childrenPrim.Add " + prim); + childrenPrim.Add(prim); + + foreach (OdePrim prm in childrenPrim) { - Body = d.BodyCreate(_parent_scene.world); - setMass(); + d.Mass m2; + d.MassSetZero(out m2); + d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z); + + d.Quaternion quat = new d.Quaternion(); + quat.W = prm._orientation.W; + quat.X = prm._orientation.X; + quat.Y = prm._orientation.Y; + quat.Z = prm._orientation.Z; + + d.Matrix3 mat = new d.Matrix3(); + d.RfromQ(out mat, ref quat); + d.MassRotate(ref m2, ref mat); + d.MassTranslate(ref m2, Position.X - prm.Position.X, Position.Y - prm.Position.Y, Position.Z - prm.Position.Z); + d.MassAdd(ref pMass, ref m2); } - if (Body != IntPtr.Zero) + + foreach (OdePrim prm in childrenPrim) { - lock (childrenPrim) - { - if (!childrenPrim.Contains(prim)) - { -//Console.WriteLine("childrenPrim.Add " + prim); - childrenPrim.Add(prim); - - foreach (OdePrim prm in childrenPrim) - { - d.Mass m2; - d.MassSetZero(out m2); - d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z); - - d.Quaternion quat = new d.Quaternion(); - quat.W = prm._orientation.W; - quat.X = prm._orientation.X; - quat.Y = prm._orientation.Y; - quat.Z = prm._orientation.Z; - - d.Matrix3 mat = new d.Matrix3(); - d.RfromQ(out mat, ref quat); - d.MassRotate(ref m2, ref mat); - d.MassTranslate(ref m2, Position.X - prm.Position.X, Position.Y - prm.Position.Y, Position.Z - prm.Position.Z); - d.MassAdd(ref pMass, ref m2); - } - - foreach (OdePrim prm in childrenPrim) - { - prm.m_collisionCategories |= CollisionCategories.Body; - prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); + prm.m_collisionCategories |= CollisionCategories.Body; + prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); //Console.WriteLine(" GeomSetCategoryBits 1: " + prm.prim_geom + " - " + (int)prm.m_collisionCategories + " for " + Name); - d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); - d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); - - d.Quaternion quat = new d.Quaternion(); - quat.W = prm._orientation.W; - quat.X = prm._orientation.X; - quat.Y = prm._orientation.Y; - quat.Z = prm._orientation.Z; - - d.Matrix3 mat = new d.Matrix3(); - d.RfromQ(out mat, ref quat); - if (Body != IntPtr.Zero) - { - d.GeomSetBody(prm.prim_geom, Body); - prm.childPrim = true; - d.GeomSetOffsetWorldPosition(prm.prim_geom, prm.Position.X , prm.Position.Y, prm.Position.Z); - //d.GeomSetOffsetPosition(prim.prim_geom, - // (Position.X - prm.Position.X) - pMass.c.X, - // (Position.Y - prm.Position.Y) - pMass.c.Y, - // (Position.Z - prm.Position.Z) - pMass.c.Z); - d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); - //d.GeomSetOffsetRotation(prm.prim_geom, ref mat); - d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); - d.BodySetMass(Body, ref pMass); - } - else - { - m_log.DebugFormat("[PHYSICS]: {0} ain't got no boooooooooddy, no body", Name); - } + d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); + d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); - prm.m_interpenetrationcount = 0; - prm.m_collisionscore = 0; - prm.m_disabled = false; + d.Quaternion quat = new d.Quaternion(); + quat.W = prm._orientation.W; + quat.X = prm._orientation.X; + quat.Y = prm._orientation.Y; + quat.Z = prm._orientation.Z; - // The body doesn't already have a finite rotation mode set here - if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) - { - prm.createAMotor(m_angularlock); - } - prm.Body = Body; - _parent_scene.ActivatePrim(prm); - } + d.Matrix3 mat = new d.Matrix3(); + d.RfromQ(out mat, ref quat); + if (Body != IntPtr.Zero) + { + d.GeomSetBody(prm.prim_geom, Body); + prm.childPrim = true; + d.GeomSetOffsetWorldPosition(prm.prim_geom, prm.Position.X , prm.Position.Y, prm.Position.Z); + //d.GeomSetOffsetPosition(prim.prim_geom, + // (Position.X - prm.Position.X) - pMass.c.X, + // (Position.Y - prm.Position.Y) - pMass.c.Y, + // (Position.Z - prm.Position.Z) - pMass.c.Z); + d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); + //d.GeomSetOffsetRotation(prm.prim_geom, ref mat); + d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); + d.BodySetMass(Body, ref pMass); + } + else + { + m_log.DebugFormat("[PHYSICS]: {0} ain't got no boooooooooddy, no body", Name); + } + + prm.m_interpenetrationcount = 0; + prm.m_collisionscore = 0; + prm.m_disabled = false; + + // The body doesn't already have a finite rotation mode set here + if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) + { + prm.createAMotor(m_angularlock); + } + prm.Body = Body; + _parent_scene.ActivatePrim(prm); + } - m_collisionCategories |= CollisionCategories.Body; - m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); + m_collisionCategories |= CollisionCategories.Body; + m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); //Console.WriteLine("GeomSetCategoryBits 2: " + prim_geom + " - " + (int)m_collisionCategories + " for " + Name); - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); //Console.WriteLine(" Post GeomSetCategoryBits 2"); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); - - d.Quaternion quat2 = new d.Quaternion(); - quat2.W = _orientation.W; - quat2.X = _orientation.X; - quat2.Y = _orientation.Y; - quat2.Z = _orientation.Z; - - d.Matrix3 mat2 = new d.Matrix3(); - d.RfromQ(out mat2, ref quat2); - d.GeomSetBody(prim_geom, Body); - d.GeomSetOffsetWorldPosition(prim_geom, Position.X - pMass.c.X, Position.Y - pMass.c.Y, Position.Z - pMass.c.Z); - //d.GeomSetOffsetPosition(prim.prim_geom, - // (Position.X - prm.Position.X) - pMass.c.X, - // (Position.Y - prm.Position.Y) - pMass.c.Y, - // (Position.Z - prm.Position.Z) - pMass.c.Z); - //d.GeomSetOffsetRotation(prim_geom, ref mat2); - d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); - d.BodySetMass(Body, ref pMass); - - d.BodySetAutoDisableFlag(Body, true); - d.BodySetAutoDisableSteps(Body, body_autodisable_frames); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); - m_interpenetrationcount = 0; - m_collisionscore = 0; - m_disabled = false; + d.Quaternion quat2 = new d.Quaternion(); + quat2.W = _orientation.W; + quat2.X = _orientation.X; + quat2.Y = _orientation.Y; + quat2.Z = _orientation.Z; - // The body doesn't already have a finite rotation mode set here - if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) - { - createAMotor(m_angularlock); - } - d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); - if (m_vehicle.Type != Vehicle.TYPE_NONE) - m_vehicle.Enable(Body, _parent_scene); + d.Matrix3 mat2 = new d.Matrix3(); + d.RfromQ(out mat2, ref quat2); + d.GeomSetBody(prim_geom, Body); + d.GeomSetOffsetWorldPosition(prim_geom, Position.X - pMass.c.X, Position.Y - pMass.c.Y, Position.Z - pMass.c.Z); + //d.GeomSetOffsetPosition(prim.prim_geom, + // (Position.X - prm.Position.X) - pMass.c.X, + // (Position.Y - prm.Position.Y) - pMass.c.Y, + // (Position.Z - prm.Position.Z) - pMass.c.Z); + //d.GeomSetOffsetRotation(prim_geom, ref mat2); + d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); + d.BodySetMass(Body, ref pMass); - _parent_scene.ActivatePrim(this); - } - } + d.BodySetAutoDisableFlag(Body, true); + d.BodySetAutoDisableSteps(Body, body_autodisable_frames); + + m_interpenetrationcount = 0; + m_collisionscore = 0; + m_disabled = false; + + // The body doesn't already have a finite rotation mode set here + if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) + { + createAMotor(m_angularlock); } + + d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); + + if (m_vehicle.Type != Vehicle.TYPE_NONE) + m_vehicle.Enable(Body, _parent_scene); + + _parent_scene.ActivatePrim(this); } } private void ChildSetGeom(OdePrim odePrim) { +// m_log.DebugFormat( +// "[ODE PRIM]: ChildSetGeom {0} {1} for {2} {3}", odePrim.Name, odePrim.LocalID, Name, LocalID); + //if (IsPhysical && Body != IntPtr.Zero) lock (childrenPrim) { -- cgit v1.1 From ae2b8f70074e4dfe2cbbd03dd543c7468fc50cc1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 21 Apr 2012 03:42:54 +0100 Subject: Comment out spurious Body != IntPtr.Zero code after disableBody(), since disableBody() sets Body == IntPtr.Zero on all code paths. --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 27 ++++++++++++++++++--------- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 3 ++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index cbb49ac..3f88353 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -1056,7 +1056,9 @@ Console.WriteLine("ZProcessTaints for " + Name); if (childrenPrim.Contains(prim)) return; -//Console.WriteLine("childrenPrim.Add " + prim); +// m_log.DebugFormat( +// "[ODE PRIM]: Linking prim {0} {1} to {2} {3}", prim.Name, prim.LocalID, Name, LocalID); + childrenPrim.Add(prim); foreach (OdePrim prm in childrenPrim) @@ -1194,12 +1196,14 @@ Console.WriteLine("ZProcessTaints for " + Name); //prm.childPrim = false; } } + disableBody(); - if (Body != IntPtr.Zero) - { - _parent_scene.DeactivatePrim(this); - } + // Spurious - Body == IntPtr.Zero after disableBody() +// if (Body != IntPtr.Zero) +// { +// _parent_scene.DeactivatePrim(this); +// } lock (childrenPrim) { @@ -1213,6 +1217,9 @@ Console.WriteLine("ZProcessTaints for " + Name); private void ChildDelink(OdePrim odePrim) { +// m_log.DebugFormat( +// "[ODE PRIM]: Delinking prim {0} {1} from {2} {3}", odePrim.Name, odePrim.LocalID, Name, LocalID); + // Okay, we have a delinked child.. need to rebuild the body. lock (childrenPrim) { @@ -1227,6 +1234,7 @@ Console.WriteLine("ZProcessTaints for " + Name); //prm.childPrim = false; } } + disableBody(); lock (childrenPrim) @@ -1235,10 +1243,11 @@ Console.WriteLine("ZProcessTaints for " + Name); childrenPrim.Remove(odePrim); } - if (Body != IntPtr.Zero) - { - _parent_scene.DeactivatePrim(this); - } + // Spurious - Body == IntPtr.Zero after disableBody() +// if (Body != IntPtr.Zero) +// { +// _parent_scene.DeactivatePrim(this); +// } lock (childrenPrim) { diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 842ff91..409b27b 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -2226,7 +2226,8 @@ namespace OpenSim.Region.Physics.OdePlugin /// internal void RemovePrimThreadLocked(OdePrim prim) { -//Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); +// m_log.DebugFormat("[ODE SCENE]: Removing physical prim {0} {1}", prim.Name, prim.LocalID); + lock (prim) { RemoveCollisionEventReporting(prim); -- cgit v1.1 From 8205fe79ceaeebd31509a044005bf27d226dbe07 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sun, 22 Apr 2012 19:51:51 +0100 Subject: Fix bug where setting phantom on a prim would result in a server log message rather than setting phantom. This was an oversight when removing some race conditions from PhysicsActor setting recently. Regression tests extended to probe this code path. Extending regression tests required implementation of a BasicPhysicsPrim (there was none before). However, BasicPhysics plugin is still of no current practical use other than to fill in as a component for other parts of regression testing. --- .../World/Archiver/Tests/ArchiverTests.cs | 4 +- OpenSim/Region/Framework/Scenes/Scene.cs | 14 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 9 +- .../Scenes/Tests/SceneObjectStatusTests.cs | 2 + .../Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs | 344 +++++++++++++++++++++ .../BasicPhysicsPlugin/BasicPhysicsScene.cs | 41 +-- 6 files changed, 382 insertions(+), 32 deletions(-) create mode 100644 OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index 63f1363..e05e8f6 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -102,9 +102,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere(); Vector3 groupPosition = new Vector3(10, 20, 30); Quaternion rotationOffset = new Quaternion(20, 30, 40, 50); - Vector3 offsetPosition = new Vector3(5, 10, 15); +// Vector3 offsetPosition = new Vector3(5, 10, 15); - return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName }; + return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, Vector3.Zero) { Name = partName }; } protected SceneObjectPart CreateSceneObjectPart2() diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e488fe1..a87dfb7 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -684,8 +684,8 @@ namespace OpenSim.Region.Framework.Scenes //Animation states m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); - PhysicalPrims = startupConfig.GetBoolean("physical_prim", true); - CollidablePrims = startupConfig.GetBoolean("collidable_prim", true); + PhysicalPrims = startupConfig.GetBoolean("physical_prim", PhysicalPrims); + CollidablePrims = startupConfig.GetBoolean("collidable_prim", CollidablePrims); m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys); if (RegionInfo.NonphysPrimMax > 0) @@ -800,13 +800,11 @@ namespace OpenSim.Region.Framework.Scenes StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; } - /// - /// Mock constructor for scene group persistency unit tests. - /// SceneObjectGroup RegionId property is delegated to Scene. - /// - /// public Scene(RegionInfo regInfo) { + PhysicalPrims = true; + CollidablePrims = true; + BordersLocked = true; Border northBorder = new Border(); northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<--- @@ -833,8 +831,6 @@ namespace OpenSim.Region.Framework.Scenes m_eventManager = new EventManager(); m_permissions = new ScenePermissions(this); - -// m_lastUpdate = Util.EnvironmentTickCount(); } #endregion diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 1592131..4bec2d4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4290,7 +4290,10 @@ namespace OpenSim.Region.Framework.Scenes AddFlag(PrimFlags.Phantom); if (PhysActor != null) + { RemoveFromPhysics(); + pa = null; + } } else // Not phantom { @@ -4356,7 +4359,7 @@ namespace OpenSim.Region.Framework.Scenes { pa.SetVolumeDetect(1); AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active - this.VolumeDetectActive = true; + VolumeDetectActive = true; } } else @@ -4364,9 +4367,9 @@ namespace OpenSim.Region.Framework.Scenes // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like // (mumbles, well, at least if you have infinte CPU powers :-)) if (pa != null) - PhysActor.SetVolumeDetect(0); + pa.SetVolumeDetect(0); - this.VolumeDetectActive = false; + VolumeDetectActive = false; } if (SetTemporary) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index 882031c..51751ef 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -62,6 +62,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests { TestHelpers.InMethod(); + m_scene.AddSceneObject(m_so1); + SceneObjectPart rootPart = m_so1.RootPart; Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs new file mode 100644 index 0000000..ba7fe1e --- /dev/null +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs @@ -0,0 +1,344 @@ +/* + * 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 Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; + +namespace OpenSim.Region.Physics.BasicPhysicsPlugin +{ + public class BasicPhysicsPrim : PhysicsActor + { + private Vector3 _position; + private Vector3 _velocity; + private Vector3 _acceleration; + private Vector3 _size; + private PrimitiveBaseShape _shape; + private Vector3 m_rotationalVelocity; + private bool flying; + private bool iscolliding; + + public BasicPhysicsPrim( + string name, uint localId, Vector3 position, Vector3 size, Quaternion orientation, PrimitiveBaseShape shape) + { + Name = name; + LocalID = localId; + Position = position; + Size = size; + Orientation = orientation; + Shape = shape; + } + + public override int PhysicsActorType + { + get { return (int) ActorTypes.Agent; } + set { return; } + } + + public override Vector3 RotationalVelocity + { + get { return m_rotationalVelocity; } + set { m_rotationalVelocity = value; } + } + + public override bool SetAlwaysRun + { + get { return false; } + set { return; } + } + + public override uint LocalID + { + set { return; } + } + + public override bool Grabbed + { + set { return; } + } + + public override bool Selected + { + set { return; } + } + + public override float Buoyancy + { + get { return 0f; } + set { return; } + } + + public override bool FloatOnWater + { + set { return; } + } + + public override bool IsPhysical + { + get { return false; } + set { return; } + } + + public override bool ThrottleUpdates + { + get { return false; } + set { return; } + } + + public override bool Flying + { + get { return flying; } + set { flying = value; } + } + + public override bool IsColliding + { + get { return iscolliding; } + set { iscolliding = value; } + } + + public override bool CollidingGround + { + get { return false; } + set { return; } + } + + public override bool CollidingObj + { + get { return false; } + set { return; } + } + + public override bool Stopped + { + get { return false; } + } + + public override Vector3 Position + { + get { return _position; } + set { _position = value; } + } + + public override Vector3 Size + { + get { return _size; } + set { + _size = value; + _size.Z = _size.Z / 2.0f; + } + } + + public override PrimitiveBaseShape Shape + { + set { _shape = value; } + } + + public override float Mass + { + get { return 0f; } + } + + public override Vector3 Force + { + get { return Vector3.Zero; } + set { return; } + } + + public override int VehicleType + { + get { return 0; } + set { return; } + } + + public override void VehicleFloatParam(int param, float value) + { + + } + + public override void VehicleVectorParam(int param, Vector3 value) + { + + } + + public override void VehicleRotationParam(int param, Quaternion rotation) + { + + } + + public override void VehicleFlags(int param, bool remove) + { + + } + + public override void SetVolumeDetect(int param) + { + + } + + public override Vector3 CenterOfMass + { + get { return Vector3.Zero; } + } + + public override Vector3 GeometricCenter + { + get { return Vector3.Zero; } + } + + public override Vector3 Velocity + { + get { return _velocity; } + set { _velocity = value; } + } + + public override Vector3 Torque + { + get { return Vector3.Zero; } + set { return; } + } + + public override float CollisionScore + { + get { return 0f; } + set { } + } + + public override Quaternion Orientation { get; set; } + + public override Vector3 Acceleration + { + get { return _acceleration; } + set { _acceleration = value; } + } + + public override bool Kinematic + { + get { return true; } + set { } + } + + public override void link(PhysicsActor obj) + { + } + + public override void delink() + { + } + + public override void LockAngularMotion(Vector3 axis) + { + } + + public override void AddForce(Vector3 force, bool pushforce) + { + } + + public override void AddAngularForce(Vector3 force, bool pushforce) + { + } + + public override void SetMomentum(Vector3 momentum) + { + } + + public override void CrossingFailure() + { + } + + public override Vector3 PIDTarget + { + set { return; } + } + + public override bool PIDActive + { + set { return; } + } + + public override float PIDTau + { + set { return; } + } + + public override float PIDHoverHeight + { + set { return; } + } + + public override bool PIDHoverActive + { + set { return; } + } + + public override PIDHoverType PIDHoverType + { + set { return; } + } + + public override float PIDHoverTau + { + set { return; } + } + + public override Quaternion APIDTarget + { + set { return; } + } + + public override bool APIDActive + { + set { return; } + } + + public override float APIDStrength + { + set { return; } + } + + public override float APIDDamping + { + set { return; } + } + + public override void SubscribeEvents(int ms) + { + } + + public override void UnSubscribeEvents() + { + } + + public override bool SubscribedEvents() + { + return false; + } + } +} diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs index 2e14216..f5826ed 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs @@ -34,9 +34,17 @@ using OpenSim.Region.Physics.Manager; namespace OpenSim.Region.Physics.BasicPhysicsPlugin { + /// + /// This is an incomplete extremely basic physics implementation + /// + /// + /// Not useful for anything at the moment apart from some regression testing in other components where some form + /// of physics plugin is needed. + /// public class BasicScene : PhysicsScene { private List _actors = new List(); + private List _prims = new List(); private float[] _heightMap; //protected internal string sceneIdentifier; @@ -50,10 +58,19 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin { } - public override void Dispose() + public override void Dispose() {} + + public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, + Vector3 size, Quaternion rotation, bool isPhysical, uint localid) { + BasicPhysicsPrim prim = new BasicPhysicsPrim(primName, localid, position, size, rotation, pbs); + prim.IsPhysical = isPhysical; + + _prims.Add(prim); + return prim; } + public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) { BasicActor act = new BasicActor(size); @@ -63,30 +80,18 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin return act; } - public override void RemovePrim(PhysicsActor prim) + public override void RemovePrim(PhysicsActor actor) { + BasicPhysicsPrim prim = (BasicPhysicsPrim)actor; + if (_prims.Contains(prim)) + _prims.Remove(prim); } public override void RemoveAvatar(PhysicsActor actor) { - BasicActor act = (BasicActor) actor; + BasicActor act = (BasicActor)actor; if (_actors.Contains(act)) - { _actors.Remove(act); - } - } - -/* - public override PhysicsActor AddPrim(Vector3 position, Vector3 size, Quaternion rotation) - { - return null; - } -*/ - - public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation, bool isPhysical, uint localid) - { - return null; } public override void AddPhysicsActorTaint(PhysicsActor prim) -- cgit v1.1 From 58c890df5d82cef6e5d648b6e3a299b058b309dc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sun, 22 Apr 2012 20:03:34 +0100 Subject: Make TestSetPhysicsSinglePrim() actually add the object to the scene in order to test more code paths. --- OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index 51751ef..360566d 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -82,6 +82,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests { TestHelpers.InMethod(); + m_scene.AddSceneObject(m_so1); + SceneObjectPart rootPart = m_so1.RootPart; Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); -- cgit v1.1 From 49ed68e98c34c752fac407aa9359201e244df19f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sun, 22 Apr 2012 20:28:12 +0100 Subject: refactor: simply some properties code in BasicPhysicsPlugin --- .../BasicPhysicsPlugin/BasicPhysicsActor.cs | 42 ++++------------------ .../Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs | 42 ++++------------------ 2 files changed, 12 insertions(+), 72 deletions(-) diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs index b1a3ff9..e43136a 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs @@ -36,13 +36,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin { public class BasicActor : PhysicsActor { - private Vector3 _position; - private Vector3 _velocity; - private Vector3 _acceleration; private Vector3 _size; - private Vector3 m_rotationalVelocity; - private bool flying; - private bool iscolliding; public BasicActor(Vector3 size) { @@ -55,11 +49,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin set { return; } } - public override Vector3 RotationalVelocity - { - get { return m_rotationalVelocity; } - set { m_rotationalVelocity = value; } - } + public override Vector3 RotationalVelocity { get; set; } public override bool SetAlwaysRun { @@ -105,17 +95,9 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin set { return; } } - public override bool Flying - { - get { return flying; } - set { flying = value; } - } + public override bool Flying { get; set; } - public override bool IsColliding - { - get { return iscolliding; } - set { iscolliding = value; } - } + public override bool IsColliding { get; set; } public override bool CollidingGround { @@ -134,11 +116,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin get { return false; } } - public override Vector3 Position - { - get { return _position; } - set { _position = value; } - } + public override Vector3 Position { get; set; } public override Vector3 Size { @@ -206,11 +184,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin get { return Vector3.Zero; } } - public override Vector3 Velocity - { - get { return _velocity; } - set { _velocity = value; } - } + public override Vector3 Velocity { get; set; } public override Vector3 Torque { @@ -230,11 +204,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin set { } } - public override Vector3 Acceleration - { - get { return _acceleration; } - set { _acceleration = value; } - } + public override Vector3 Acceleration { get; set; } public override bool Kinematic { diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs index ba7fe1e..b89eeed 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs @@ -36,14 +36,8 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin { public class BasicPhysicsPrim : PhysicsActor { - private Vector3 _position; - private Vector3 _velocity; - private Vector3 _acceleration; private Vector3 _size; private PrimitiveBaseShape _shape; - private Vector3 m_rotationalVelocity; - private bool flying; - private bool iscolliding; public BasicPhysicsPrim( string name, uint localId, Vector3 position, Vector3 size, Quaternion orientation, PrimitiveBaseShape shape) @@ -62,11 +56,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin set { return; } } - public override Vector3 RotationalVelocity - { - get { return m_rotationalVelocity; } - set { m_rotationalVelocity = value; } - } + public override Vector3 RotationalVelocity { get; set; } public override bool SetAlwaysRun { @@ -112,17 +102,9 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin set { return; } } - public override bool Flying - { - get { return flying; } - set { flying = value; } - } + public override bool Flying { get; set; } - public override bool IsColliding - { - get { return iscolliding; } - set { iscolliding = value; } - } + public override bool IsColliding { get; set; } public override bool CollidingGround { @@ -141,11 +123,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin get { return false; } } - public override Vector3 Position - { - get { return _position; } - set { _position = value; } - } + public override Vector3 Position { get; set; } public override Vector3 Size { @@ -213,11 +191,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin get { return Vector3.Zero; } } - public override Vector3 Velocity - { - get { return _velocity; } - set { _velocity = value; } - } + public override Vector3 Velocity { get; set; } public override Vector3 Torque { @@ -233,11 +207,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin public override Quaternion Orientation { get; set; } - public override Vector3 Acceleration - { - get { return _acceleration; } - set { _acceleration = value; } - } + public override Vector3 Acceleration { get; set; } public override bool Kinematic { -- cgit v1.1 From 679da63da617d031e5e7ae3f2d2a29db1a23ace3 Mon Sep 17 00:00:00 2001 From: Talun Date: Sun, 22 Apr 2012 23:07:50 +0100 Subject: Mantis 5977 Corrections to llRegionSayTo Signed-off-by: BlueWall --- OpenSim/Framework/OSChatMessage.cs | 20 +++++++ .../Region/CoreModules/Avatar/Chat/ChatModule.cs | 52 ++++++++++------ .../Scripting/WorldComm/WorldCommModule.cs | 70 +++++++++++----------- OpenSim/Region/Framework/Interfaces/IWorldComm.cs | 2 +- .../Framework/Scenes/Scene.PacketHandlers.cs | 26 +++++++- .../Shared/Api/Implementation/LSL_Api.cs | 8 ++- 6 files changed, 120 insertions(+), 58 deletions(-) diff --git a/OpenSim/Framework/OSChatMessage.cs b/OpenSim/Framework/OSChatMessage.cs index 54fa275..455756d 100644 --- a/OpenSim/Framework/OSChatMessage.cs +++ b/OpenSim/Framework/OSChatMessage.cs @@ -51,10 +51,12 @@ namespace OpenSim.Framework protected object m_senderObject; protected ChatTypeEnum m_type; protected UUID m_fromID; + protected UUID m_toID; public OSChatMessage() { m_position = new Vector3(); + m_toID = UUID.Zero; } /// @@ -102,6 +104,15 @@ namespace OpenSim.Framework set { m_from = value; } } + /// + /// The name of the sender (needed for scripts) + /// + public string To + { + get { return m_from; } + set { m_from = value; } + } + #region IEventArgs Members /// TODO: Sender and SenderObject should just be Sender and of @@ -132,6 +143,15 @@ namespace OpenSim.Framework } /// + /// The single recipient or all if not set. + /// + public UUID TargetUUID + { + get { return m_toID; } + set { m_toID = value; } + } + + /// /// /// public IScene Scene diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 10b4c37..e4452fb 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs @@ -186,6 +186,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat { string fromName = c.From; UUID fromID = UUID.Zero; + UUID targetID = c.TargetUUID; string message = c.Message; IScene scene = c.Scene; Vector3 fromPos = c.Position; @@ -221,24 +222,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat message = message.Substring(0, 1000); // m_log.DebugFormat( -// "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}", -// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType); +// "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}, targetID {5}", +// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType, targetID); HashSet receiverIDs = new HashSet(); - + foreach (Scene s in m_scenes) { - // This should use ForEachClient, but clients don't have a position. - // If camera is moved into client, then camera position can be used - s.ForEachRootScenePresence( - delegate(ScenePresence presence) + if (targetID == UUID.Zero) + { + // This should use ForEachClient, but clients don't have a position. + // If camera is moved into client, then camera position can be used + s.ForEachRootScenePresence( + delegate(ScenePresence presence) + { + if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType, false)) + receiverIDs.Add(presence.UUID); + } + ); + } + else + { + // This is a send to a specific client eg from llRegionSayTo + // no need to check distance etc, jand send is as say + ScenePresence presence = s.GetScenePresence(targetID); + if (presence != null && !presence.IsChildAgent) { - if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType)) - receiverIDs.Add(presence.UUID); + if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, ChatTypeEnum.Say, message, sourceType, true)) + receiverIDs.Add(presence.UUID); } - ); + } } - + (scene as Scene).EventManager.TriggerOnChatToClients( fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully); } @@ -315,7 +330,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat /// precondition protected virtual bool TrySendChatMessage(ScenePresence presence, Vector3 fromPos, Vector3 regionPos, UUID fromAgentID, string fromName, ChatTypeEnum type, - string message, ChatSourceType src) + string message, ChatSourceType src, bool ignoreDistance) { // don't send stuff to child agents if (presence.IsChildAgent) return false; @@ -326,12 +341,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); - - if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || - type == ChatTypeEnum.Say && dis > m_saydistance || - type == ChatTypeEnum.Shout && dis > m_shoutdistance) + + if (!ignoreDistance) { - return false; + if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || + type == ChatTypeEnum.Say && dis > m_saydistance || + type == ChatTypeEnum.Shout && dis > m_shoutdistance) + { + return false; + } } // TODO: should change so the message is sent through the avatar rather than direct to the ClientView diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index 176c86d..8358bc0 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -308,56 +308,56 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm /// /// Message. /// - public bool DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg, out string error) + public void DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg) { - error = null; // Is id an avatar? ScenePresence sp = m_scene.GetScenePresence(target); if (sp != null) { - // Send message to avatar + // ignore if a child agent this is restricted to inside one region + if (sp.IsChildAgent) + return; + + // Send message to the avatar. + // Channel zero only goes to the avatar + // non zero channel messages only go to the attachments if (channel == 0) { - m_scene.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, false); - } - - List attachments = sp.GetAttachments(); - - if (attachments.Count == 0) - return true; - - // Get uuid of attachments - List targets = new List(); - foreach (SceneObjectGroup sog in attachments) + m_scene.SimChatToAgent(target, Utils.StringToBytes(msg), pos, name, id, false); + } + else { - if (!sog.IsDeleted) - targets.Add(sog.UUID); - } + List attachments = sp.GetAttachments(); + if (attachments.Count == 0) + return; - // Need to check each attachment - foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) - { - if (li.GetHostID().Equals(id)) - continue; + // Get uuid of attachments + List targets = new List(); + foreach (SceneObjectGroup sog in attachments) + { + if (!sog.IsDeleted) + targets.Add(sog.UUID); + } - if (m_scene.GetSceneObjectPart(li.GetHostID()) == null) - continue; + // Need to check each attachment + foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) + { + if (li.GetHostID().Equals(id)) + continue; - if (targets.Contains(li.GetHostID())) - QueueMessage(new ListenerInfo(li, name, id, msg)); - } + if (m_scene.GetSceneObjectPart(li.GetHostID()) == null) + continue; - return true; - } + if (targets.Contains(li.GetHostID())) + QueueMessage(new ListenerInfo(li, name, id, msg)); + } + } - // Need to toss an error here - if (channel == 0) - { - error = "Cannot use llRegionSayTo to message objects on channel 0"; - return false; + return; } + // No avatar found so look for an object foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) { // Dont process if this message is from yourself! @@ -375,7 +375,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm } } - return true; + return; } protected void QueueMessage(ListenerInfo li) diff --git a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs index e8e375e..4e74781 100644 --- a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs +++ b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs @@ -103,7 +103,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Message. /// - bool DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg, out string error); + void DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg); /// /// Are there any listen events ready to be dispatched? diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 87ffc74..2701d6e 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -38,8 +38,9 @@ namespace OpenSim.Region.Framework.Scenes { public partial class Scene { + protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, - UUID fromID, bool fromAgent, bool broadcast) + UUID fromID, UUID targetID, bool fromAgent, bool broadcast) { OSChatMessage args = new OSChatMessage(); @@ -63,14 +64,20 @@ namespace OpenSim.Region.Framework.Scenes } args.From = fromName; - //args. + args.TargetUUID = targetID; if (broadcast) EventManager.TriggerOnChatBroadcast(this, args); else EventManager.TriggerOnChatFromWorld(this, args); } - + + protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, + UUID fromID, bool fromAgent, bool broadcast) + { + SimChat(message, type, channel, fromPos, fromName, fromID, UUID.Zero, fromAgent, broadcast); + } + /// /// /// @@ -108,6 +115,19 @@ namespace OpenSim.Region.Framework.Scenes { SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, true); } + /// + /// + /// + /// + /// + /// + /// + /// + /// + public void SimChatToAgent(UUID targetID, byte[] message, Vector3 fromPos, string fromName, UUID fromID, bool fromAgent) + { + SimChat(message, ChatTypeEnum.Say, 0, fromPos, fromName, fromID, targetID, fromAgent, false); + } /// /// Invoked when the client requests a prim. diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 36c9d5e..a2176ba 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -839,13 +839,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); + if (channel == ScriptBaseClass.DEBUG_CHANNEL) + { + return; + } + UUID TargetID; UUID.TryParse(target, out TargetID); IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); if (wComm != null) - if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error)) - LSLError(error); + wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); } public LSL_Integer llListen(int channelID, string name, string ID, string msg) -- cgit v1.1 From 60065f06b3fd6f680202405e117402b22d62f902 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 23 Apr 2012 22:23:47 +0100 Subject: refactor: Replace calls to InventorySelf() with existing m_itemID in LSL_Api There's no point look up an item ID that we already have. --- .../Shared/Api/Implementation/LSL_Api.cs | 136 +++++++-------------- 1 file changed, 42 insertions(+), 94 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 36c9d5e..6000293 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -85,7 +85,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected IScriptEngine m_ScriptEngine; protected SceneObjectPart m_host; protected uint m_localID; + + /// + /// The UUID of the item that hosts this script + /// protected UUID m_itemID; + protected bool throwErrorOnNotImplemented = true; protected AsyncCommandManager AsyncCommands = null; protected float m_ScriptDelayFactor = 1.0f; @@ -267,25 +272,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - protected UUID InventorySelf() - { - UUID invItemID = new UUID(); - - lock (m_host.TaskInventory) - { - foreach (KeyValuePair inv in m_host.TaskInventory) - { - if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) - { - invItemID = inv.Key; - break; - } - } - } - - return invItemID; - } - protected UUID InventoryKey(string name, int type) { m_host.AddScriptLPS(1); @@ -2697,17 +2683,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llGiveMoney(string destination, int amount) { - UUID invItemID=InventorySelf(); - if (invItemID == UUID.Zero) - return 0; - m_host.AddScriptLPS(1); - TaskInventoryItem item = m_host.TaskInventory[invItemID]; + TaskInventoryItem item; lock (m_host.TaskInventory) { - item = m_host.TaskInventory[invItemID]; + item = m_host.TaskInventory[m_itemID]; } if (item.PermsGranter == UUID.Zero) @@ -2955,10 +2937,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api lock (m_host.TaskInventory) { - if (!m_host.TaskInventory.ContainsKey(InventorySelf())) + if (!m_host.TaskInventory.ContainsKey(m_itemID)) return; else - item = m_host.TaskInventory[InventorySelf()]; + item = m_host.TaskInventory[m_itemID]; } if (item.PermsGranter != UUID.Zero) @@ -2983,10 +2965,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api lock (m_host.TaskInventory) { - if (!m_host.TaskInventory.ContainsKey(InventorySelf())) + if (!m_host.TaskInventory.ContainsKey(m_itemID)) return; else - item = m_host.TaskInventory[InventorySelf()]; + item = m_host.TaskInventory[m_itemID]; } m_host.AddScriptLPS(1); @@ -3026,10 +3008,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api lock (m_host.TaskInventory) { - if (!m_host.TaskInventory.ContainsKey(InventorySelf())) + if (!m_host.TaskInventory.ContainsKey(m_itemID)) return; else - item = m_host.TaskInventory[InventorySelf()]; + item = m_host.TaskInventory[m_itemID]; } if (item.PermsGranter != m_host.OwnerID) @@ -3058,10 +3040,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api lock (m_host.TaskInventory) { - if (!m_host.TaskInventory.ContainsKey(InventorySelf())) + if (!m_host.TaskInventory.ContainsKey(m_itemID)) return; else - item = m_host.TaskInventory[InventorySelf()]; + item = m_host.TaskInventory[m_itemID]; } if (item.PermsGranter != m_host.OwnerID) @@ -3313,18 +3295,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - UUID invItemID = InventorySelf(); - if (invItemID == UUID.Zero) - return; - TaskInventoryItem item; lock (m_host.TaskInventory) { - if (!m_host.TaskInventory.ContainsKey(InventorySelf())) + if (!m_host.TaskInventory.ContainsKey(m_itemID)) return; else - item = m_host.TaskInventory[InventorySelf()]; + item = m_host.TaskInventory[m_itemID]; } if (item.PermsGranter == UUID.Zero) @@ -3350,18 +3328,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - UUID invItemID=InventorySelf(); - if (invItemID == UUID.Zero) - return; - TaskInventoryItem item; lock (m_host.TaskInventory) { - if (!m_host.TaskInventory.ContainsKey(InventorySelf())) + if (!m_host.TaskInventory.ContainsKey(m_itemID)) return; else - item = m_host.TaskInventory[InventorySelf()]; + item = m_host.TaskInventory[m_itemID]; } if (item.PermsGranter == UUID.Zero) @@ -3417,21 +3391,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llRequestPermissions(string agent, int perm) { - UUID agentID = new UUID(); + UUID agentID; if (!UUID.TryParse(agent, out agentID)) return; - UUID invItemID = InventorySelf(); - - if (invItemID == UUID.Zero) - return; // Not in a prim? How?? - TaskInventoryItem item; lock (m_host.TaskInventory) { - item = m_host.TaskInventory[invItemID]; + item = m_host.TaskInventory[m_itemID]; } if (agentID == UUID.Zero || perm == 0) // Releasing permissions @@ -3466,8 +3435,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { lock (m_host.TaskInventory) { - m_host.TaskInventory[invItemID].PermsGranter = agentID; - m_host.TaskInventory[invItemID].PermsMask = perm; + m_host.TaskInventory[m_itemID].PermsGranter = agentID; + m_host.TaskInventory[m_itemID].PermsMask = perm; } m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( @@ -3490,8 +3459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { lock (m_host.TaskInventory) { - m_host.TaskInventory[invItemID].PermsGranter = agentID; - m_host.TaskInventory[invItemID].PermsMask = perm; + m_host.TaskInventory[m_itemID].PermsGranter = agentID; + m_host.TaskInventory[m_itemID].PermsMask = perm; } m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( @@ -3515,8 +3484,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { lock (m_host.TaskInventory) { - m_host.TaskInventory[invItemID].PermsGranter = agentID; - m_host.TaskInventory[invItemID].PermsMask = 0; + m_host.TaskInventory[m_itemID].PermsGranter = agentID; + m_host.TaskInventory[m_itemID].PermsMask = 0; } presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; @@ -3524,7 +3493,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } presence.ControllingClient.SendScriptQuestion( - m_host.UUID, m_host.ParentGroup.RootPart.Name, ownerName, invItemID, perm); + m_host.UUID, m_host.ParentGroup.RootPart.Name, ownerName, m_itemID, perm); return; } @@ -3541,20 +3510,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (taskID != m_host.UUID) return; - UUID invItemID = InventorySelf(); - - if (invItemID == UUID.Zero) - return; - - client.OnScriptAnswer-=handleScriptAnswer; - m_waitingForScriptAnswer=false; + client.OnScriptAnswer -= handleScriptAnswer; + m_waitingForScriptAnswer = false; if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) llReleaseControls(); lock (m_host.TaskInventory) { - m_host.TaskInventory[invItemID].PermsMask = answer; + m_host.TaskInventory[m_itemID].PermsMask = answer; } m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( @@ -3627,7 +3591,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llCreateLink(string target, int parent) { m_host.AddScriptLPS(1); - UUID invItemID = InventorySelf(); + UUID targetID; if (!UUID.TryParse(target, out targetID)) @@ -3636,7 +3600,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api TaskInventoryItem item; lock (m_host.TaskInventory) { - item = m_host.TaskInventory[invItemID]; + item = m_host.TaskInventory[m_itemID]; } if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 @@ -3688,11 +3652,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llBreakLink(int linknum) { m_host.AddScriptLPS(1); - UUID invItemID = InventorySelf(); lock (m_host.TaskInventory) { - if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 + if ((m_host.TaskInventory[m_itemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 && !m_automaticLinkPermission) { ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); @@ -9691,17 +9654,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llGetCameraPos() { m_host.AddScriptLPS(1); - UUID invItemID = InventorySelf(); - - if (invItemID == UUID.Zero) - return new LSL_Vector(); lock (m_host.TaskInventory) { - if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) + if (m_host.TaskInventory[m_itemID].PermsGranter == UUID.Zero) return new LSL_Vector(); - if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) + if ((m_host.TaskInventory[m_itemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) { ShoutError("No permissions to track the camera"); return new LSL_Vector(); @@ -9720,16 +9679,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Rotation llGetCameraRot() { m_host.AddScriptLPS(1); - UUID invItemID = InventorySelf(); - if (invItemID == UUID.Zero) - return new LSL_Rotation(); lock (m_host.TaskInventory) { - if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) + if (m_host.TaskInventory[m_itemID].PermsGranter == UUID.Zero) return new LSL_Rotation(); - if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) + if ((m_host.TaskInventory[m_itemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) { ShoutError("No permissions to track the camera"); return new LSL_Rotation(); @@ -9907,10 +9863,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - // our key in the object we are in - UUID invItemID = InventorySelf(); - if (invItemID == UUID.Zero) return; - // the object we are in UUID objectID = m_host.ParentUUID; if (objectID == UUID.Zero) return; @@ -9919,10 +9871,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api lock (m_host.TaskInventory) { // we need the permission first, to know which avatar we want to set the camera for - agentID = m_host.TaskInventory[invItemID].PermsGranter; + agentID = m_host.TaskInventory[m_itemID].PermsGranter; if (agentID == UUID.Zero) return; - if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; + if ((m_host.TaskInventory[m_itemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; } ScenePresence presence = World.GetScenePresence(agentID); @@ -9963,10 +9915,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - // our key in the object we are in - UUID invItemID=InventorySelf(); - if (invItemID == UUID.Zero) return; - // the object we are in UUID objectID = m_host.ParentUUID; if (objectID == UUID.Zero) return; @@ -9975,9 +9923,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID agentID; lock (m_host.TaskInventory) { - agentID = m_host.TaskInventory[invItemID].PermsGranter; + agentID = m_host.TaskInventory[m_itemID].PermsGranter; if (agentID == UUID.Zero) return; - if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; + if ((m_host.TaskInventory[m_itemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; } ScenePresence presence = World.GetScenePresence(agentID); -- cgit v1.1 From 1f8d1bcdcf7ae48ad0b3609e532ad87859f6300b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 23 Apr 2012 22:52:46 +0100 Subject: Replace common code to fetch self inventory item (as opposed to uuid) with GetSelfInventoryItem() However, at some point it would be far more convenient to receive the TaskInventoryItem in the constructor rather than just the item UUID, so we don't have to constantly refetch our self item. --- .../Shared/Api/Implementation/LSL_Api.cs | 231 +++++++-------------- 1 file changed, 76 insertions(+), 155 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 6000293..a353b25 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -272,6 +272,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + /// + /// Get the inventory item that hosts ourselves. + /// + /// + /// FIXME: It would be far easier to pass in TaskInventoryItem rather than just m_itemID so that we don't need + /// to keep looking ourselves up. + /// + /// + protected TaskInventoryItem GetSelfInventoryItem() + { + lock (m_host.TaskInventory) + return m_host.TaskInventory[m_itemID]; + } + protected UUID InventoryKey(string name, int type) { m_host.AddScriptLPS(1); @@ -2685,12 +2699,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - TaskInventoryItem item; - - lock (m_host.TaskInventory) - { - item = m_host.TaskInventory[m_itemID]; - } + TaskInventoryItem item = GetSelfInventoryItem(); if (item.PermsGranter == UUID.Zero) return 0; @@ -2933,15 +2942,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llTakeControls(int controls, int accept, int pass_on) { - TaskInventoryItem item; - - lock (m_host.TaskInventory) - { - if (!m_host.TaskInventory.ContainsKey(m_itemID)) - return; - else - item = m_host.TaskInventory[m_itemID]; - } + TaskInventoryItem item = GetSelfInventoryItem(); if (item.PermsGranter != UUID.Zero) { @@ -2961,18 +2962,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llReleaseControls() { - TaskInventoryItem item; - - lock (m_host.TaskInventory) - { - if (!m_host.TaskInventory.ContainsKey(m_itemID)) - return; - else - item = m_host.TaskInventory[m_itemID]; - } - m_host.AddScriptLPS(1); + TaskInventoryItem item = GetSelfInventoryItem(); + if (item.PermsGranter != UUID.Zero) { ScenePresence presence = World.GetScenePresence(item.PermsGranter); @@ -3004,15 +2997,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // if (m_host.ParentGroup.RootPart.AttachmentPoint == 0) // return; - TaskInventoryItem item; - - lock (m_host.TaskInventory) - { - if (!m_host.TaskInventory.ContainsKey(m_itemID)) - return; - else - item = m_host.TaskInventory[m_itemID]; - } + TaskInventoryItem item = GetSelfInventoryItem(); if (item.PermsGranter != m_host.OwnerID) return; @@ -3036,15 +3021,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_host.ParentGroup.AttachmentPoint == 0) return; - TaskInventoryItem item; - - lock (m_host.TaskInventory) - { - if (!m_host.TaskInventory.ContainsKey(m_itemID)) - return; - else - item = m_host.TaskInventory[m_itemID]; - } + TaskInventoryItem item = GetSelfInventoryItem(); if (item.PermsGranter != m_host.OwnerID) return; @@ -3295,15 +3272,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - TaskInventoryItem item; - - lock (m_host.TaskInventory) - { - if (!m_host.TaskInventory.ContainsKey(m_itemID)) - return; - else - item = m_host.TaskInventory[m_itemID]; - } + TaskInventoryItem item = GetSelfInventoryItem(); if (item.PermsGranter == UUID.Zero) return; @@ -3328,15 +3297,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - TaskInventoryItem item; - - lock (m_host.TaskInventory) - { - if (!m_host.TaskInventory.ContainsKey(m_itemID)) - return; - else - item = m_host.TaskInventory[m_itemID]; - } + TaskInventoryItem item = GetSelfInventoryItem(); if (item.PermsGranter == UUID.Zero) return; @@ -3396,12 +3357,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(agent, out agentID)) return; - TaskInventoryItem item; - - lock (m_host.TaskInventory) - { - item = m_host.TaskInventory[m_itemID]; - } + TaskInventoryItem item = GetSelfInventoryItem(); if (agentID == UUID.Zero || perm == 0) // Releasing permissions { @@ -3531,39 +3487,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) - { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) - { - if (item.Type == 10 && item.ItemID == m_itemID) - { - return item.PermsGranter.ToString(); - } - } - } - - return UUID.Zero.ToString(); + return GetSelfInventoryItem().PermsGranter.ToString(); } public LSL_Integer llGetPermissions() { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) - { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) - { - if (item.Type == 10 && item.ItemID == m_itemID) - { - int perms = item.PermsMask; - if (m_automaticLinkPermission) - perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; - return perms; - } - } - } + int perms = GetSelfInventoryItem().PermsMask; - return 0; + if (m_automaticLinkPermission) + perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; + + return perms; } public LSL_Integer llGetLinkNumber() @@ -3597,11 +3533,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(target, out targetID)) return; - TaskInventoryItem item; - lock (m_host.TaskInventory) - { - item = m_host.TaskInventory[m_itemID]; - } + TaskInventoryItem item = GetSelfInventoryItem(); if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 && !m_automaticLinkPermission) @@ -3653,14 +3585,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + if ((GetSelfInventoryItem().PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 + && !m_automaticLinkPermission) { - if ((m_host.TaskInventory[m_itemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 - && !m_automaticLinkPermission) - { - ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); - return; - } + ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); + return; } if (linknum < ScriptBaseClass.LINK_THIS) @@ -4537,23 +4466,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String llGetScriptName() { - string result = String.Empty; - m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) - { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) - { - if (item.Type == 10 && item.ItemID == m_itemID) - { - result = item.Name != null ? item.Name : String.Empty; - break; - } - } - } + TaskInventoryItem item = GetSelfInventoryItem(); - return result; + return item.Name != null ? item.Name : String.Empty; } public LSL_Integer llGetLinkNumberOfSides(int link) @@ -9655,16 +9572,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) - { - if (m_host.TaskInventory[m_itemID].PermsGranter == UUID.Zero) - return new LSL_Vector(); + TaskInventoryItem item = GetSelfInventoryItem(); - if ((m_host.TaskInventory[m_itemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) - { - ShoutError("No permissions to track the camera"); - return new LSL_Vector(); - } + if (item.PermsGranter == UUID.Zero) + return new LSL_Vector(); + + if ((item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) + { + ShoutError("No permissions to track the camera"); + return new LSL_Vector(); } ScenePresence presence = World.GetScenePresence(m_host.OwnerID); @@ -9680,16 +9596,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) - { - if (m_host.TaskInventory[m_itemID].PermsGranter == UUID.Zero) - return new LSL_Rotation(); + TaskInventoryItem item = GetSelfInventoryItem(); - if ((m_host.TaskInventory[m_itemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) - { - ShoutError("No permissions to track the camera"); - return new LSL_Rotation(); - } + if (item.PermsGranter == UUID.Zero) + return new LSL_Rotation(); + + if ((item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) + { + ShoutError("No permissions to track the camera"); + return new LSL_Rotation(); } ScenePresence presence = World.GetScenePresence(m_host.OwnerID); @@ -9865,17 +9780,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // the object we are in UUID objectID = m_host.ParentUUID; - if (objectID == UUID.Zero) return; + if (objectID == UUID.Zero) + return; - UUID agentID; - lock (m_host.TaskInventory) - { - // we need the permission first, to know which avatar we want to set the camera for - agentID = m_host.TaskInventory[m_itemID].PermsGranter; + TaskInventoryItem item = GetSelfInventoryItem(); - if (agentID == UUID.Zero) return; - if ((m_host.TaskInventory[m_itemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; - } + // we need the permission first, to know which avatar we want to set the camera for + UUID agentID = item.PermsGranter; + + if (agentID == UUID.Zero) + return; + + if ((item.PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) + return; ScenePresence presence = World.GetScenePresence(agentID); @@ -9917,21 +9834,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // the object we are in UUID objectID = m_host.ParentUUID; - if (objectID == UUID.Zero) return; + if (objectID == UUID.Zero) + return; + + TaskInventoryItem item = GetSelfInventoryItem(); // we need the permission first, to know which avatar we want to clear the camera for - UUID agentID; - lock (m_host.TaskInventory) - { - agentID = m_host.TaskInventory[m_itemID].PermsGranter; - if (agentID == UUID.Zero) return; - if ((m_host.TaskInventory[m_itemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; - } + UUID agentID = item.PermsGranter; + + if (agentID == UUID.Zero) + return; + + if ((item.PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) + return; ScenePresence presence = World.GetScenePresence(agentID); // we are not interested in child-agents - if (presence.IsChildAgent) return; + if (presence.IsChildAgent) + return; presence.ControllingClient.SendClearFollowCamProperties(objectID); } -- cgit v1.1 From 40e37d8b78379db08de541c8c7a9fed1d22ec5ef Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 24 Apr 2012 00:03:57 +0100 Subject: Add osForceAttachToAvatar() and osForceDetachFromAvatar() These behave identically to llAttachToAvatar() and llDetachFromAvatar() except that they do not enforce the PERMISSION_ATTACH check Intended for use in completely controlled dedicated environments where these checks are more a UI hinderance than a help. Threat level high. --- .../Shared/Api/Implementation/ApiManager.cs | 41 ++++++------ .../Shared/Api/Implementation/LSL_Api.cs | 73 +++++++++++++--------- .../Shared/Api/Implementation/OSSL_Api.cs | 28 +++++++++ .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 14 +++++ .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 13 +++- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 7 +++ 6 files changed, 127 insertions(+), 49 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/ApiManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/ApiManager.cs index 47ed6ba..684138f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/ApiManager.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/ApiManager.cs @@ -29,42 +29,43 @@ using System; using System.Collections; using System.Collections.Generic; using System.Reflection; +using log4net; using OpenSim.Region.ScriptEngine.Interfaces; namespace OpenSim.Region.ScriptEngine.Shared.Api { public class ApiManager { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private Dictionary m_Apis = new Dictionary(); public string[] GetApis() { - if (m_Apis.Count > 0) + if (m_Apis.Count <= 0) { - List l = new List(m_Apis.Keys); - return l.ToArray(); - } + Assembly a = Assembly.GetExecutingAssembly(); - Assembly a = Assembly.GetExecutingAssembly(); + Type[] types = a.GetExportedTypes(); - Type[] types = a.GetExportedTypes(); - - foreach (Type t in types) - { - string name = t.ToString(); - int idx = name.LastIndexOf('.'); - if (idx != -1) - name = name.Substring(idx+1); - - if (name.EndsWith("_Api")) + foreach (Type t in types) { - name = name.Substring(0, name.Length - 4); - m_Apis[name] = t; + string name = t.ToString(); + int idx = name.LastIndexOf('.'); + if (idx != -1) + name = name.Substring(idx+1); + + if (name.EndsWith("_Api")) + { + name = name.Substring(0, name.Length - 4); + m_Apis[name] = t; + } } } - List ret = new List(m_Apis.Keys); - return ret.ToArray(); +// m_log.DebugFormat("[API MANAGER]: Found {0} apis", m_Apis.Keys.Count); + + return new List(m_Apis.Keys).ToArray(); } public IScriptApi CreateApi(string api) @@ -76,4 +77,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return ret; } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 9cb97f9..d4c872c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2994,7 +2994,49 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_UrlModule.ReleaseURL(url); } - public void llAttachToAvatar(int attachment) + /// + /// Attach the object containing this script to the avatar that owns it. + /// + /// The attachment point (e.g. ATTACH_CHEST) + /// true if the attach suceeded, false if it did not + public bool AttachToAvatar(int attachmentPoint) + { + SceneObjectGroup grp = m_host.ParentGroup; + ScenePresence presence = World.GetScenePresence(m_host.OwnerID); + + IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; + + if (attachmentsModule != null) + return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false); + else + return false; + } + + /// + /// Detach the object containing this script from the avatar it is attached to. + /// + /// + /// Nothing happens if the object is not attached. + /// + public void DetachFromAvatar() + { + Util.FireAndForget(DetachWrapper, m_host); + } + + private void DetachWrapper(object o) + { + SceneObjectPart host = (SceneObjectPart)o; + + SceneObjectGroup grp = host.ParentGroup; + UUID itemID = grp.FromItemID; + ScenePresence presence = World.GetScenePresence(host.OwnerID); + + IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; + if (attachmentsModule != null) + attachmentsModule.DetachSingleAttachmentToInv(presence, itemID); + } + + public void llAttachToAvatar(int attachmentPoint) { m_host.AddScriptLPS(1); @@ -3007,15 +3049,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0) - { - SceneObjectGroup grp = m_host.ParentGroup; - - ScenePresence presence = World.GetScenePresence(m_host.OwnerID); - - IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; - if (attachmentsModule != null) - attachmentsModule.AttachObject(presence, grp, (uint)attachment, false); - } + AttachToAvatar(attachmentPoint); } public void llDetachFromAvatar() @@ -3031,24 +3065,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0) - { - IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; - if (attachmentsModule != null) - Util.FireAndForget(DetachWrapper, m_host); - } - } - - private void DetachWrapper(object o) - { - SceneObjectPart host = (SceneObjectPart)o; - - SceneObjectGroup grp = host.ParentGroup; - UUID itemID = grp.FromItemID; - ScenePresence presence = World.GetScenePresence(host.OwnerID); - - IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; - if (attachmentsModule != null) - attachmentsModule.DetachSingleAttachmentToInv(presence, itemID); + DetachFromAvatar(); } public void llTakeCamera(string avatar) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index fe94b79..3f261ea 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -209,6 +209,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api throw new Exception("OSSL Runtime Error: " + msg); } + /// + /// Initialize the LSL interface. + /// + /// + /// FIXME: This is an abomination. We should be able to set this up earlier but currently we have no + /// guarantee the interface is present on Initialize(). There needs to be another post initialize call from + /// ScriptInstance. + /// private void InitLSL() { if (m_LSL_Api != null) @@ -3093,5 +3101,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api estate.setEstateTerrainTextureHeights(corner, (float)low, (float)high); } } + + public void osForceAttachToAvatar(int attachmentPoint) + { + CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatar"); + + m_host.AddScriptLPS(1); + + InitLSL(); + ((LSL_Api)m_LSL_Api).AttachToAvatar(attachmentPoint); + } + + public void osForceDetachFromAvatar() + { + CheckThreatLevel(ThreatLevel.High, "osForceDetachFromAvatar"); + + m_host.AddScriptLPS(1); + + InitLSL(); + ((LSL_Api)m_LSL_Api).DetachFromAvatar(); + } } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 545bbee..d0c852b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -98,6 +98,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osAvatarPlayAnimation(string avatar, string animation); void osAvatarStopAnimation(string avatar, string animation); + // Attachment commands + + /// + /// Attach the object containing this script to the avatar that owns it without checking for PERMISSION_ATTACH + /// + /// The attachment point. For example, ATTACH_CHEST + void osForceAttachToAvatar(int attachment); + + /// + /// Detach the object containing this script from the avatar it is attached to without checking for PERMISSION_ATTACH + /// + /// Nothing happens if the object is not attached. + void osForceDetachFromAvatar(); + //texture draw functions string osMovePen(string drawList, int x, int y); string osDrawLine(string drawList, int startX, int startY, int endX, int endY); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index b94b9bf..36ac0e3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -289,8 +289,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osAvatarStopAnimation(avatar, animation); } + // Avatar functions - //Texture Draw functions + public void osForceAttachToAvatar(int attachmentPoint) + { + m_OSSL_Functions.osForceAttachToAvatar(attachmentPoint); + } + + public void osForceDetachFromAvatar() + { + m_OSSL_Functions.osForceDetachFromAvatar(); + } + + // Texture Draw functions public string osMovePen(string drawList, int x, int y) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 6e36742..2c8af81 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -964,7 +964,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public IScriptApi GetApi(string name) { if (m_Apis.ContainsKey(name)) + { +// m_log.DebugFormat("[SCRIPT INSTANCE]: Found api {0} in {1}@{2}", name, ScriptName, PrimName); + return m_Apis[name]; + } + +// m_log.DebugFormat("[SCRIPT INSTANCE]: Did not find api {0} in {1}@{2}", name, ScriptName, PrimName); + return null; } -- cgit v1.1 From 6c21e15cb9542c06e69fd8acd6d4c04aad2cd7da Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 24 Apr 2012 00:32:01 +0100 Subject: Add online/offline indicator to "friends show" region console command. Improve output table formatting. --- .../Avatar/Friends/FriendsCommandsModule.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs index e68f9d0..2602050 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs @@ -58,6 +58,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends private Scene m_scene; private IFriendsModule m_friendsModule; private IUserManagement m_userManagementModule; + private IPresenceService m_presenceService; // private IAvatarFactoryModule m_avatarFactory; @@ -99,8 +100,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends m_friendsModule = m_scene.RequestModuleInterface(); m_userManagementModule = m_scene.RequestModuleInterface(); + m_presenceService = m_scene.RequestModuleInterface(); - if (m_friendsModule != null && m_userManagementModule != null) + if (m_friendsModule != null && m_userManagementModule != null && m_presenceService != null) { m_scene.AddCommand( "Friends", this, "friends show", @@ -162,7 +164,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends MainConsole.Instance.OutputFormat("Friends for {0} {1} {2}:", firstName, lastName, userId); - MainConsole.Instance.OutputFormat("UUID, Name, MyFlags, TheirFlags"); + MainConsole.Instance.OutputFormat( + "{0,-36} {1,-36} {2,-7} {3,7} {4,10}", "UUID", "Name", "Status", "MyFlags", "TheirFlags"); foreach (FriendInfo friend in friends) { @@ -175,14 +178,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends UUID friendId; string friendName; + string onlineText; if (UUID.TryParse(friend.Friend, out friendId)) friendName = m_userManagementModule.GetUserName(friendId); else friendName = friend.Friend; + OpenSim.Services.Interfaces.PresenceInfo[] pi = m_presenceService.GetAgents(new string[] { friend.Friend }); + if (pi.Length > 0) + onlineText = "online"; + else + onlineText = "offline"; + MainConsole.Instance.OutputFormat( - "{0} {1} {2} {3}", friend.Friend, friendName, friend.MyFlags, friend.TheirFlags); + "{0,-36} {1,-36} {2,-7} {3,-7} {4,-10}", + friend.Friend, friendName, onlineText, friend.MyFlags, friend.TheirFlags); } } } -- cgit v1.1 From fd279889788420a63d7454833ab33cb4060edf38 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 23 Apr 2012 21:29:18 -0700 Subject: Changed the Map-related messages from Info to Debug. They're debug messages. --- OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs | 4 ++-- OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs | 4 ++-- OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs | 4 ++-- OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs index f86c790..aa306c7 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs @@ -225,7 +225,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap int tc = 0; double[,] hm = whichScene.Heightmap.GetDoubles(); tc = Environment.TickCount; - m_log.Info("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile"); + m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile"); EntityBase[] objs = whichScene.GetEntities(); Dictionary z_sort = new Dictionary(); //SortedList z_sort = new SortedList(); @@ -541,7 +541,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap g.Dispose(); } // lock entities objs - m_log.Info("[MAPTILE]: Generating Maptile Step 2: Done in " + (Environment.TickCount - tc) + " ms"); + m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Done in " + (Environment.TickCount - tc) + " ms"); return mapbmp; } diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs index eb1a27f..992bff3 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs @@ -54,7 +54,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap public void TerrainToBitmap(Bitmap mapbmp) { int tc = Environment.TickCount; - m_log.Info("[MAPTILE]: Generating Maptile Step 1: Terrain"); + m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Terrain"); double[,] hm = m_scene.Heightmap.GetDoubles(); bool ShadowDebugContinue = true; @@ -238,7 +238,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap } } } - m_log.Info("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); + m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); } } } diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs index 1d2141e..d13c2ef 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs @@ -278,7 +278,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap public void TerrainToBitmap(Bitmap mapbmp) { int tc = Environment.TickCount; - m_log.Info("[MAPTILE]: Generating Maptile Step 1: Terrain"); + m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Terrain"); // These textures should be in the AssetCache anyway, as every client conneting to this // region needs them. Except on start, when the map is recreated (before anyone connected), @@ -412,7 +412,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap } } } - m_log.Info("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); + m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); } } } diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs index 6163fd1..4f4e296 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs @@ -88,11 +88,11 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap if (renderers.Count > 0) { m_primMesher = RenderingLoader.LoadRenderer(renderers[0]); - m_log.Info("[MAPTILE]: Loaded prim mesher " + m_primMesher.ToString()); + m_log.Debug("[MAPTILE]: Loaded prim mesher " + m_primMesher.ToString()); } else { - m_log.Info("[MAPTILE]: No prim mesher loaded, prim rendering will be disabled"); + m_log.Debug("[MAPTILE]: No prim mesher loaded, prim rendering will be disabled"); } m_scene.RegisterModuleInterface(this); -- cgit v1.1 From c6f30e044b6cd2ed8493ad0e2914786eef4f7890 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 24 Apr 2012 19:49:52 +0100 Subject: Restore _parent_scene.actor_name_map[prim_geom] = this; accidentally removed from ODEPrim.SetGeom. This occurred in 7a574be3fd from Sat 21 Apr 2012. This should fix collision detection. Mnay thanks to tglion for the spot and the fix in http://opensimulator.org/mantis/view.php?id=5988 --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 3f88353..0716214 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -338,6 +338,7 @@ namespace OpenSim.Region.Physics.OdePlugin d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); _parent_scene.geom_name_map[prim_geom] = Name; + _parent_scene.actor_name_map[prim_geom] = this; if (childPrim) { -- cgit v1.1 From 0e3053e4c97670e897496ffa98d7039bf686e6d2 Mon Sep 17 00:00:00 2001 From: Olivier van Helden and Gudule Lapointe (Speculoos.net) Date: Thu, 19 Apr 2012 01:17:56 +0200 Subject: DST settings to match client default Pacific Time (mantis #5972) --- OpenSim/Services/LLLoginService/LLLoginResponse.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs index 844c5ae..8fdcf4e 100644 --- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs +++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs @@ -349,7 +349,21 @@ namespace OpenSim.Services.LLLoginService private void SetDefaultValues() { - DST = TimeZone.CurrentTimeZone.IsDaylightSavingTime(DateTime.Now) ? "Y" : "N"; + TimeZoneInfo gridTimeZone; + try + { + // First try to fetch DST from Pacific Standard Time, because this is + // the one expected by the viewer. "US/Pacific" is the string to search + // on linux and mac, and should work also on Windows (to confirm) + gridTimeZone = TimeZoneInfo.FindSystemTimeZoneById("US/Pacific"); + } + catch (Exception e) + { + m_log.WarnFormat("[TIMEZONE]: {0} Falling back to system time. System time should be set to Pacific Standard Time to provide the expected time", e.Message); + gridTimeZone = TimeZoneInfo.Local; + } + DST = gridTimeZone.IsDaylightSavingTime(DateTime.Now) ? "Y" : "N"; + StipendSinceLogin = "N"; Gendered = "Y"; EverLoggedIn = "Y"; -- cgit v1.1 From cbe889e10bc06f0a3e31b4094c88bf022635dff9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 24 Apr 2012 20:30:19 +0100 Subject: minor: formatting changes to top of LLLoginResponse.SetDefaultValues(), chiefly some break up of the long line. --- OpenSim/Services/LLLoginService/LLLoginResponse.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs index 8fdcf4e..10a44ed 100644 --- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs +++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs @@ -350,6 +350,7 @@ namespace OpenSim.Services.LLLoginService private void SetDefaultValues() { TimeZoneInfo gridTimeZone; + try { // First try to fetch DST from Pacific Standard Time, because this is @@ -359,9 +360,13 @@ namespace OpenSim.Services.LLLoginService } catch (Exception e) { - m_log.WarnFormat("[TIMEZONE]: {0} Falling back to system time. System time should be set to Pacific Standard Time to provide the expected time", e.Message); + m_log.WarnFormat( + "[TIMEZONE]: {0} Falling back to system time. System time should be set to Pacific Standard Time to provide the expected time", + e.Message); + gridTimeZone = TimeZoneInfo.Local; } + DST = gridTimeZone.IsDaylightSavingTime(DateTime.Now) ? "Y" : "N"; StipendSinceLogin = "N"; -- cgit v1.1 From 6011bfa5e36d77ad58cf50ddd99b8c6289144f57 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 23 Apr 2012 19:19:08 +0300 Subject: OSSL: fixed the threat level check for osParseJSONNew --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 3f261ea..7fc7337 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -1617,7 +1617,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public Object osParseJSONNew(string JSON) { - CheckThreatLevel(ThreatLevel.None, "osParseJSON"); + CheckThreatLevel(ThreatLevel.None, "osParseJSONNew"); m_host.AddScriptLPS(1); -- cgit v1.1 From c70e85a3271aaa9e6d892240964cb55cbc2960c7 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 23 Apr 2012 18:38:21 +0300 Subject: When reading a region, use null objects to represent NULL fields. Previously NULL fields were converted to an empty string due to the use of ToString(). But if the field was an Int (e.g., "locZ"), then the subsequent attempt to convert an empty string to an int caused an exception. Now the field is null so we don't try to convert it, so there's no exception. --- OpenSim/Data/MySQL/MySQLRegionData.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index c20c392..948cdf3 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -187,7 +187,11 @@ namespace OpenSim.Data.MySQL if (s == "locY") continue; - ret.Data[s] = result[s].ToString(); + object value = result[s]; + if (value is DBNull) + ret.Data[s] = null; + else + ret.Data[s] = result[s].ToString(); } retList.Add(ret); -- cgit v1.1 From da5fd53702ce97d13da2cb50da0753d507e6c11b Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 23 Apr 2012 18:39:23 +0300 Subject: Fixed problem with MySQL: it was possible for one thread to use an incomplete list of column names if another thread was creating the list at the same time. Now this is thread-safe. --- OpenSim/Data/MySQL/MySQLAuthenticationData.cs | 23 +++++++++++++------- OpenSim/Data/MySQL/MySQLGenericTableHandler.cs | 6 ++++-- OpenSim/Data/MySQL/MySQLRegionData.cs | 29 ++++++++++++++++---------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs index 8d82f61..664ce84 100644 --- a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs +++ b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs @@ -79,14 +79,7 @@ namespace OpenSim.Data.MySQL { ret.PrincipalID = principalID; - if (m_ColumnNames == null) - { - m_ColumnNames = new List(); - - DataTable schemaTable = result.GetSchemaTable(); - foreach (DataRow row in schemaTable.Rows) - m_ColumnNames.Add(row["ColumnName"].ToString()); - } + CheckColumnNames(result); foreach (string s in m_ColumnNames) { @@ -105,6 +98,20 @@ namespace OpenSim.Data.MySQL } } + private void CheckColumnNames(IDataReader result) + { + if (m_ColumnNames != null) + return; + + List columnNames = new List(); + + DataTable schemaTable = result.GetSchemaTable(); + foreach (DataRow row in schemaTable.Rows) + columnNames.Add(row["ColumnName"].ToString()); + + m_ColumnNames = columnNames; + } + public bool Store(AuthenticationData data) { if (data.Data.ContainsKey("UUID")) diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index 754cf72..da8e958 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs @@ -91,15 +91,17 @@ namespace OpenSim.Data.MySQL if (m_ColumnNames != null) return; - m_ColumnNames = new List(); + List columnNames = new List(); DataTable schemaTable = reader.GetSchemaTable(); foreach (DataRow row in schemaTable.Rows) { if (row["ColumnName"] != null && (!m_Fields.ContainsKey(row["ColumnName"].ToString()))) - m_ColumnNames.Add(row["ColumnName"].ToString()); + columnNames.Add(row["ColumnName"].ToString()); } + + m_ColumnNames = columnNames; } public virtual T[] Get(string field, string key) diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index 948cdf3..d1f1932 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -162,17 +162,7 @@ namespace OpenSim.Data.MySQL ret.sizeX = Convert.ToInt32(result["sizeX"]); ret.sizeY = Convert.ToInt32(result["sizeY"]); - if (m_ColumnNames == null) - { - m_ColumnNames = new List(); - - DataTable schemaTable = result.GetSchemaTable(); - foreach (DataRow row in schemaTable.Rows) - { - if (row["ColumnName"] != null) - m_ColumnNames.Add(row["ColumnName"].ToString()); - } - } + CheckColumnNames(result); foreach (string s in m_ColumnNames) { @@ -202,6 +192,23 @@ namespace OpenSim.Data.MySQL return retList; } + private void CheckColumnNames(IDataReader result) + { + if (m_ColumnNames != null) + return; + + List columnNames = new List(); + + DataTable schemaTable = result.GetSchemaTable(); + foreach (DataRow row in schemaTable.Rows) + { + if (row["ColumnName"] != null) + columnNames.Add(row["ColumnName"].ToString()); + } + + m_ColumnNames = columnNames; + } + public bool Store(RegionData data) { if (data.Data.ContainsKey("uuid")) -- cgit v1.1 From d3a4d67a207976cd0d116bb9021f7dfc896784e8 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 23 Apr 2012 17:26:37 +0300 Subject: Refactored how asset/inventory types are associated with content types: gathered all the knowledge into a single class. Added the Mesh content type. --- OpenSim/Framework/SLUtil.cs | 382 ++++++++++++++++-------------------- OpenSim/Framework/Tests/UtilTest.cs | 23 ++- 2 files changed, 177 insertions(+), 228 deletions(-) diff --git a/OpenSim/Framework/SLUtil.cs b/OpenSim/Framework/SLUtil.cs index db4541e..537de7a 100644 --- a/OpenSim/Framework/SLUtil.cs +++ b/OpenSim/Framework/SLUtil.cs @@ -38,239 +38,189 @@ namespace OpenSim.Framework public static class SLUtil { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + #region SL / file extension / content-type conversions - public static string SLAssetTypeToContentType(int assetType) + private class TypeMapping { - switch ((AssetType)assetType) + private sbyte assetType; + private InventoryType inventoryType; + private string contentType; + private string contentType2; + private string extension; + + public sbyte AssetTypeCode + { + get { return assetType; } + } + + public object AssetType + { + get { + if (Enum.IsDefined(typeof(OpenMetaverse.AssetType), assetType)) + return (OpenMetaverse.AssetType)assetType; + else + return OpenMetaverse.AssetType.Unknown; + } + } + + public InventoryType InventoryType + { + get { return inventoryType; } + } + + public string ContentType + { + get { return contentType; } + } + + public string ContentType2 + { + get { return contentType2; } + } + + public string Extension + { + get { return extension; } + } + + private TypeMapping(sbyte assetType, InventoryType inventoryType, string contentType, string contentType2, string extension) + { + this.assetType = assetType; + this.inventoryType = inventoryType; + this.contentType = contentType; + this.contentType2 = contentType2; + this.extension = extension; + } + + public TypeMapping(AssetType assetType, InventoryType inventoryType, string contentType, string contentType2, string extension) + : this((sbyte)assetType, inventoryType, contentType, contentType2, extension) + { + } + + public TypeMapping(AssetType assetType, InventoryType inventoryType, string contentType, string extension) + : this((sbyte)assetType, inventoryType, contentType, null, extension) { - case AssetType.Texture: - return "image/x-j2c"; - case AssetType.Sound: - return "audio/ogg"; - case AssetType.CallingCard: - return "application/vnd.ll.callingcard"; - case AssetType.Landmark: - return "application/vnd.ll.landmark"; - case AssetType.Clothing: - return "application/vnd.ll.clothing"; - case AssetType.Object: - return "application/vnd.ll.primitive"; - case AssetType.Notecard: - return "application/vnd.ll.notecard"; - case AssetType.Folder: - return "application/vnd.ll.folder"; - case AssetType.RootFolder: - return "application/vnd.ll.rootfolder"; - case AssetType.LSLText: - return "application/vnd.ll.lsltext"; - case AssetType.LSLBytecode: - return "application/vnd.ll.lslbyte"; - case AssetType.TextureTGA: - case AssetType.ImageTGA: - return "image/tga"; - case AssetType.Bodypart: - return "application/vnd.ll.bodypart"; - case AssetType.TrashFolder: - return "application/vnd.ll.trashfolder"; - case AssetType.SnapshotFolder: - return "application/vnd.ll.snapshotfolder"; - case AssetType.LostAndFoundFolder: - return "application/vnd.ll.lostandfoundfolder"; - case AssetType.SoundWAV: - return "audio/x-wav"; - case AssetType.ImageJPEG: - return "image/jpeg"; - case AssetType.Animation: - return "application/vnd.ll.animation"; - case AssetType.Gesture: - return "application/vnd.ll.gesture"; - case AssetType.Simstate: - return "application/x-metaverse-simstate"; - case AssetType.FavoriteFolder: - return "application/vnd.ll.favoritefolder"; - case AssetType.Link: - return "application/vnd.ll.link"; - case AssetType.LinkFolder: - return "application/vnd.ll.linkfolder"; - case AssetType.CurrentOutfitFolder: - return "application/vnd.ll.currentoutfitfolder"; - case AssetType.OutfitFolder: - return "application/vnd.ll.outfitfolder"; - case AssetType.MyOutfitsFolder: - return "application/vnd.ll.myoutfitsfolder"; - case AssetType.Unknown: - default: - return "application/octet-stream"; } } - public static string SLInvTypeToContentType(int invType) + /// + /// Maps between AssetType, InventoryType and Content-Type. + /// Where more than one possibility exists, the first one takes precedence. E.g.: + /// AssetType "AssetType.Texture" -> Content-Type "image-xj2c" + /// Content-Type "image/x-j2c" -> InventoryType "InventoryType.Texture" + /// + private static TypeMapping[] MAPPINGS = new TypeMapping[] { + new TypeMapping(AssetType.Unknown, InventoryType.Unknown, "application/octet-stream", "bin"), + new TypeMapping(AssetType.Texture, InventoryType.Texture, "image/x-j2c", "image/jp2", "j2c"), + new TypeMapping(AssetType.Texture, InventoryType.Snapshot, "image/x-j2c", "image/jp2", "j2c"), + new TypeMapping(AssetType.TextureTGA, InventoryType.Texture, "image/tga", "tga"), + new TypeMapping(AssetType.ImageTGA, InventoryType.Texture, "image/tga", "tga"), + new TypeMapping(AssetType.ImageJPEG, InventoryType.Texture, "image/jpeg", "jpg"), + new TypeMapping(AssetType.Sound, InventoryType.Sound, "audio/ogg", "application/ogg", "ogg"), + new TypeMapping(AssetType.SoundWAV, InventoryType.Sound, "audio/x-wav", "wav"), + new TypeMapping(AssetType.CallingCard, InventoryType.CallingCard, "application/vnd.ll.callingcard", "application/x-metaverse-callingcard", "callingcard"), + new TypeMapping(AssetType.Landmark, InventoryType.Landmark, "application/vnd.ll.landmark", "application/x-metaverse-landmark", "landmark"), + new TypeMapping(AssetType.Clothing, InventoryType.Wearable, "application/vnd.ll.clothing", "application/x-metaverse-clothing", "clothing"), + new TypeMapping(AssetType.Object, InventoryType.Object, "application/vnd.ll.primitive", "application/x-metaverse-primitive", "primitive"), + new TypeMapping(AssetType.Object, InventoryType.Attachment, "application/vnd.ll.primitive", "application/x-metaverse-primitive", "primitive"), + new TypeMapping(AssetType.Notecard, InventoryType.Notecard, "application/vnd.ll.notecard", "application/x-metaverse-notecard", "notecard"), + new TypeMapping(AssetType.Folder, InventoryType.Folder, "application/vnd.ll.folder", "folder"), + new TypeMapping(AssetType.RootFolder, InventoryType.RootCategory, "application/vnd.ll.rootfolder", "rootfolder"), + new TypeMapping(AssetType.LSLText, InventoryType.LSL, "application/vnd.ll.lsltext", "application/x-metaverse-lsl", "lsl"), + new TypeMapping(AssetType.LSLBytecode, InventoryType.LSL, "application/vnd.ll.lslbyte", "application/x-metaverse-lso", "lso"), + new TypeMapping(AssetType.Bodypart, InventoryType.Wearable, "application/vnd.ll.bodypart", "application/x-metaverse-bodypart", "bodypart"), + new TypeMapping(AssetType.TrashFolder, InventoryType.Folder, "application/vnd.ll.trashfolder", "trashfolder"), + new TypeMapping(AssetType.SnapshotFolder, InventoryType.Folder, "application/vnd.ll.snapshotfolder", "snapshotfolder"), + new TypeMapping(AssetType.LostAndFoundFolder, InventoryType.Folder, "application/vnd.ll.lostandfoundfolder", "lostandfoundfolder"), + new TypeMapping(AssetType.Animation, InventoryType.Animation, "application/vnd.ll.animation", "application/x-metaverse-animation", "animation"), + new TypeMapping(AssetType.Gesture, InventoryType.Gesture, "application/vnd.ll.gesture", "application/x-metaverse-gesture", "gesture"), + new TypeMapping(AssetType.Simstate, InventoryType.Snapshot, "application/x-metaverse-simstate", "simstate"), + new TypeMapping(AssetType.FavoriteFolder, InventoryType.Unknown, "application/vnd.ll.favoritefolder", "favoritefolder"), + new TypeMapping(AssetType.Link, InventoryType.Unknown, "application/vnd.ll.link", "link"), + new TypeMapping(AssetType.LinkFolder, InventoryType.Unknown, "application/vnd.ll.linkfolder", "linkfolder"), + new TypeMapping(AssetType.CurrentOutfitFolder, InventoryType.Unknown, "application/vnd.ll.currentoutfitfolder", "currentoutfitfolder"), + new TypeMapping(AssetType.OutfitFolder, InventoryType.Unknown, "application/vnd.ll.outfitfolder", "outfitfolder"), + new TypeMapping(AssetType.MyOutfitsFolder, InventoryType.Unknown, "application/vnd.ll.myoutfitsfolder", "myoutfitsfolder"), + new TypeMapping(AssetType.Mesh, InventoryType.Mesh, "application/vnd.ll.mesh", "llm") + }; + + private static Dictionary asset2Content; + private static Dictionary asset2Extension; + private static Dictionary inventory2Content; + private static Dictionary content2Asset; + private static Dictionary content2Inventory; + + static SLUtil() { - switch ((InventoryType)invType) + asset2Content = new Dictionary(); + asset2Extension = new Dictionary(); + inventory2Content = new Dictionary(); + content2Asset = new Dictionary(); + content2Inventory = new Dictionary(); + + foreach (TypeMapping mapping in MAPPINGS) { - case InventoryType.Animation: - return "application/vnd.ll.animation"; - case InventoryType.CallingCard: - return "application/vnd.ll.callingcard"; - case InventoryType.Folder: - return "application/vnd.ll.folder"; - case InventoryType.Gesture: - return "application/vnd.ll.gesture"; - case InventoryType.Landmark: - return "application/vnd.ll.landmark"; - case InventoryType.LSL: - return "application/vnd.ll.lsltext"; - case InventoryType.Notecard: - return "application/vnd.ll.notecard"; - case InventoryType.Attachment: - case InventoryType.Object: - return "application/vnd.ll.primitive"; - case InventoryType.Sound: - return "audio/ogg"; - case InventoryType.Snapshot: - case InventoryType.Texture: - return "image/x-j2c"; - case InventoryType.Wearable: - return "application/vnd.ll.clothing"; - default: - return "application/octet-stream"; + sbyte assetType = mapping.AssetTypeCode; + if (!asset2Content.ContainsKey(assetType)) + asset2Content.Add(assetType, mapping.ContentType); + if (!asset2Extension.ContainsKey(assetType)) + asset2Extension.Add(assetType, mapping.Extension); + if (!inventory2Content.ContainsKey(mapping.InventoryType)) + inventory2Content.Add(mapping.InventoryType, mapping.ContentType); + if (!content2Asset.ContainsKey(mapping.ContentType)) + content2Asset.Add(mapping.ContentType, assetType); + if (!content2Inventory.ContainsKey(mapping.ContentType)) + content2Inventory.Add(mapping.ContentType, mapping.InventoryType); + + if (mapping.ContentType2 != null) + { + if (!content2Asset.ContainsKey(mapping.ContentType2)) + content2Asset.Add(mapping.ContentType2, assetType); + if (!content2Inventory.ContainsKey(mapping.ContentType2)) + content2Inventory.Add(mapping.ContentType2, mapping.InventoryType); + } } } + + public static string SLAssetTypeToContentType(int assetType) + { + string contentType; + if (!asset2Content.TryGetValue((sbyte)assetType, out contentType)) + contentType = asset2Content[(sbyte)AssetType.Unknown]; + return contentType; + } + + public static string SLInvTypeToContentType(int invType) + { + string contentType; + if (!inventory2Content.TryGetValue((InventoryType)invType, out contentType)) + contentType = inventory2Content[InventoryType.Unknown]; + return contentType; + } public static sbyte ContentTypeToSLAssetType(string contentType) { - switch (contentType) - { - case "image/x-j2c": - case "image/jp2": - return (sbyte)AssetType.Texture; - case "application/ogg": - case "audio/ogg": - return (sbyte)AssetType.Sound; - case "application/vnd.ll.callingcard": - case "application/x-metaverse-callingcard": - return (sbyte)AssetType.CallingCard; - case "application/vnd.ll.landmark": - case "application/x-metaverse-landmark": - return (sbyte)AssetType.Landmark; - case "application/vnd.ll.clothing": - case "application/x-metaverse-clothing": - return (sbyte)AssetType.Clothing; - case "application/vnd.ll.primitive": - case "application/x-metaverse-primitive": - return (sbyte)AssetType.Object; - case "application/vnd.ll.notecard": - case "application/x-metaverse-notecard": - return (sbyte)AssetType.Notecard; - case "application/vnd.ll.folder": - return (sbyte)AssetType.Folder; - case "application/vnd.ll.rootfolder": - return (sbyte)AssetType.RootFolder; - case "application/vnd.ll.lsltext": - case "application/x-metaverse-lsl": - return (sbyte)AssetType.LSLText; - case "application/vnd.ll.lslbyte": - case "application/x-metaverse-lso": - return (sbyte)AssetType.LSLBytecode; - case "image/tga": - // Note that AssetType.TextureTGA will be converted to AssetType.ImageTGA - return (sbyte)AssetType.ImageTGA; - case "application/vnd.ll.bodypart": - case "application/x-metaverse-bodypart": - return (sbyte)AssetType.Bodypart; - case "application/vnd.ll.trashfolder": - return (sbyte)AssetType.TrashFolder; - case "application/vnd.ll.snapshotfolder": - return (sbyte)AssetType.SnapshotFolder; - case "application/vnd.ll.lostandfoundfolder": - return (sbyte)AssetType.LostAndFoundFolder; - case "audio/x-wav": - return (sbyte)AssetType.SoundWAV; - case "image/jpeg": - return (sbyte)AssetType.ImageJPEG; - case "application/vnd.ll.animation": - case "application/x-metaverse-animation": - return (sbyte)AssetType.Animation; - case "application/vnd.ll.gesture": - case "application/x-metaverse-gesture": - return (sbyte)AssetType.Gesture; - case "application/x-metaverse-simstate": - return (sbyte)AssetType.Simstate; - case "application/vnd.ll.favoritefolder": - return (sbyte)AssetType.FavoriteFolder; - case "application/vnd.ll.link": - return (sbyte)AssetType.Link; - case "application/vnd.ll.linkfolder": - return (sbyte)AssetType.LinkFolder; - case "application/vnd.ll.currentoutfitfolder": - return (sbyte)AssetType.CurrentOutfitFolder; - case "application/vnd.ll.outfitfolder": - return (sbyte)AssetType.OutfitFolder; - case "application/vnd.ll.myoutfitsfolder": - return (sbyte)AssetType.MyOutfitsFolder; - case "application/octet-stream": - default: - return (sbyte)AssetType.Unknown; - } + sbyte assetType; + if (!content2Asset.TryGetValue(contentType, out assetType)) + assetType = (sbyte)AssetType.Unknown; + return (sbyte)assetType; } public static sbyte ContentTypeToSLInvType(string contentType) { - switch (contentType) - { - case "image/x-j2c": - case "image/jp2": - case "image/tga": - case "image/jpeg": - return (sbyte)InventoryType.Texture; - case "application/ogg": - case "audio/ogg": - case "audio/x-wav": - return (sbyte)InventoryType.Sound; - case "application/vnd.ll.callingcard": - case "application/x-metaverse-callingcard": - return (sbyte)InventoryType.CallingCard; - case "application/vnd.ll.landmark": - case "application/x-metaverse-landmark": - return (sbyte)InventoryType.Landmark; - case "application/vnd.ll.clothing": - case "application/x-metaverse-clothing": - case "application/vnd.ll.bodypart": - case "application/x-metaverse-bodypart": - return (sbyte)InventoryType.Wearable; - case "application/vnd.ll.primitive": - case "application/x-metaverse-primitive": - return (sbyte)InventoryType.Object; - case "application/vnd.ll.notecard": - case "application/x-metaverse-notecard": - return (sbyte)InventoryType.Notecard; - case "application/vnd.ll.folder": - return (sbyte)InventoryType.Folder; - case "application/vnd.ll.rootfolder": - return (sbyte)InventoryType.RootCategory; - case "application/vnd.ll.lsltext": - case "application/x-metaverse-lsl": - case "application/vnd.ll.lslbyte": - case "application/x-metaverse-lso": - return (sbyte)InventoryType.LSL; - case "application/vnd.ll.trashfolder": - case "application/vnd.ll.snapshotfolder": - case "application/vnd.ll.lostandfoundfolder": - return (sbyte)InventoryType.Folder; - case "application/vnd.ll.animation": - case "application/x-metaverse-animation": - return (sbyte)InventoryType.Animation; - case "application/vnd.ll.gesture": - case "application/x-metaverse-gesture": - return (sbyte)InventoryType.Gesture; - case "application/x-metaverse-simstate": - return (sbyte)InventoryType.Snapshot; - case "application/octet-stream": - default: - return (sbyte)InventoryType.Unknown; - } + InventoryType invType; + if (!content2Inventory.TryGetValue(contentType, out invType)) + invType = InventoryType.Unknown; + return (sbyte)invType; + } + + public static string SLAssetTypeToExtension(int assetType) + { + string extension; + if (!asset2Extension.TryGetValue((sbyte)assetType, out extension)) + extension = asset2Extension[(sbyte)AssetType.Unknown]; + return extension; } #endregion SL / file extension / content-type conversions @@ -377,4 +327,4 @@ namespace OpenSim.Framework return output; } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/Tests/UtilTest.cs b/OpenSim/Framework/Tests/UtilTest.cs index 1ca35df..f0d2a3f 100644 --- a/OpenSim/Framework/Tests/UtilTest.cs +++ b/OpenSim/Framework/Tests/UtilTest.cs @@ -214,16 +214,13 @@ namespace OpenSim.Framework.Tests for (int i = 0; i < contenttypes.Length; i++) { - if (SLUtil.ContentTypeToSLAssetType(contenttypes[i]) == 18) - { - Assert.That(contenttypes[i] == "image/tga"); - } + int expected; + if (contenttypes[i] == "image/tga") + expected = 12; // if we know only the content-type "image/tga", then we assume the asset type is TextureTGA; not ImageTGA else - { - Assert.That(SLUtil.ContentTypeToSLAssetType(contenttypes[i]) == assettypes[i], - "Expecting {0} but got {1}", assettypes[i], - SLUtil.ContentTypeToSLAssetType(contenttypes[i])); - } + expected = assettypes[i]; + Assert.AreEqual(expected, SLUtil.ContentTypeToSLAssetType(contenttypes[i]), + String.Format("Incorrect AssetType mapped from Content-Type {0}", contenttypes[i])); } int[] inventorytypes = new int[] {-1,0,1,2,3,6,7,8,9,10,15,17,18,20}; @@ -237,7 +234,7 @@ namespace OpenSim.Framework.Tests "application/vnd.ll.primitive", "application/vnd.ll.notecard", "application/vnd.ll.folder", - "application/octet-stream", + "application/vnd.ll.rootfolder", "application/vnd.ll.lsltext", "image/x-j2c", "application/vnd.ll.primitive", @@ -247,7 +244,8 @@ namespace OpenSim.Framework.Tests for (int i=0;i - /// Maps between AssetType, InventoryType and Content-Type. - /// Where more than one possibility exists, the first one takes precedence. E.g.: - /// AssetType "AssetType.Texture" -> Content-Type "image-xj2c" - /// Content-Type "image/x-j2c" -> InventoryType "InventoryType.Texture" - /// - private static TypeMapping[] MAPPINGS = new TypeMapping[] { - new TypeMapping(AssetType.Unknown, InventoryType.Unknown, "application/octet-stream", "bin"), - new TypeMapping(AssetType.Texture, InventoryType.Texture, "image/x-j2c", "image/jp2", "j2c"), - new TypeMapping(AssetType.Texture, InventoryType.Snapshot, "image/x-j2c", "image/jp2", "j2c"), - new TypeMapping(AssetType.TextureTGA, InventoryType.Texture, "image/tga", "tga"), - new TypeMapping(AssetType.ImageTGA, InventoryType.Texture, "image/tga", "tga"), - new TypeMapping(AssetType.ImageJPEG, InventoryType.Texture, "image/jpeg", "jpg"), - new TypeMapping(AssetType.Sound, InventoryType.Sound, "audio/ogg", "application/ogg", "ogg"), - new TypeMapping(AssetType.SoundWAV, InventoryType.Sound, "audio/x-wav", "wav"), - new TypeMapping(AssetType.CallingCard, InventoryType.CallingCard, "application/vnd.ll.callingcard", "application/x-metaverse-callingcard", "callingcard"), - new TypeMapping(AssetType.Landmark, InventoryType.Landmark, "application/vnd.ll.landmark", "application/x-metaverse-landmark", "landmark"), - new TypeMapping(AssetType.Clothing, InventoryType.Wearable, "application/vnd.ll.clothing", "application/x-metaverse-clothing", "clothing"), - new TypeMapping(AssetType.Object, InventoryType.Object, "application/vnd.ll.primitive", "application/x-metaverse-primitive", "primitive"), - new TypeMapping(AssetType.Object, InventoryType.Attachment, "application/vnd.ll.primitive", "application/x-metaverse-primitive", "primitive"), - new TypeMapping(AssetType.Notecard, InventoryType.Notecard, "application/vnd.ll.notecard", "application/x-metaverse-notecard", "notecard"), - new TypeMapping(AssetType.Folder, InventoryType.Folder, "application/vnd.ll.folder", "folder"), - new TypeMapping(AssetType.RootFolder, InventoryType.RootCategory, "application/vnd.ll.rootfolder", "rootfolder"), - new TypeMapping(AssetType.LSLText, InventoryType.LSL, "application/vnd.ll.lsltext", "application/x-metaverse-lsl", "lsl"), - new TypeMapping(AssetType.LSLBytecode, InventoryType.LSL, "application/vnd.ll.lslbyte", "application/x-metaverse-lso", "lso"), - new TypeMapping(AssetType.Bodypart, InventoryType.Wearable, "application/vnd.ll.bodypart", "application/x-metaverse-bodypart", "bodypart"), - new TypeMapping(AssetType.TrashFolder, InventoryType.Folder, "application/vnd.ll.trashfolder", "trashfolder"), - new TypeMapping(AssetType.SnapshotFolder, InventoryType.Folder, "application/vnd.ll.snapshotfolder", "snapshotfolder"), - new TypeMapping(AssetType.LostAndFoundFolder, InventoryType.Folder, "application/vnd.ll.lostandfoundfolder", "lostandfoundfolder"), - new TypeMapping(AssetType.Animation, InventoryType.Animation, "application/vnd.ll.animation", "application/x-metaverse-animation", "animation"), - new TypeMapping(AssetType.Gesture, InventoryType.Gesture, "application/vnd.ll.gesture", "application/x-metaverse-gesture", "gesture"), - new TypeMapping(AssetType.Simstate, InventoryType.Snapshot, "application/x-metaverse-simstate", "simstate"), - new TypeMapping(AssetType.FavoriteFolder, InventoryType.Unknown, "application/vnd.ll.favoritefolder", "favoritefolder"), - new TypeMapping(AssetType.Link, InventoryType.Unknown, "application/vnd.ll.link", "link"), - new TypeMapping(AssetType.LinkFolder, InventoryType.Unknown, "application/vnd.ll.linkfolder", "linkfolder"), - new TypeMapping(AssetType.CurrentOutfitFolder, InventoryType.Unknown, "application/vnd.ll.currentoutfitfolder", "currentoutfitfolder"), - new TypeMapping(AssetType.OutfitFolder, InventoryType.Unknown, "application/vnd.ll.outfitfolder", "outfitfolder"), - new TypeMapping(AssetType.MyOutfitsFolder, InventoryType.Unknown, "application/vnd.ll.myoutfitsfolder", "myoutfitsfolder"), - new TypeMapping(AssetType.Mesh, InventoryType.Mesh, "application/vnd.ll.mesh", "llm") - }; - - private static Dictionary asset2Content; - private static Dictionary asset2Extension; - private static Dictionary inventory2Content; - private static Dictionary content2Asset; - private static Dictionary content2Inventory; - - static SLUtil() + public static string SLInvTypeToContentType(int invType) { - asset2Content = new Dictionary(); - asset2Extension = new Dictionary(); - inventory2Content = new Dictionary(); - content2Asset = new Dictionary(); - content2Inventory = new Dictionary(); - - foreach (TypeMapping mapping in MAPPINGS) + switch ((InventoryType)invType) { - sbyte assetType = mapping.AssetTypeCode; - if (!asset2Content.ContainsKey(assetType)) - asset2Content.Add(assetType, mapping.ContentType); - if (!asset2Extension.ContainsKey(assetType)) - asset2Extension.Add(assetType, mapping.Extension); - if (!inventory2Content.ContainsKey(mapping.InventoryType)) - inventory2Content.Add(mapping.InventoryType, mapping.ContentType); - if (!content2Asset.ContainsKey(mapping.ContentType)) - content2Asset.Add(mapping.ContentType, assetType); - if (!content2Inventory.ContainsKey(mapping.ContentType)) - content2Inventory.Add(mapping.ContentType, mapping.InventoryType); - - if (mapping.ContentType2 != null) - { - if (!content2Asset.ContainsKey(mapping.ContentType2)) - content2Asset.Add(mapping.ContentType2, assetType); - if (!content2Inventory.ContainsKey(mapping.ContentType2)) - content2Inventory.Add(mapping.ContentType2, mapping.InventoryType); - } + case InventoryType.Animation: + return "application/vnd.ll.animation"; + case InventoryType.CallingCard: + return "application/vnd.ll.callingcard"; + case InventoryType.Folder: + return "application/vnd.ll.folder"; + case InventoryType.Gesture: + return "application/vnd.ll.gesture"; + case InventoryType.Landmark: + return "application/vnd.ll.landmark"; + case InventoryType.LSL: + return "application/vnd.ll.lsltext"; + case InventoryType.Notecard: + return "application/vnd.ll.notecard"; + case InventoryType.Attachment: + case InventoryType.Object: + return "application/vnd.ll.primitive"; + case InventoryType.Sound: + return "audio/ogg"; + case InventoryType.Snapshot: + case InventoryType.Texture: + return "image/x-j2c"; + case InventoryType.Wearable: + return "application/vnd.ll.clothing"; + default: + return "application/octet-stream"; } } - - public static string SLAssetTypeToContentType(int assetType) - { - string contentType; - if (!asset2Content.TryGetValue((sbyte)assetType, out contentType)) - contentType = asset2Content[(sbyte)AssetType.Unknown]; - return contentType; - } - - public static string SLInvTypeToContentType(int invType) - { - string contentType; - if (!inventory2Content.TryGetValue((InventoryType)invType, out contentType)) - contentType = inventory2Content[InventoryType.Unknown]; - return contentType; - } public static sbyte ContentTypeToSLAssetType(string contentType) { - sbyte assetType; - if (!content2Asset.TryGetValue(contentType, out assetType)) - assetType = (sbyte)AssetType.Unknown; - return (sbyte)assetType; + switch (contentType) + { + case "image/x-j2c": + case "image/jp2": + return (sbyte)AssetType.Texture; + case "application/ogg": + case "audio/ogg": + return (sbyte)AssetType.Sound; + case "application/vnd.ll.callingcard": + case "application/x-metaverse-callingcard": + return (sbyte)AssetType.CallingCard; + case "application/vnd.ll.landmark": + case "application/x-metaverse-landmark": + return (sbyte)AssetType.Landmark; + case "application/vnd.ll.clothing": + case "application/x-metaverse-clothing": + return (sbyte)AssetType.Clothing; + case "application/vnd.ll.primitive": + case "application/x-metaverse-primitive": + return (sbyte)AssetType.Object; + case "application/vnd.ll.notecard": + case "application/x-metaverse-notecard": + return (sbyte)AssetType.Notecard; + case "application/vnd.ll.folder": + return (sbyte)AssetType.Folder; + case "application/vnd.ll.rootfolder": + return (sbyte)AssetType.RootFolder; + case "application/vnd.ll.lsltext": + case "application/x-metaverse-lsl": + return (sbyte)AssetType.LSLText; + case "application/vnd.ll.lslbyte": + case "application/x-metaverse-lso": + return (sbyte)AssetType.LSLBytecode; + case "image/tga": + // Note that AssetType.TextureTGA will be converted to AssetType.ImageTGA + return (sbyte)AssetType.ImageTGA; + case "application/vnd.ll.bodypart": + case "application/x-metaverse-bodypart": + return (sbyte)AssetType.Bodypart; + case "application/vnd.ll.trashfolder": + return (sbyte)AssetType.TrashFolder; + case "application/vnd.ll.snapshotfolder": + return (sbyte)AssetType.SnapshotFolder; + case "application/vnd.ll.lostandfoundfolder": + return (sbyte)AssetType.LostAndFoundFolder; + case "audio/x-wav": + return (sbyte)AssetType.SoundWAV; + case "image/jpeg": + return (sbyte)AssetType.ImageJPEG; + case "application/vnd.ll.animation": + case "application/x-metaverse-animation": + return (sbyte)AssetType.Animation; + case "application/vnd.ll.gesture": + case "application/x-metaverse-gesture": + return (sbyte)AssetType.Gesture; + case "application/x-metaverse-simstate": + return (sbyte)AssetType.Simstate; + case "application/vnd.ll.favoritefolder": + return (sbyte)AssetType.FavoriteFolder; + case "application/vnd.ll.link": + return (sbyte)AssetType.Link; + case "application/vnd.ll.linkfolder": + return (sbyte)AssetType.LinkFolder; + case "application/vnd.ll.currentoutfitfolder": + return (sbyte)AssetType.CurrentOutfitFolder; + case "application/vnd.ll.outfitfolder": + return (sbyte)AssetType.OutfitFolder; + case "application/vnd.ll.myoutfitsfolder": + return (sbyte)AssetType.MyOutfitsFolder; + case "application/octet-stream": + default: + return (sbyte)AssetType.Unknown; + } } public static sbyte ContentTypeToSLInvType(string contentType) { - InventoryType invType; - if (!content2Inventory.TryGetValue(contentType, out invType)) - invType = InventoryType.Unknown; - return (sbyte)invType; - } - - public static string SLAssetTypeToExtension(int assetType) - { - string extension; - if (!asset2Extension.TryGetValue((sbyte)assetType, out extension)) - extension = asset2Extension[(sbyte)AssetType.Unknown]; - return extension; + switch (contentType) + { + case "image/x-j2c": + case "image/jp2": + case "image/tga": + case "image/jpeg": + return (sbyte)InventoryType.Texture; + case "application/ogg": + case "audio/ogg": + case "audio/x-wav": + return (sbyte)InventoryType.Sound; + case "application/vnd.ll.callingcard": + case "application/x-metaverse-callingcard": + return (sbyte)InventoryType.CallingCard; + case "application/vnd.ll.landmark": + case "application/x-metaverse-landmark": + return (sbyte)InventoryType.Landmark; + case "application/vnd.ll.clothing": + case "application/x-metaverse-clothing": + case "application/vnd.ll.bodypart": + case "application/x-metaverse-bodypart": + return (sbyte)InventoryType.Wearable; + case "application/vnd.ll.primitive": + case "application/x-metaverse-primitive": + return (sbyte)InventoryType.Object; + case "application/vnd.ll.notecard": + case "application/x-metaverse-notecard": + return (sbyte)InventoryType.Notecard; + case "application/vnd.ll.folder": + return (sbyte)InventoryType.Folder; + case "application/vnd.ll.rootfolder": + return (sbyte)InventoryType.RootCategory; + case "application/vnd.ll.lsltext": + case "application/x-metaverse-lsl": + case "application/vnd.ll.lslbyte": + case "application/x-metaverse-lso": + return (sbyte)InventoryType.LSL; + case "application/vnd.ll.trashfolder": + case "application/vnd.ll.snapshotfolder": + case "application/vnd.ll.lostandfoundfolder": + return (sbyte)InventoryType.Folder; + case "application/vnd.ll.animation": + case "application/x-metaverse-animation": + return (sbyte)InventoryType.Animation; + case "application/vnd.ll.gesture": + case "application/x-metaverse-gesture": + return (sbyte)InventoryType.Gesture; + case "application/x-metaverse-simstate": + return (sbyte)InventoryType.Snapshot; + case "application/octet-stream": + default: + return (sbyte)InventoryType.Unknown; + } } #endregion SL / file extension / content-type conversions @@ -327,4 +377,4 @@ namespace OpenSim.Framework return output; } } -} +} \ No newline at end of file diff --git a/OpenSim/Framework/Tests/UtilTest.cs b/OpenSim/Framework/Tests/UtilTest.cs index f0d2a3f..1ca35df 100644 --- a/OpenSim/Framework/Tests/UtilTest.cs +++ b/OpenSim/Framework/Tests/UtilTest.cs @@ -214,13 +214,16 @@ namespace OpenSim.Framework.Tests for (int i = 0; i < contenttypes.Length; i++) { - int expected; - if (contenttypes[i] == "image/tga") - expected = 12; // if we know only the content-type "image/tga", then we assume the asset type is TextureTGA; not ImageTGA + if (SLUtil.ContentTypeToSLAssetType(contenttypes[i]) == 18) + { + Assert.That(contenttypes[i] == "image/tga"); + } else - expected = assettypes[i]; - Assert.AreEqual(expected, SLUtil.ContentTypeToSLAssetType(contenttypes[i]), - String.Format("Incorrect AssetType mapped from Content-Type {0}", contenttypes[i])); + { + Assert.That(SLUtil.ContentTypeToSLAssetType(contenttypes[i]) == assettypes[i], + "Expecting {0} but got {1}", assettypes[i], + SLUtil.ContentTypeToSLAssetType(contenttypes[i])); + } } int[] inventorytypes = new int[] {-1,0,1,2,3,6,7,8,9,10,15,17,18,20}; @@ -234,7 +237,7 @@ namespace OpenSim.Framework.Tests "application/vnd.ll.primitive", "application/vnd.ll.notecard", "application/vnd.ll.folder", - "application/vnd.ll.rootfolder", + "application/octet-stream", "application/vnd.ll.lsltext", "image/x-j2c", "application/vnd.ll.primitive", @@ -244,8 +247,7 @@ namespace OpenSim.Framework.Tests for (int i=0;i @@ -891,13 +891,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // Calls attach with a Zero position if (AttachObject(sp, part.ParentGroup, AttachmentPt, false)) { - m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); +// m_log.Debug( +// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId +// + ", AttachmentPoint: " + AttachmentPt); // Save avatar attachment information - m_log.Debug( - "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId - + ", AttachmentPoint: " + AttachmentPt); - + m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); } } catch (Exception e) -- cgit v1.1 From f24289c47f81caf92c7cb91428008ce1bd038301 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 25 Apr 2012 01:09:23 +0100 Subject: Comment out AvatarService.SetAvatar debug log line for now --- OpenSim/Services/AvatarService/AvatarService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/AvatarService/AvatarService.cs b/OpenSim/Services/AvatarService/AvatarService.cs index c59a9e0..423c781 100644 --- a/OpenSim/Services/AvatarService/AvatarService.cs +++ b/OpenSim/Services/AvatarService/AvatarService.cs @@ -93,7 +93,7 @@ namespace OpenSim.Services.AvatarService if (kvp.Key.StartsWith("_")) count++; - m_log.DebugFormat("[AVATAR SERVICE]: SetAvatar for {0}, attachs={1}", principalID, count); +// m_log.DebugFormat("[AVATAR SERVICE]: SetAvatar for {0}, attachs={1}", principalID, count); m_Database.Delete("PrincipalID", principalID.ToString()); AvatarBaseData av = new AvatarBaseData(); -- cgit v1.1 From a65ca24701ac34415bf76f4d9094ab42ae721c9a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 25 Apr 2012 01:51:40 +0100 Subject: Add regression test TestSameRegionTeleport() --- .../EntityTransfer/EntityTransferModule.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 ++++ .../Scenes/Tests/ScenePresenceTeleportTests.cs | 36 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index feb783f..221e0bd 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -192,7 +192,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.WarnFormat( "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", position, sp.Name, sp.UUID, emergencyPos); - + position = emergencyPos; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b5f789b..9005acd 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -990,6 +990,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void Teleport(Vector3 pos) { +// m_log.DebugFormat("[SCENE PRESENCE]: Moving {0} to {1} in {2}", Name, pos, Scene.RegionInfo.RegionName); + bool isFlying = Flying; RemoveFromPhysicalScene(); Velocity = Vector3.Zero; @@ -1002,6 +1004,10 @@ namespace OpenSim.Region.Framework.Scenes public void TeleportWithMomentum(Vector3 pos) { +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Moving {0} to {1} with existing momentum {2} in {3} ", +// Name, pos, Velocity, Scene.RegionInfo.RegionName); + bool isFlying = Flying; RemoveFromPhysicalScene(); CheckLandingPoint(ref pos); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index bebc10c..eb7bfbd 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -33,6 +33,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications; using OpenSim.Framework.Servers; +using OpenSim.Region.CoreModules.Framework.EntityTransfer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; using OpenSim.Tests.Common; @@ -47,6 +48,41 @@ namespace OpenSim.Region.Framework.Scenes.Tests [TestFixture] public class ScenePresenceTeleportTests { + [Test] + public void TestSameRegionTeleport() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + EntityTransferModule etm = new EntityTransferModule(); + + IConfigSource config = new IniConfigSource(); + config.AddConfig("Modules"); + // Not strictly necessary since FriendsModule assumes it is the default (!) + config.Configs["Modules"].Set("EntityTransferModule", etm.Name); + + TestScene scene = SceneHelpers.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); + SceneHelpers.SetupSceneModules(scene, config, etm); + + Vector3 teleportPosition = new Vector3(10, 11, 12); + Vector3 teleportLookAt = new Vector3(20, 21, 22); + + ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); + sp.AbsolutePosition = new Vector3(30, 31, 32); + scene.RequestTeleportLocation( + sp.ControllingClient, + scene.RegionInfo.RegionHandle, + teleportPosition, + teleportLookAt, + (uint)TeleportFlags.ViaLocation); + + Assert.That(sp.AbsolutePosition, Is.EqualTo(teleportPosition)); + + // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera + // position instead). +// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); + } + /// /// Test a teleport between two regions that are not neighbours and do not share any neighbours in common. /// -- cgit v1.1 From 683cfc6f827c15ee70e4651cbcc7b94a01d2f8e3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 25 Apr 2012 02:07:55 +0100 Subject: refactor: Combine ScenePresence.Teleport() and TeleportWithMomentum() These are identical apart from setting Velocity = zero, which has no practical effect anyway since this is zeroed when the avatar is added back to the physics scene. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 16 ---------------- .../OptionalModules/Scripting/Minimodule/SPAvatar.cs | 2 +- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9005acd..8cb4921 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -994,22 +994,6 @@ namespace OpenSim.Region.Framework.Scenes bool isFlying = Flying; RemoveFromPhysicalScene(); - Velocity = Vector3.Zero; - CheckLandingPoint(ref pos); - AbsolutePosition = pos; - AddToPhysicalScene(isFlying); - - SendTerseUpdateToAllClients(); - } - - public void TeleportWithMomentum(Vector3 pos) - { -// m_log.DebugFormat( -// "[SCENE PRESENCE]: Moving {0} to {1} with existing momentum {2} in {3} ", -// Name, pos, Velocity, Scene.RegionInfo.RegionName); - - bool isFlying = Flying; - RemoveFromPhysicalScene(); CheckLandingPoint(ref pos); AbsolutePosition = pos; AddToPhysicalScene(isFlying); diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs index 922eaaf..d192309 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs @@ -68,7 +68,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule public Vector3 WorldPosition { get { return GetSP().AbsolutePosition; } - set { GetSP().TeleportWithMomentum(value); } + set { GetSP().Teleport(value); } } public bool IsChildAgent -- cgit v1.1 From af86e2939c54837d47303668266ca314d405fb37 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 25 Apr 2012 03:47:26 +0100 Subject: zero out SP velocity before calling SP.Teleport(), as the client expects (though this is also effectively done by physics at the moment) --- .../Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 221e0bd..f094346 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -215,6 +215,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.ControllingClient.SendTeleportStart(teleportFlags); sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); + sp.Velocity = Vector3.Zero; sp.Teleport(position); foreach (SceneObjectGroup grp in sp.GetAttachments()) -- cgit v1.1 From 3be3189ee067b26fa6486535a65a0c0e99a9ef5b Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 25 Apr 2012 04:00:01 +0100 Subject: Commit the avination Teleport() methods (adaptedto justincc's changes) --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 8cb4921..e8178ce 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -990,13 +990,24 @@ namespace OpenSim.Region.Framework.Scenes /// public void Teleport(Vector3 pos) { -// m_log.DebugFormat("[SCENE PRESENCE]: Moving {0} to {1} in {2}", Name, pos, Scene.RegionInfo.RegionName); + TeleportWithMomentum(pos, null); + } + public void TeleportWithMomentum(Vector3 pos, Vector3? v) + { bool isFlying = Flying; + Vector3 vel = Velocity; RemoveFromPhysicalScene(); CheckLandingPoint(ref pos); AbsolutePosition = pos; AddToPhysicalScene(isFlying); + if (PhysicsActor != null) + { + if (v.HasValue) + PhysicsActor.SetMomentum((Vector3)v); + else + PhysicsActor.SetMomentum(vel); + } SendTerseUpdateToAllClients(); } -- cgit v1.1 From cf1c34605bf58ee783c2a7d0c63f51ecf6d3288a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 24 Apr 2012 22:17:10 -0700 Subject: HG: Moved User-level code down to the HGEntityTransferModule where it belongs. --- .../Framework/EntityTransfer/EntityTransferModule.cs | 15 +-------------- .../Framework/EntityTransfer/HGEntityTransferModule.cs | 13 +++++++++++++ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 221e0bd..8d810fc 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -61,8 +61,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer set { m_MaxTransferDistance = value; } } - private int m_levelHGTeleport = 0; - protected bool m_Enabled = false; protected Scene m_aScene; protected List m_Scenes = new List(); @@ -106,7 +104,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (transferConfig != null) { MaxTransferDistance = transferConfig.GetInt("max_distance", 4095); - m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0); } m_agentsInTransit = new List(); @@ -240,16 +237,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer destinationRegionName = finalDestination.RegionName; - // check if HyperGrid teleport is allowed, based on user level - int flags = m_aScene.GridService.GetRegionFlags(sp.Scene.RegionInfo.ScopeID, reg.RegionID); - - if (((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) && (sp.UserLevel < m_levelHGTeleport)) - { - m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Final destination link is non permitted hypergrid region. Unable to teleport agent."); - sp.ControllingClient.SendTeleportFailed("HyperGrid teleport not permitted"); - return; - } - uint curX = 0, curY = 0; Utils.LongToUInts(sp.Scene.RegionInfo.RegionHandle, out curX, out curY); int curCellX = (int)(curX / Constants.RegionSize); @@ -413,7 +400,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer bool logout = false; if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) { - sp.ControllingClient.SendTeleportFailed(String.Format("Destination refused: {0}", + sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); return; } diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 7f9175d..6a92e61 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -50,6 +50,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private bool m_Initialized = false; + private int m_levelHGTeleport = 0; private GatekeeperServiceConnector m_GatekeeperConnector; @@ -68,6 +69,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer string name = moduleConfig.GetString("EntityTransferModule", ""); if (name == Name) { + IConfig transferConfig = source.Configs["EntityTransfer"]; + if (transferConfig != null) + m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0); + InitialiseCommon(source); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); } @@ -164,6 +169,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) { // this user is going to another grid + // check if HyperGrid teleport is allowed, based on user level + if (sp.UserLevel < m_levelHGTeleport) + { + m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Final destination link is non permitted hypergrid region. Unable to teleport agent."); + reason = "HyperGrid teleport not permitted"; + return false; + } + if (agentCircuit.ServiceURLs.ContainsKey("HomeURI")) { string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString(); -- cgit v1.1 From 7aa25c6762e40ee9254e2982a9fca89913fa0279 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 24 Apr 2012 22:40:07 -0700 Subject: Slight rewording of output messages. --- .../CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 6a92e61..634fb43 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -172,7 +172,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // check if HyperGrid teleport is allowed, based on user level if (sp.UserLevel < m_levelHGTeleport) { - m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Final destination link is non permitted hypergrid region. Unable to teleport agent."); + m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel."); reason = "HyperGrid teleport not permitted"; return false; } -- cgit v1.1 From bec100a662f2734b5da0cc8d4fb731da019b4304 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 25 Apr 2012 09:51:30 -0700 Subject: Add try/catch around Json script method registration to avoild some issues with .NET 3.5 vs 4.0 differences. See http://opensimulator.org/mantis/view.php?id=5971 --- .../Scripting/JsonStore/JsonStoreScriptModule.cs | 39 +++++++++++++--------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index eda2aef..4949097 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -163,28 +163,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore return; } - m_comms.RegisterScriptInvocation(this,"JsonCreateStore"); - m_comms.RegisterScriptInvocation(this,"JsonDestroyStore"); + try + { + m_comms.RegisterScriptInvocation(this,"JsonCreateStore"); + m_comms.RegisterScriptInvocation(this,"JsonDestroyStore"); - m_comms.RegisterScriptInvocation(this,"JsonReadNotecard"); - m_comms.RegisterScriptInvocation(this,"JsonWriteNotecard"); + m_comms.RegisterScriptInvocation(this,"JsonReadNotecard"); + m_comms.RegisterScriptInvocation(this,"JsonWriteNotecard"); - m_comms.RegisterScriptInvocation(this,"JsonTestPath"); - m_comms.RegisterScriptInvocation(this,"JsonTestPathJson"); + m_comms.RegisterScriptInvocation(this,"JsonTestPath"); + m_comms.RegisterScriptInvocation(this,"JsonTestPathJson"); - m_comms.RegisterScriptInvocation(this,"JsonGetValue"); - m_comms.RegisterScriptInvocation(this,"JsonGetValueJson"); + m_comms.RegisterScriptInvocation(this,"JsonGetValue"); + m_comms.RegisterScriptInvocation(this,"JsonGetValueJson"); - m_comms.RegisterScriptInvocation(this,"JsonTakeValue"); - m_comms.RegisterScriptInvocation(this,"JsonTakeValueJson"); + m_comms.RegisterScriptInvocation(this,"JsonTakeValue"); + m_comms.RegisterScriptInvocation(this,"JsonTakeValueJson"); - m_comms.RegisterScriptInvocation(this,"JsonReadValue"); - m_comms.RegisterScriptInvocation(this,"JsonReadValueJson"); + m_comms.RegisterScriptInvocation(this,"JsonReadValue"); + m_comms.RegisterScriptInvocation(this,"JsonReadValueJson"); - m_comms.RegisterScriptInvocation(this,"JsonSetValue"); - m_comms.RegisterScriptInvocation(this,"JsonSetValueJson"); + m_comms.RegisterScriptInvocation(this,"JsonSetValue"); + m_comms.RegisterScriptInvocation(this,"JsonSetValueJson"); - m_comms.RegisterScriptInvocation(this,"JsonRemoveValue"); + m_comms.RegisterScriptInvocation(this,"JsonRemoveValue"); + } + catch (Exception e) + { + // See http://opensimulator.org/mantis/view.php?id=5971 for more information + m_log.WarnFormat("[JsonStroreScripts] script method registration failed; {0}",e.Message); + m_enabled = false; + } } } -- cgit v1.1 From 88c9fdfa3adda4984aed39bf800832adef883ecc Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 25 Apr 2012 18:36:29 +0100 Subject: Adapt some TeleportWithMomentum calls --- OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 02ac091..06d5587 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -1771,7 +1771,7 @@ namespace OpenSim.Region.CoreModules.World.Land Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land); - targetAvatar.TeleportWithMomentum(pos); + targetAvatar.TeleportWithMomentum(pos, null); targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8637df7..5a5f2e1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6115,7 +6115,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_host.OwnerID == land.LandData.OwnerID) { Vector3 pos = World.GetNearestAllowedPosition(presence, land); - presence.TeleportWithMomentum(pos); + presence.TeleportWithMomentum(pos, null); presence.ControllingClient.SendAlertMessage("You have been ejected from this land"); } } -- cgit v1.1 From 88553bb884c5c8849ec61362e65fe0950c1e3080 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 25 Apr 2012 19:09:22 +0100 Subject: Port Avination link order to make OpenSim behave like SL. Make Primstar scripts work. Fixes Mantis #5990 --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 42 ++++++++++++++++++++-- .../Shared/Api/Implementation/LSL_Api.cs | 12 ++++--- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 49a3485..2686004 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1969,6 +1969,11 @@ namespace OpenSim.Region.Framework.Scenes /// The group of prims which should be linked to this group public void LinkToGroup(SceneObjectGroup objectGroup) { + LinkToGroup(objectGroup, false); + } + + public void LinkToGroup(SceneObjectGroup objectGroup, bool insert) + { // m_log.DebugFormat( // "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}", // objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); @@ -1979,6 +1984,10 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart linkPart = objectGroup.m_rootPart; + // physics flags from group to be applied to linked parts + bool grpusephys = UsesPhysics; + bool grptemporary = IsTemporary; + Vector3 oldGroupPosition = linkPart.GroupPosition; Quaternion oldRootRotation = linkPart.RotationOffset; @@ -2002,15 +2011,35 @@ namespace OpenSim.Region.Framework.Scenes lock (m_parts.SyncRoot) { - int linkNum = PrimCount + 1; + int linkNum; + if (insert) + { + linkNum = 2; + foreach (SceneObjectPart part in Parts) + { + if (part.LinkNum > 1) + part.LinkNum++; + } + } + else + { + linkNum = PrimCount + 1; + } m_parts.Add(linkPart.UUID, linkPart); linkPart.SetParent(this); linkPart.CreateSelected = true; + // let physics know preserve part volume dtc messy since UpdatePrimFlags doesn't look to parent changes for now + linkPart.UpdatePrimFlags(grpusephys, grptemporary, (IsPhantom || (linkPart.Flags & PrimFlags.Phantom) != 0), linkPart.VolumeDetectActive); + if (linkPart.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical) + { + linkPart.PhysActor.link(m_rootPart.PhysActor); + this.Scene.PhysicsScene.AddPhysicsActorTaint(linkPart.PhysActor); + } + linkPart.LinkNum = linkNum++; - linkPart.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect); SceneObjectPart[] ogParts = objectGroup.Parts; Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b) @@ -2022,7 +2051,16 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectPart part = ogParts[i]; if (part.UUID != objectGroup.m_rootPart.UUID) + { LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); + // let physics know + part.UpdatePrimFlags(grpusephys, grptemporary, (IsPhantom || (part.Flags & PrimFlags.Phantom) != 0), part.VolumeDetectActive); + if (part.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical) + { + part.PhysActor.link(m_rootPart.PhysActor); + this.Scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); + } + } part.ClearUndoState(); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d4c872c..d641958 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -832,8 +832,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llRegionSayTo(string target, int channel, string msg) { - string error = String.Empty; - if (msg.Length > 1023) msg = msg.Substring(0, 1023); @@ -3548,7 +3546,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llCreateLink(string target, int parent) { m_host.AddScriptLPS(1); - UUID targetID; if (!UUID.TryParse(target, out targetID)) @@ -3572,11 +3569,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (targetPart.ParentGroup.AttachmentPoint != 0) return; // Fail silently if attached + + if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID) + return; + SceneObjectGroup parentPrim = null, childPrim = null; if (targetPart != null) { - if (parent != 0) { + if (parent != 0) + { parentPrim = m_host.ParentGroup; childPrim = targetPart.ParentGroup; } @@ -3588,7 +3590,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // Required for linking childPrim.RootPart.ClearUpdateSchedule(); - parentPrim.LinkToGroup(childPrim); + parentPrim.LinkToGroup(childPrim, true); } parentPrim.TriggerScriptChangedEvent(Changed.LINK); -- cgit v1.1 From a2d544c9383391f483bdfb82026e2ebc9c88388f Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 25 Apr 2012 11:54:57 -0700 Subject: Add a configuration switch to turn on/off the use of the trash folder when deleting objects from a scene. The use of the trash folder causes assets to be created and stored everytime you delete an object from the scene (slows down the delete and adds mostly useless assets to your database). Default is on (use the trash folder) which is the standard behavior. --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 2 ++ bin/OpenSimDefaults.ini | 7 +++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 10b25ed..816d3b6 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1988,7 +1988,7 @@ namespace OpenSim.Region.Framework.Scenes } } - if (permissionToTake) + if (permissionToTake && (action != DeRezAction.Delete || this.m_useTrashOnDelete)) { m_asyncSceneObjectDeleter.DeleteToInventory( action, destinationID, deleteGroups, remoteClient, diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index a87dfb7..7a2b2ed 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -103,6 +103,7 @@ namespace OpenSim.Region.Framework.Scenes public bool m_trustBinaries; public bool m_allowScriptCrossings; public bool m_useFlySlow; + public bool m_useTrashOnDelete = true; /// /// Temporarily setting to trigger appearance resends at 60 second intervals. @@ -709,6 +710,7 @@ namespace OpenSim.Region.Framework.Scenes m_clampPrimSize = true; } + m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete",m_useTrashOnDelete); m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries); m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings); m_dontPersistBefore = diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 3f2f131..cb9ef22 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -337,6 +337,13 @@ ; OpenJPEG if false ; UseCSJ2K = true + + ; Use "Trash" folder for items deleted from the scene + ; When set to True (the default) items deleted from the scene will be + ; stored in the user's trash or lost and found folder. When set to + ; False items will be removed from the scene permanently + UseTrashOnDelete = True + ; Persist avatar baked textures ; Persisting baked textures can speed up login and region border ; crossings especially with large numbers of users, though it -- cgit v1.1 From 74dbfe6bb5cebf0ea2af5cb80ff03a15a12e125e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 25 Apr 2012 23:46:42 +0100 Subject: Comment out avatar move to target message for now. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index e8178ce..7a94215 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1690,9 +1690,9 @@ namespace OpenSim.Region.Framework.Scenes if (pos.Z - terrainHeight < 0.2) pos.Z = terrainHeight; - m_log.DebugFormat( - "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", - Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", +// Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); if (noFly) Flying = false; -- cgit v1.1 From e52fe03fffc908c4a3387ba77a204ec19f9ed9d4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 26 Apr 2012 00:42:37 +0100 Subject: minor: Add avatar name to removing agent log message --- OpenSim/Region/Framework/Scenes/Scene.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 7a2b2ed..a46c827 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3217,8 +3217,8 @@ namespace OpenSim.Region.Framework.Scenes try { m_log.DebugFormat( - "[SCENE]: Removing {0} agent {1} from region {2}", - (isChildAgent ? "child" : "root"), agentID, RegionInfo.RegionName); + "[SCENE]: Removing {0} agent {1} {2} from region {2}", + (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName); m_sceneGraph.removeUserCount(!isChildAgent); -- cgit v1.1 From 4c4ffb986897dfc66d296aa30f6111393eb02710 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 26 Apr 2012 00:43:31 +0100 Subject: Add request verb and url to error messages in WebUtil that lack this. Make exception printing consistent across windows and mono. --- OpenSim/Framework/WebUtil.cs | 55 ++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index ead8f46..d2aa538 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs @@ -86,8 +86,7 @@ namespace OpenSim.Framework return eplock; } } - - + #region JSONRequest /// @@ -216,7 +215,9 @@ namespace OpenSim.Framework reqnum,url,method,tickdiff,tickdata); } - m_log.DebugFormat("[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage); + m_log.DebugFormat( + "[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage); + return ErrorResponseMap(errorMessage); } @@ -357,7 +358,8 @@ namespace OpenSim.Framework reqnum,url,method,tickdiff,tickdata); } - m_log.WarnFormat("[WEB UTIL]: <{0}> form request failed: {1}",reqnum,errorMessage); + m_log.WarnFormat("[WEB UTIL]: <{0}> form request to {1} failed: {2}", reqnum, url, errorMessage); + return ErrorResponseMap(errorMessage); } @@ -771,12 +773,16 @@ namespace OpenSim.Framework } else { - m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}", verb, requestUrl, e.Status, e.Message); + m_log.ErrorFormat( + "[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}", + verb, requestUrl, e.Status, e.Message); } } catch (Exception e) { - m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with exception {2}", verb, requestUrl, e); + m_log.ErrorFormat( + "[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}", + verb, requestUrl, e.Message, e.StackTrace); } // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString()); @@ -788,7 +794,8 @@ namespace OpenSim.Framework catch (Exception e) { m_log.ErrorFormat( - "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}", verb, requestUrl, e); + "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}", + verb, requestUrl, e.Message, e.StackTrace); } }, null); @@ -841,7 +848,8 @@ namespace OpenSim.Framework } catch (Exception e) { - m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: " + e.ToString(), requestUrl); + m_log.DebugFormat( + "[FORMS]: exception occured {0} {1}: {2}{3}", verb, requestUrl, e.Message, e.StackTrace); } finally { @@ -867,7 +875,9 @@ namespace OpenSim.Framework } catch (Exception e) { - m_log.DebugFormat("[FORMS]: exception occured on receiving reply " + e.ToString()); + m_log.DebugFormat( + "[FORMS]: Exception occured on receiving {0} {1}: {2}{3}", + verb, requestUrl, e.Message, e.StackTrace); } finally { @@ -880,7 +890,7 @@ namespace OpenSim.Framework catch (System.InvalidOperationException) { // This is what happens when there is invalid XML - m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving request"); + m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving {0} {1}", verb, requestUrl); } } return respstring; @@ -938,7 +948,10 @@ namespace OpenSim.Framework } catch (Exception e) { - m_log.DebugFormat("[SynchronousRestObjectRequester]: exception in sending data to {0}: {1}", requestUrl, e); + m_log.DebugFormat( + "[SynchronousRestObjectRequester]: Exception in making request {0} {1}: {2}{3}", + verb, requestUrl, e.Message, e.StackTrace); + return deserial; } finally @@ -960,7 +973,11 @@ namespace OpenSim.Framework respStream.Close(); } else - m_log.DebugFormat("[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", requestUrl, verb); + { + m_log.DebugFormat( + "[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", + verb, requestUrl); + } } } catch (WebException e) @@ -971,20 +988,24 @@ namespace OpenSim.Framework return deserial; else m_log.ErrorFormat( - "[SynchronousRestObjectRequester]: WebException {0} {1} {2} {3}", - requestUrl, typeof(TResponse).ToString(), e.Message, e.StackTrace); + "[SynchronousRestObjectRequester]: WebException for {0} {1} {2}: {3} {4}", + verb, requestUrl, typeof(TResponse).ToString(), e.Message, e.StackTrace); } catch (System.InvalidOperationException) { // This is what happens when there is invalid XML - m_log.DebugFormat("[SynchronousRestObjectRequester]: Invalid XML {0} {1}", requestUrl, typeof(TResponse).ToString()); + m_log.DebugFormat( + "[SynchronousRestObjectRequester]: Invalid XML from {0} {1} {2}", + verb, requestUrl, typeof(TResponse).ToString()); } catch (Exception e) { - m_log.DebugFormat("[SynchronousRestObjectRequester]: Exception on response from {0} {1}", requestUrl, e); + m_log.DebugFormat( + "[SynchronousRestObjectRequester]: Exception on response from {0} {1}: {2}{3}", + verb, requestUrl, e.Message, e.StackTrace); } return deserial; } } -} +} \ No newline at end of file -- cgit v1.1 From b0cbf16c19495814920e138deba4d1bb47615582 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 26 Apr 2012 16:04:49 +0100 Subject: minor: Add region name to dropped inbound packet message --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index fb6b11e..d05f72f 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1350,7 +1350,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { - m_log.DebugFormat("[LLUDPSERVER]: Dropping incoming {0} packet for dead client {1}", packet.Type, udpClient.AgentID); + m_log.DebugFormat( + "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", + packet.Type, udpClient.AgentID, m_scene.RegionInfo.RegionName); } } -- cgit v1.1 From f49912f92abfae79ba00da74fc7665548266f7cd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 26 Apr 2012 16:10:24 +0100 Subject: minor: Add more detail to unauthorized caps client message --- OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 8ec2f20..e20c24f 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -235,7 +235,10 @@ namespace OpenSim.Region.ClientStack.Linden if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint)) { - m_log.DebugFormat("[CAPS]: Unauthorized CAPS client"); + m_log.DebugFormat( + "[CAPS]: Unauthorized CAPS client {0} from {1}", + m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint); + return string.Empty; } -- cgit v1.1 From ca228c4770660096bde98fb603e7e295808a2133 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 26 Apr 2012 16:20:53 +0100 Subject: Comment out old Scene.HandleLogOffUserFromGrid() to reduce client closing analysis complexity --- OpenSim/Region/Framework/Scenes/Scene.cs | 70 ++++++++++++++++---------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index a46c827..dacd9b6 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3796,41 +3796,41 @@ namespace OpenSim.Region.Framework.Scenes return m_authenticateHandler.TryChangeCiruitCode(oldcc, newcc); } - /// - /// The Grid has requested that we log-off a user. Log them off. - /// - /// Unique ID of the avatar to log-off - /// SecureSessionID of the user, or the RegionSecret text when logging on to the grid - /// message to display to the user. Reason for being logged off - public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message) - { - ScenePresence loggingOffUser = GetScenePresence(AvatarID); - if (loggingOffUser != null) - { - UUID localRegionSecret = UUID.Zero; - bool parsedsecret = UUID.TryParse(m_regInfo.regionSecret, out localRegionSecret); - - // Region Secret is used here in case a new sessionid overwrites an old one on the user server. - // Will update the user server in a few revisions to use it. - - if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret)) - { - m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, loggingOffUser.KnownRegionHandles); - loggingOffUser.ControllingClient.Kick(message); - // Give them a second to receive the message! - Thread.Sleep(1000); - loggingOffUser.ControllingClient.Close(); - } - else - { - m_log.Info("[USERLOGOFF]: System sending the LogOff user message failed to sucessfully authenticate"); - } - } - else - { - m_log.InfoFormat("[USERLOGOFF]: Got a logoff request for {0} but the user isn't here. The user might already have been logged out", AvatarID.ToString()); - } - } +// /// +// /// The Grid has requested that we log-off a user. Log them off. +// /// +// /// Unique ID of the avatar to log-off +// /// SecureSessionID of the user, or the RegionSecret text when logging on to the grid +// /// message to display to the user. Reason for being logged off +// public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message) +// { +// ScenePresence loggingOffUser = GetScenePresence(AvatarID); +// if (loggingOffUser != null) +// { +// UUID localRegionSecret = UUID.Zero; +// bool parsedsecret = UUID.TryParse(m_regInfo.regionSecret, out localRegionSecret); +// +// // Region Secret is used here in case a new sessionid overwrites an old one on the user server. +// // Will update the user server in a few revisions to use it. +// +// if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret)) +// { +// m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, loggingOffUser.KnownRegionHandles); +// loggingOffUser.ControllingClient.Kick(message); +// // Give them a second to receive the message! +// Thread.Sleep(1000); +// loggingOffUser.ControllingClient.Close(); +// } +// else +// { +// m_log.Info("[USERLOGOFF]: System sending the LogOff user message failed to sucessfully authenticate"); +// } +// } +// else +// { +// m_log.InfoFormat("[USERLOGOFF]: Got a logoff request for {0} but the user isn't here. The user might already have been logged out", AvatarID.ToString()); +// } +// } /// /// Triggered when an agent crosses into this sim. Also happens on initial login. -- cgit v1.1 From b8114d2b67c8ae8d7551a2ece2177f8b7e958112 Mon Sep 17 00:00:00 2001 From: Talun Date: Tue, 24 Apr 2012 21:54:13 +0100 Subject: Add a version of osNpcSay that takes a channel number Mantis 5747 osNpcSay(UUID npc, string message) left untouched New functions:- osNpcSay(UUID npc, int channel, string message) osNpcShout(UUID npc, int channel, string message) osNpcWhisper(UUID npc, int channel, string message) Signed-off-by: BlueWall --- OpenSim/Region/Framework/Interfaces/INPCModule.cs | 30 +++++++++++++++ .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 21 +++++++---- .../Region/OptionalModules/World/NPC/NPCModule.cs | 43 +++++++++++++++++++++- .../Shared/Api/Implementation/OSSL_Api.cs | 41 ++++++++++++++++++++- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 3 ++ .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 16 ++++++++ 6 files changed, 144 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs index dc3ff89..b4dc3c3 100644 --- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs +++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs @@ -135,6 +135,36 @@ namespace OpenSim.Region.Framework.Interfaces bool Say(UUID agentID, Scene scene, string text); /// + /// Get the NPC to say something. + /// + /// The UUID of the NPC + /// + /// + /// + /// True if the operation succeeded, false if there was no such agent or the agent was not an NPC + bool Say(UUID agentID, Scene scene, string text, int channel); + + /// + /// Get the NPC to shout something. + /// + /// The UUID of the NPC + /// + /// + /// + /// True if the operation succeeded, false if there was no such agent or the agent was not an NPC + bool Shout(UUID agentID, Scene scene, string text, int channel); + + /// + /// Get the NPC to whisper something. + /// + /// The UUID of the NPC + /// + /// + /// + /// True if the operation succeeded, false if there was no such agent or the agent was not an NPC + bool Whisper(UUID agentID, Scene scene, string text, int channel); + + /// /// Sit the NPC. /// /// diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 5ea5af7..e57e5e6 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -76,22 +76,27 @@ namespace OpenSim.Region.OptionalModules.World.NPC public void Say(string message) { - SendOnChatFromClient(message, ChatTypeEnum.Say); + SendOnChatFromClient(0, message, ChatTypeEnum.Say); } - public void Shout(string message) + public void Say(int channel, string message) { - SendOnChatFromClient(message, ChatTypeEnum.Shout); + SendOnChatFromClient(channel, message, ChatTypeEnum.Say); } - public void Whisper(string message) + public void Shout(int channel, string message) { - SendOnChatFromClient(message, ChatTypeEnum.Whisper); + SendOnChatFromClient(channel, message, ChatTypeEnum.Shout); + } + + public void Whisper(int channel, string message) + { + SendOnChatFromClient(channel, message, ChatTypeEnum.Whisper); } public void Broadcast(string message) { - SendOnChatFromClient(message, ChatTypeEnum.Broadcast); + SendOnChatFromClient(0, message, ChatTypeEnum.Broadcast); } public void GiveMoney(UUID target, int amount) @@ -146,10 +151,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC #region Internal Functions - private void SendOnChatFromClient(string message, ChatTypeEnum chatType) + private void SendOnChatFromClient(int channel, string message, ChatTypeEnum chatType) { OSChatMessage chatFromClient = new OSChatMessage(); - chatFromClient.Channel = 0; + chatFromClient.Channel = channel; chatFromClient.From = Name; chatFromClient.Message = message; chatFromClient.Position = StartPos; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 2b8379d..adc6f9c 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -212,6 +212,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC public bool Say(UUID agentID, Scene scene, string text) { + return Say(agentID, scene, text, 0); + } + + public bool Say(UUID agentID, Scene scene, string text, int channel) + { lock (m_avatars) { if (m_avatars.ContainsKey(agentID)) @@ -219,7 +224,25 @@ namespace OpenSim.Region.OptionalModules.World.NPC ScenePresence sp; scene.TryGetScenePresence(agentID, out sp); - m_avatars[agentID].Say(text); + m_avatars[agentID].Say(channel, text); + + return true; + } + } + + return false; + } + + public bool Shout(UUID agentID, Scene scene, string text, int channel) + { + lock (m_avatars) + { + if (m_avatars.ContainsKey(agentID)) + { + ScenePresence sp; + scene.TryGetScenePresence(agentID, out sp); + + m_avatars[agentID].Shout(channel, text); return true; } @@ -246,6 +269,24 @@ namespace OpenSim.Region.OptionalModules.World.NPC return false; } + public bool Whisper(UUID agentID, Scene scene, string text, int channel) + { + lock (m_avatars) + { + if (m_avatars.ContainsKey(agentID)) + { + ScenePresence sp; + scene.TryGetScenePresence(agentID, out sp); + + m_avatars[agentID].Whisper(channel, text); + + return true; + } + } + + return false; + } + public bool Stand(UUID agentID, Scene scene) { lock (m_avatars) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index fe94b79..890115d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2531,6 +2531,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcSay(LSL_Key npc, string message) { + osNpcSay(npc, 0, message); + } + + public void osNpcSay(LSL_Key npc, int channel, string message) + { CheckThreatLevel(ThreatLevel.High, "osNpcSay"); m_host.AddScriptLPS(1); @@ -2542,7 +2547,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!module.CheckPermissions(npcId, m_host.OwnerID)) return; - module.Say(npcId, World, message); + module.Say(npcId, World, message, channel); + } + } + + public void osNpcShout(LSL_Key npc, int channel, string message) + { + CheckThreatLevel(ThreatLevel.High, "osNpcShout"); + m_host.AddScriptLPS(1); + + INPCModule module = World.RequestModuleInterface(); + if (module != null) + { + UUID npcId = new UUID(npc.m_string); + + if (!module.CheckPermissions(npcId, m_host.OwnerID)) + return; + + module.Shout(npcId, World, message, channel); } } @@ -2627,6 +2649,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + public void osNpcWhisper(LSL_Key npc, int channel, string message) + { + CheckThreatLevel(ThreatLevel.High, "osNpcWhisper"); + m_host.AddScriptLPS(1); + + INPCModule module = World.RequestModuleInterface(); + if (module != null) + { + UUID npcId = new UUID(npc.m_string); + + if (!module.CheckPermissions(npcId, m_host.OwnerID)) + return; + + module.Whisper(npcId, World, message, channel); + } + } + /// /// Save the current appearance of the script owner permanently to the named notecard. /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 545bbee..2d3e8e8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -203,11 +203,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osNpcSetRot(LSL_Key npc, rotation rot); void osNpcStopMoveToTarget(LSL_Key npc); void osNpcSay(key npc, string message); + void osNpcSay(key npc, int channel, string message); + void osNpcShout(key npc, int channel, string message); void osNpcSit(key npc, key target, int options); void osNpcStand(LSL_Key npc); void osNpcRemove(key npc); void osNpcPlayAnimation(LSL_Key npc, string animation); void osNpcStopAnimation(LSL_Key npc, string animation); + void osNpcWhisper(key npc, int channel, string message); LSL_Key osOwnerSaveAppearance(string notecard); LSL_Key osAgentSaveAppearance(key agentId, string notecard); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index b94b9bf..e836959 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -569,6 +569,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osNpcSay(npc, message); } + public void osNpcSay(key npc, int channel, string message) + { + m_OSSL_Functions.osNpcSay(npc, channel, message); + } + + + public void osNpcShout(key npc, int channel, string message) + { + m_OSSL_Functions.osNpcShout(npc, channel, message); + } + public void osNpcSit(LSL_Key npc, LSL_Key target, int options) { m_OSSL_Functions.osNpcSit(npc, target, options); @@ -594,6 +605,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osNpcStopAnimation(npc, animation); } + public void osNpcWhisper(key npc, int channel, string message) + { + m_OSSL_Functions.osNpcWhisper(npc, channel, message); + } + public LSL_Key osOwnerSaveAppearance(string notecard) { return m_OSSL_Functions.osOwnerSaveAppearance(notecard); -- cgit v1.1 From cb6791fb30ce0fbe416f42d95b9737f9f30e02a7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 26 Apr 2012 22:35:25 +0100 Subject: Tweak log messages on local region to region teleport path to help with problem resolution. --- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 4 +- .../EntityTransfer/EntityTransferModule.cs | 51 ++++++++++++++-------- .../EntityTransfer/HGEntityTransferModule.cs | 3 +- .../Simulation/LocalSimulationConnector.cs | 10 ++--- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 5 ++- 5 files changed, 48 insertions(+), 25 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index d05f72f..edf91cb 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -916,7 +916,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP UDPPacketBuffer buffer = (UDPPacketBuffer)array[0]; UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1]; - m_log.DebugFormat("[LLUDPSERVER]: Handling UseCircuitCode request from {0}", buffer.RemoteEndPoint); + m_log.DebugFormat( + "[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} from {1}", + uccp.CircuitCode.Code, buffer.RemoteEndPoint); remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index a36d0fe..0f3ed27 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -178,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer destinationRegionName = sp.Scene.RegionInfo.RegionName; m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation for {0} to {1} within existing region {2}", + "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", sp.Name, position, destinationRegionName); // Teleport within the same region @@ -231,7 +231,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer GridRegion finalDestination = GetFinalDestination(reg); if (finalDestination == null) { - m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport agent."); + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport {0} {1}", + sp.Name, sp.UUID); + sp.ControllingClient.SendTeleportFailed("Problem at destination"); return; } @@ -320,10 +323,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } if (IsInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this. + { + 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_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Request Teleport to {0} ({1}) {2}/{3}", + "[ENTITY TRANSFER MODULE]: Teleporting {0} {1} from {2} to {3} ({4}) {5}/{6}", + sp.Name, sp.UUID, sp.Scene.RegionInfo.RegionName, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); uint newRegionX = (uint)(reg.RegionHandle >> 40); @@ -444,7 +454,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); } - SetInTransit(sp.UUID); // Let's send a full update of the agent. This is a synchronous call. @@ -656,7 +665,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public virtual void TeleportHome(UUID id, IClientAPI client) { - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.FirstName, client.LastName); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); //OpenSim.Services.Interfaces.PresenceInfo pinfo = m_aScene.PresenceService.GetAgent(client.SessionId); GridUserInfo uinfo = m_aScene.GridUserService.GetGridUserInfo(client.AgentId.ToString()); @@ -671,14 +681,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: User's home region is {0} {1} ({2}-{3})", - regionInfo.RegionName, regionInfo.RegionID, regionInfo.RegionLocX / Constants.RegionSize, regionInfo.RegionLocY / Constants.RegionSize); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})", + client.Name, regionInfo.RegionName, regionInfo.RegionCoordX, regionInfo.RegionCoordY); // a little eekie that this goes back to Scene and with a forced cast, will fix that at some point... ((Scene)(client.Scene)).RequestTeleportLocation( client, regionInfo.RegionHandle, uinfo.HomePosition, uinfo.HomeLookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome)); } + else + { + m_log.ErrorFormat( + "[ENTITY TRANSFER MODULE]: No grid user information found for {0} {1}. Cannot send home.", + client.Name, client.AgentId); + } } #endregion @@ -1362,19 +1378,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // after a cross here Thread.Sleep(500); - Scene m_scene = sp.Scene; + Scene scene = sp.Scene; - uint x, y; - Utils.LongToUInts(reg.RegionHandle, out x, out y); - x = x / Constants.RegionSize; - y = y / Constants.RegionSize; - m_log.Debug("[ENTITY TRANSFER MODULE]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint + ")"); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})", + sp.Name, sp.UUID, reg.RegionName, endPoint, reg.RegionCoordX, reg.RegionCoordY); string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath); string reason = String.Empty; - bool regionAccepted = m_scene.SimulationService.CreateAgent(reg, a, (uint)TeleportFlags.Default, out reason); + bool regionAccepted = scene.SimulationService.CreateAgent(reg, a, (uint)TeleportFlags.Default, out reason); if (regionAccepted && newAgent) { @@ -1391,7 +1405,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat("[ENTITY TRANSFER MODULE]: {0} is sending {1} EnableSimulator for neighbour region {2} @ {3} " + "and EstablishAgentCommunication with seed cap {4}", - m_scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); + scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); eq.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); @@ -1402,10 +1416,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // TODO: make Event Queue disablable! } - m_log.Debug("[ENTITY TRANSFER MODULE]: Completed inform client about neighbour " + endPoint.ToString()); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Completed inform {0} {1} about neighbour {2}", sp.Name, sp.UUID, endPoint); } + if (!regionAccepted) - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Region {0} did not accept agent: {1}", reg.RegionName, reason); + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: Region {0} did not accept {1} {2}: {3}", + reg.RegionName, sp.Name, sp.UUID, reason); } /// diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 634fb43..6696997 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -201,7 +201,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public override void TeleportHome(UUID id, IClientAPI client) { - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.FirstName, client.LastName); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); // Let's find out if this is a foreign user or a local user IUserManagement uMan = m_aScene.RequestModuleInterface(); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 85e7e94..90f27c4 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs @@ -191,7 +191,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation { if (s.RegionInfo.RegionHandle == destination.RegionHandle) { - m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: Found region {0} to send SendCreateChildAgent", destination.RegionName); +// m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: Found region {0} to send SendCreateChildAgent", destination.RegionName); return s.NewUserConnection(aCircuit, teleportFlags, out reason); } } @@ -209,9 +209,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation { if (s.RegionInfo.RegionHandle == destination.RegionHandle) { - m_log.DebugFormat( - "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", - s.RegionInfo.RegionName, destination.RegionHandle); +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); s.IncomingChildAgentDataUpdate(cAgentData); return true; @@ -281,7 +281,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation { if (s.RegionInfo.RegionID == origin) { - m_log.Debug("[LOCAL COMMS]: Found region to SendReleaseAgent"); +// m_log.Debug("[LOCAL COMMS]: Found region to SendReleaseAgent"); AgentTransferModule.AgentArrivedAtDestination(id); return true; // return s.IncomingReleaseAgent(id); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 7a94215..6b38027 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1142,7 +1142,10 @@ namespace OpenSim.Region.Framework.Scenes if ((m_callbackURI != null) && !m_callbackURI.Equals("")) { - m_log.DebugFormat("[SCENE PRESENCE]: Releasing agent in URI {0}", m_callbackURI); + m_log.DebugFormat( + "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", + client.Name, client.AgentId, m_callbackURI); + Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); m_callbackURI = null; } -- cgit v1.1 From ee13d817f128c294dc05bddaa0bc9a643c48fe8d Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 23 Apr 2012 18:33:50 +0300 Subject: When creating an OAR, objects where the user is the Creator are always included, regardless of their permissions. The purpose of the permission checks is to prevent the unauthorized copying of assets, but users can always copy assets that they created. --- .../CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index 4d459bf..ab3cc41 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -297,10 +297,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver if (checkPermissions.Contains("T") && !canTransfer) partPermitted = false; + // If the user is the Creator of the object then it can always be included in the OAR + bool creator = (obj.CreatorID.Guid == user.Guid); + if (creator) + partPermitted = true; + //string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount); - //m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, permitted={8}", + //m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, creator={8}, permitted={9}", // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask, - // permissionClass, checkPermissions, canCopy, canTransfer, permitted); + // permissionClass, checkPermissions, canCopy, canTransfer, creator, partPermitted); if (!partPermitted) { -- cgit v1.1 From 0da8fe3124402581883f87b2f7036727905038db Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 23 Apr 2012 17:26:37 +0300 Subject: Refactored how asset/inventory types are associated with content types: gathered all the knowledge into a single class. Added the Mesh content type. --- OpenSim/Framework/SLUtil.cs | 382 ++++++++++++++++-------------------- OpenSim/Framework/Tests/UtilTest.cs | 23 ++- 2 files changed, 177 insertions(+), 228 deletions(-) diff --git a/OpenSim/Framework/SLUtil.cs b/OpenSim/Framework/SLUtil.cs index db4541e..537de7a 100644 --- a/OpenSim/Framework/SLUtil.cs +++ b/OpenSim/Framework/SLUtil.cs @@ -38,239 +38,189 @@ namespace OpenSim.Framework public static class SLUtil { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + #region SL / file extension / content-type conversions - public static string SLAssetTypeToContentType(int assetType) + private class TypeMapping { - switch ((AssetType)assetType) + private sbyte assetType; + private InventoryType inventoryType; + private string contentType; + private string contentType2; + private string extension; + + public sbyte AssetTypeCode + { + get { return assetType; } + } + + public object AssetType + { + get { + if (Enum.IsDefined(typeof(OpenMetaverse.AssetType), assetType)) + return (OpenMetaverse.AssetType)assetType; + else + return OpenMetaverse.AssetType.Unknown; + } + } + + public InventoryType InventoryType + { + get { return inventoryType; } + } + + public string ContentType + { + get { return contentType; } + } + + public string ContentType2 + { + get { return contentType2; } + } + + public string Extension + { + get { return extension; } + } + + private TypeMapping(sbyte assetType, InventoryType inventoryType, string contentType, string contentType2, string extension) + { + this.assetType = assetType; + this.inventoryType = inventoryType; + this.contentType = contentType; + this.contentType2 = contentType2; + this.extension = extension; + } + + public TypeMapping(AssetType assetType, InventoryType inventoryType, string contentType, string contentType2, string extension) + : this((sbyte)assetType, inventoryType, contentType, contentType2, extension) + { + } + + public TypeMapping(AssetType assetType, InventoryType inventoryType, string contentType, string extension) + : this((sbyte)assetType, inventoryType, contentType, null, extension) { - case AssetType.Texture: - return "image/x-j2c"; - case AssetType.Sound: - return "audio/ogg"; - case AssetType.CallingCard: - return "application/vnd.ll.callingcard"; - case AssetType.Landmark: - return "application/vnd.ll.landmark"; - case AssetType.Clothing: - return "application/vnd.ll.clothing"; - case AssetType.Object: - return "application/vnd.ll.primitive"; - case AssetType.Notecard: - return "application/vnd.ll.notecard"; - case AssetType.Folder: - return "application/vnd.ll.folder"; - case AssetType.RootFolder: - return "application/vnd.ll.rootfolder"; - case AssetType.LSLText: - return "application/vnd.ll.lsltext"; - case AssetType.LSLBytecode: - return "application/vnd.ll.lslbyte"; - case AssetType.TextureTGA: - case AssetType.ImageTGA: - return "image/tga"; - case AssetType.Bodypart: - return "application/vnd.ll.bodypart"; - case AssetType.TrashFolder: - return "application/vnd.ll.trashfolder"; - case AssetType.SnapshotFolder: - return "application/vnd.ll.snapshotfolder"; - case AssetType.LostAndFoundFolder: - return "application/vnd.ll.lostandfoundfolder"; - case AssetType.SoundWAV: - return "audio/x-wav"; - case AssetType.ImageJPEG: - return "image/jpeg"; - case AssetType.Animation: - return "application/vnd.ll.animation"; - case AssetType.Gesture: - return "application/vnd.ll.gesture"; - case AssetType.Simstate: - return "application/x-metaverse-simstate"; - case AssetType.FavoriteFolder: - return "application/vnd.ll.favoritefolder"; - case AssetType.Link: - return "application/vnd.ll.link"; - case AssetType.LinkFolder: - return "application/vnd.ll.linkfolder"; - case AssetType.CurrentOutfitFolder: - return "application/vnd.ll.currentoutfitfolder"; - case AssetType.OutfitFolder: - return "application/vnd.ll.outfitfolder"; - case AssetType.MyOutfitsFolder: - return "application/vnd.ll.myoutfitsfolder"; - case AssetType.Unknown: - default: - return "application/octet-stream"; } } - public static string SLInvTypeToContentType(int invType) + /// + /// Maps between AssetType, InventoryType and Content-Type. + /// Where more than one possibility exists, the first one takes precedence. E.g.: + /// AssetType "AssetType.Texture" -> Content-Type "image-xj2c" + /// Content-Type "image/x-j2c" -> InventoryType "InventoryType.Texture" + /// + private static TypeMapping[] MAPPINGS = new TypeMapping[] { + new TypeMapping(AssetType.Unknown, InventoryType.Unknown, "application/octet-stream", "bin"), + new TypeMapping(AssetType.Texture, InventoryType.Texture, "image/x-j2c", "image/jp2", "j2c"), + new TypeMapping(AssetType.Texture, InventoryType.Snapshot, "image/x-j2c", "image/jp2", "j2c"), + new TypeMapping(AssetType.TextureTGA, InventoryType.Texture, "image/tga", "tga"), + new TypeMapping(AssetType.ImageTGA, InventoryType.Texture, "image/tga", "tga"), + new TypeMapping(AssetType.ImageJPEG, InventoryType.Texture, "image/jpeg", "jpg"), + new TypeMapping(AssetType.Sound, InventoryType.Sound, "audio/ogg", "application/ogg", "ogg"), + new TypeMapping(AssetType.SoundWAV, InventoryType.Sound, "audio/x-wav", "wav"), + new TypeMapping(AssetType.CallingCard, InventoryType.CallingCard, "application/vnd.ll.callingcard", "application/x-metaverse-callingcard", "callingcard"), + new TypeMapping(AssetType.Landmark, InventoryType.Landmark, "application/vnd.ll.landmark", "application/x-metaverse-landmark", "landmark"), + new TypeMapping(AssetType.Clothing, InventoryType.Wearable, "application/vnd.ll.clothing", "application/x-metaverse-clothing", "clothing"), + new TypeMapping(AssetType.Object, InventoryType.Object, "application/vnd.ll.primitive", "application/x-metaverse-primitive", "primitive"), + new TypeMapping(AssetType.Object, InventoryType.Attachment, "application/vnd.ll.primitive", "application/x-metaverse-primitive", "primitive"), + new TypeMapping(AssetType.Notecard, InventoryType.Notecard, "application/vnd.ll.notecard", "application/x-metaverse-notecard", "notecard"), + new TypeMapping(AssetType.Folder, InventoryType.Folder, "application/vnd.ll.folder", "folder"), + new TypeMapping(AssetType.RootFolder, InventoryType.RootCategory, "application/vnd.ll.rootfolder", "rootfolder"), + new TypeMapping(AssetType.LSLText, InventoryType.LSL, "application/vnd.ll.lsltext", "application/x-metaverse-lsl", "lsl"), + new TypeMapping(AssetType.LSLBytecode, InventoryType.LSL, "application/vnd.ll.lslbyte", "application/x-metaverse-lso", "lso"), + new TypeMapping(AssetType.Bodypart, InventoryType.Wearable, "application/vnd.ll.bodypart", "application/x-metaverse-bodypart", "bodypart"), + new TypeMapping(AssetType.TrashFolder, InventoryType.Folder, "application/vnd.ll.trashfolder", "trashfolder"), + new TypeMapping(AssetType.SnapshotFolder, InventoryType.Folder, "application/vnd.ll.snapshotfolder", "snapshotfolder"), + new TypeMapping(AssetType.LostAndFoundFolder, InventoryType.Folder, "application/vnd.ll.lostandfoundfolder", "lostandfoundfolder"), + new TypeMapping(AssetType.Animation, InventoryType.Animation, "application/vnd.ll.animation", "application/x-metaverse-animation", "animation"), + new TypeMapping(AssetType.Gesture, InventoryType.Gesture, "application/vnd.ll.gesture", "application/x-metaverse-gesture", "gesture"), + new TypeMapping(AssetType.Simstate, InventoryType.Snapshot, "application/x-metaverse-simstate", "simstate"), + new TypeMapping(AssetType.FavoriteFolder, InventoryType.Unknown, "application/vnd.ll.favoritefolder", "favoritefolder"), + new TypeMapping(AssetType.Link, InventoryType.Unknown, "application/vnd.ll.link", "link"), + new TypeMapping(AssetType.LinkFolder, InventoryType.Unknown, "application/vnd.ll.linkfolder", "linkfolder"), + new TypeMapping(AssetType.CurrentOutfitFolder, InventoryType.Unknown, "application/vnd.ll.currentoutfitfolder", "currentoutfitfolder"), + new TypeMapping(AssetType.OutfitFolder, InventoryType.Unknown, "application/vnd.ll.outfitfolder", "outfitfolder"), + new TypeMapping(AssetType.MyOutfitsFolder, InventoryType.Unknown, "application/vnd.ll.myoutfitsfolder", "myoutfitsfolder"), + new TypeMapping(AssetType.Mesh, InventoryType.Mesh, "application/vnd.ll.mesh", "llm") + }; + + private static Dictionary asset2Content; + private static Dictionary asset2Extension; + private static Dictionary inventory2Content; + private static Dictionary content2Asset; + private static Dictionary content2Inventory; + + static SLUtil() { - switch ((InventoryType)invType) + asset2Content = new Dictionary(); + asset2Extension = new Dictionary(); + inventory2Content = new Dictionary(); + content2Asset = new Dictionary(); + content2Inventory = new Dictionary(); + + foreach (TypeMapping mapping in MAPPINGS) { - case InventoryType.Animation: - return "application/vnd.ll.animation"; - case InventoryType.CallingCard: - return "application/vnd.ll.callingcard"; - case InventoryType.Folder: - return "application/vnd.ll.folder"; - case InventoryType.Gesture: - return "application/vnd.ll.gesture"; - case InventoryType.Landmark: - return "application/vnd.ll.landmark"; - case InventoryType.LSL: - return "application/vnd.ll.lsltext"; - case InventoryType.Notecard: - return "application/vnd.ll.notecard"; - case InventoryType.Attachment: - case InventoryType.Object: - return "application/vnd.ll.primitive"; - case InventoryType.Sound: - return "audio/ogg"; - case InventoryType.Snapshot: - case InventoryType.Texture: - return "image/x-j2c"; - case InventoryType.Wearable: - return "application/vnd.ll.clothing"; - default: - return "application/octet-stream"; + sbyte assetType = mapping.AssetTypeCode; + if (!asset2Content.ContainsKey(assetType)) + asset2Content.Add(assetType, mapping.ContentType); + if (!asset2Extension.ContainsKey(assetType)) + asset2Extension.Add(assetType, mapping.Extension); + if (!inventory2Content.ContainsKey(mapping.InventoryType)) + inventory2Content.Add(mapping.InventoryType, mapping.ContentType); + if (!content2Asset.ContainsKey(mapping.ContentType)) + content2Asset.Add(mapping.ContentType, assetType); + if (!content2Inventory.ContainsKey(mapping.ContentType)) + content2Inventory.Add(mapping.ContentType, mapping.InventoryType); + + if (mapping.ContentType2 != null) + { + if (!content2Asset.ContainsKey(mapping.ContentType2)) + content2Asset.Add(mapping.ContentType2, assetType); + if (!content2Inventory.ContainsKey(mapping.ContentType2)) + content2Inventory.Add(mapping.ContentType2, mapping.InventoryType); + } } } + + public static string SLAssetTypeToContentType(int assetType) + { + string contentType; + if (!asset2Content.TryGetValue((sbyte)assetType, out contentType)) + contentType = asset2Content[(sbyte)AssetType.Unknown]; + return contentType; + } + + public static string SLInvTypeToContentType(int invType) + { + string contentType; + if (!inventory2Content.TryGetValue((InventoryType)invType, out contentType)) + contentType = inventory2Content[InventoryType.Unknown]; + return contentType; + } public static sbyte ContentTypeToSLAssetType(string contentType) { - switch (contentType) - { - case "image/x-j2c": - case "image/jp2": - return (sbyte)AssetType.Texture; - case "application/ogg": - case "audio/ogg": - return (sbyte)AssetType.Sound; - case "application/vnd.ll.callingcard": - case "application/x-metaverse-callingcard": - return (sbyte)AssetType.CallingCard; - case "application/vnd.ll.landmark": - case "application/x-metaverse-landmark": - return (sbyte)AssetType.Landmark; - case "application/vnd.ll.clothing": - case "application/x-metaverse-clothing": - return (sbyte)AssetType.Clothing; - case "application/vnd.ll.primitive": - case "application/x-metaverse-primitive": - return (sbyte)AssetType.Object; - case "application/vnd.ll.notecard": - case "application/x-metaverse-notecard": - return (sbyte)AssetType.Notecard; - case "application/vnd.ll.folder": - return (sbyte)AssetType.Folder; - case "application/vnd.ll.rootfolder": - return (sbyte)AssetType.RootFolder; - case "application/vnd.ll.lsltext": - case "application/x-metaverse-lsl": - return (sbyte)AssetType.LSLText; - case "application/vnd.ll.lslbyte": - case "application/x-metaverse-lso": - return (sbyte)AssetType.LSLBytecode; - case "image/tga": - // Note that AssetType.TextureTGA will be converted to AssetType.ImageTGA - return (sbyte)AssetType.ImageTGA; - case "application/vnd.ll.bodypart": - case "application/x-metaverse-bodypart": - return (sbyte)AssetType.Bodypart; - case "application/vnd.ll.trashfolder": - return (sbyte)AssetType.TrashFolder; - case "application/vnd.ll.snapshotfolder": - return (sbyte)AssetType.SnapshotFolder; - case "application/vnd.ll.lostandfoundfolder": - return (sbyte)AssetType.LostAndFoundFolder; - case "audio/x-wav": - return (sbyte)AssetType.SoundWAV; - case "image/jpeg": - return (sbyte)AssetType.ImageJPEG; - case "application/vnd.ll.animation": - case "application/x-metaverse-animation": - return (sbyte)AssetType.Animation; - case "application/vnd.ll.gesture": - case "application/x-metaverse-gesture": - return (sbyte)AssetType.Gesture; - case "application/x-metaverse-simstate": - return (sbyte)AssetType.Simstate; - case "application/vnd.ll.favoritefolder": - return (sbyte)AssetType.FavoriteFolder; - case "application/vnd.ll.link": - return (sbyte)AssetType.Link; - case "application/vnd.ll.linkfolder": - return (sbyte)AssetType.LinkFolder; - case "application/vnd.ll.currentoutfitfolder": - return (sbyte)AssetType.CurrentOutfitFolder; - case "application/vnd.ll.outfitfolder": - return (sbyte)AssetType.OutfitFolder; - case "application/vnd.ll.myoutfitsfolder": - return (sbyte)AssetType.MyOutfitsFolder; - case "application/octet-stream": - default: - return (sbyte)AssetType.Unknown; - } + sbyte assetType; + if (!content2Asset.TryGetValue(contentType, out assetType)) + assetType = (sbyte)AssetType.Unknown; + return (sbyte)assetType; } public static sbyte ContentTypeToSLInvType(string contentType) { - switch (contentType) - { - case "image/x-j2c": - case "image/jp2": - case "image/tga": - case "image/jpeg": - return (sbyte)InventoryType.Texture; - case "application/ogg": - case "audio/ogg": - case "audio/x-wav": - return (sbyte)InventoryType.Sound; - case "application/vnd.ll.callingcard": - case "application/x-metaverse-callingcard": - return (sbyte)InventoryType.CallingCard; - case "application/vnd.ll.landmark": - case "application/x-metaverse-landmark": - return (sbyte)InventoryType.Landmark; - case "application/vnd.ll.clothing": - case "application/x-metaverse-clothing": - case "application/vnd.ll.bodypart": - case "application/x-metaverse-bodypart": - return (sbyte)InventoryType.Wearable; - case "application/vnd.ll.primitive": - case "application/x-metaverse-primitive": - return (sbyte)InventoryType.Object; - case "application/vnd.ll.notecard": - case "application/x-metaverse-notecard": - return (sbyte)InventoryType.Notecard; - case "application/vnd.ll.folder": - return (sbyte)InventoryType.Folder; - case "application/vnd.ll.rootfolder": - return (sbyte)InventoryType.RootCategory; - case "application/vnd.ll.lsltext": - case "application/x-metaverse-lsl": - case "application/vnd.ll.lslbyte": - case "application/x-metaverse-lso": - return (sbyte)InventoryType.LSL; - case "application/vnd.ll.trashfolder": - case "application/vnd.ll.snapshotfolder": - case "application/vnd.ll.lostandfoundfolder": - return (sbyte)InventoryType.Folder; - case "application/vnd.ll.animation": - case "application/x-metaverse-animation": - return (sbyte)InventoryType.Animation; - case "application/vnd.ll.gesture": - case "application/x-metaverse-gesture": - return (sbyte)InventoryType.Gesture; - case "application/x-metaverse-simstate": - return (sbyte)InventoryType.Snapshot; - case "application/octet-stream": - default: - return (sbyte)InventoryType.Unknown; - } + InventoryType invType; + if (!content2Inventory.TryGetValue(contentType, out invType)) + invType = InventoryType.Unknown; + return (sbyte)invType; + } + + public static string SLAssetTypeToExtension(int assetType) + { + string extension; + if (!asset2Extension.TryGetValue((sbyte)assetType, out extension)) + extension = asset2Extension[(sbyte)AssetType.Unknown]; + return extension; } #endregion SL / file extension / content-type conversions @@ -377,4 +327,4 @@ namespace OpenSim.Framework return output; } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/Tests/UtilTest.cs b/OpenSim/Framework/Tests/UtilTest.cs index 1ca35df..f0d2a3f 100644 --- a/OpenSim/Framework/Tests/UtilTest.cs +++ b/OpenSim/Framework/Tests/UtilTest.cs @@ -214,16 +214,13 @@ namespace OpenSim.Framework.Tests for (int i = 0; i < contenttypes.Length; i++) { - if (SLUtil.ContentTypeToSLAssetType(contenttypes[i]) == 18) - { - Assert.That(contenttypes[i] == "image/tga"); - } + int expected; + if (contenttypes[i] == "image/tga") + expected = 12; // if we know only the content-type "image/tga", then we assume the asset type is TextureTGA; not ImageTGA else - { - Assert.That(SLUtil.ContentTypeToSLAssetType(contenttypes[i]) == assettypes[i], - "Expecting {0} but got {1}", assettypes[i], - SLUtil.ContentTypeToSLAssetType(contenttypes[i])); - } + expected = assettypes[i]; + Assert.AreEqual(expected, SLUtil.ContentTypeToSLAssetType(contenttypes[i]), + String.Format("Incorrect AssetType mapped from Content-Type {0}", contenttypes[i])); } int[] inventorytypes = new int[] {-1,0,1,2,3,6,7,8,9,10,15,17,18,20}; @@ -237,7 +234,7 @@ namespace OpenSim.Framework.Tests "application/vnd.ll.primitive", "application/vnd.ll.notecard", "application/vnd.ll.folder", - "application/octet-stream", + "application/vnd.ll.rootfolder", "application/vnd.ll.lsltext", "image/x-j2c", "application/vnd.ll.primitive", @@ -247,7 +244,8 @@ namespace OpenSim.Framework.Tests for (int i=0;i foldersCreated = new Dictionary(); @@ -393,7 +393,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests TestHelpers.InMethod(); //log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); string folder1ExistingName = "a"; @@ -444,7 +444,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); string folder1ExistingName = "a"; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 0f3ed27..a318a3c 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -597,7 +597,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) { - sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true); + if (sp.Scene.AttachmentsModule != null) + sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true); } protected void KillEntity(Scene scene, uint localID) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs index e74310c..d6afaa9 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs @@ -65,7 +65,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests config.AddConfig("Modules"); config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); - m_scene = SceneHelpers.SetupScene(); + m_scene = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(m_scene, config, m_iam); // Create user diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index e05e8f6..053c6f5 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -68,7 +68,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests SerialiserModule serialiserModule = new SerialiserModule(); TerrainModule terrainModule = new TerrainModule(); - m_scene = SceneHelpers.SetupScene(); + m_scene = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule); } @@ -463,7 +463,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests SerialiserModule serialiserModule = new SerialiserModule(); TerrainModule terrainModule = new TerrainModule(); - TestScene scene2 = SceneHelpers.SetupScene(); + TestScene scene2 = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule); // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is @@ -607,7 +607,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests SerialiserModule serialiserModule = new SerialiserModule(); TerrainModule terrainModule = new TerrainModule(); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule); m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false); diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs index e553ffa..b5ee4d2 100644 --- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs +++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs @@ -64,7 +64,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests { m_pcm = new PrimCountModule(); LandManagementModule lmm = new LandManagementModule(); - m_scene = SceneHelpers.SetupScene(); + m_scene = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(m_scene, lmm, m_pcm); int xParcelDivider = (int)Constants.RegionSize - 1; diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs index 4326606..0545250 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs @@ -53,7 +53,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests public void SetUp() { m_module = new MoapModule(); - m_scene = SceneHelpers.SetupScene(); + m_scene = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(m_scene, m_module); } diff --git a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs index d1d2020..7825e3e 100644 --- a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs +++ b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs @@ -343,7 +343,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests public void Init() { m_serialiserModule = new SerialiserModule(); - m_scene = SceneHelpers.SetupScene(); + m_scene = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(m_scene, m_serialiserModule); } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index dacd9b6..4d0aa6f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -437,6 +437,7 @@ namespace OpenSim.Region.Framework.Scenes { if (m_simulationService == null) m_simulationService = RequestModuleInterface(); + return m_simulationService; } } @@ -3217,7 +3218,7 @@ namespace OpenSim.Region.Framework.Scenes try { m_log.DebugFormat( - "[SCENE]: Removing {0} agent {1} {2} from region {2}", + "[SCENE]: Removing {0} agent {1} {2} from region {3}", (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName); m_sceneGraph.removeUserCount(!isChildAgent); @@ -3879,7 +3880,10 @@ namespace OpenSim.Region.Framework.Scenes ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); if (nearestParcel == null) { - m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: no allowed parcel", cAgentData.AgentID); + m_log.DebugFormat( + "[SCENE]: Denying root agent entry to {0} in {1}: no allowed parcel", + cAgentData.AgentID, RegionInfo.RegionName); + return false; } diff --git a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs index a5d2b23..ea9fc93 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs @@ -45,7 +45,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests { static public Random random; SceneObjectGroup found; - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); [Test] public void T010_AddObjects() diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs index 9a60e50..1c33a5f 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs @@ -44,7 +44,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests public void TestDuplicateObject() { TestHelpers.InMethod(); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); UUID ownerId = new UUID("00000000-0000-0000-0000-000000000010"); string part1Name = "part1"; diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs index 7737d8e..453e077 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs @@ -88,7 +88,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests { TestHelpers.InMethod(); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); int partsToTestCount = 3; SceneObjectGroup so @@ -118,7 +118,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests { TestHelpers.InMethod(); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); string obj1Name = "Alfred"; string obj2Name = "Betty"; @@ -152,7 +152,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests { TestHelpers.InMethod(); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); int partsToTestCount = 3; SceneObjectGroup so @@ -185,7 +185,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests { TestHelpers.InMethod(); - TestScene scene = SceneHelpers.SetupScene(); + TestScene scene = new SceneHelpers().SetupScene(); SceneObjectPart part = SceneHelpers.AddSceneObject(scene); scene.DeleteSceneObject(part.ParentGroup, false); @@ -204,7 +204,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001"); - TestScene scene = SceneHelpers.SetupScene(); + TestScene scene = new SceneHelpers().SetupScene(); // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs index 654b1a2..0076f41 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs @@ -61,7 +61,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); - TestScene scene = SceneHelpers.SetupScene(); + TestScene scene = new SceneHelpers().SetupScene(); IConfigSource configSource = new IniConfigSource(); IConfig config = configSource.AddConfig("Startup"); config.Set("serverside_object_permissions", true); @@ -100,7 +100,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); UUID objectOwnerId = UUID.Parse("20000000-0000-0000-0000-000000000001"); - TestScene scene = SceneHelpers.SetupScene(); + TestScene scene = new SceneHelpers().SetupScene(); IConfigSource configSource = new IniConfigSource(); IConfig config = configSource.AddConfig("Startup"); config.Set("serverside_object_permissions", true); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs index be5b4a8..1add3dd 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs @@ -55,7 +55,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID ownerId = TestHelpers.ParseTail(0x1); int nParts = 3; - TestScene scene = SceneHelpers.SetupScene(); + TestScene scene = new SceneHelpers().SetupScene(); SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(nParts, ownerId, "TestLinkToSelf_", 0x10); scene.AddSceneObject(sog1); scene.LinkObjects(ownerId, sog1.LocalId, new List() { sog1.Parts[1].LocalId }); @@ -71,7 +71,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests bool debugtest = false; - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene); SceneObjectGroup grp1 = part1.ParentGroup; SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene); @@ -153,7 +153,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests bool debugtest = false; - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene); SceneObjectGroup grp1 = part1.ParentGroup; SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene); @@ -286,7 +286,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestHelpers.InMethod(); //log4net.Config.XmlConfigurator.Configure(); - TestScene scene = SceneHelpers.SetupScene(); + TestScene scene = new SceneHelpers().SetupScene(); string rootPartName = "rootpart"; UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001"); @@ -325,7 +325,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestHelpers.InMethod(); //log4net.Config.XmlConfigurator.Configure(); - TestScene scene = SceneHelpers.SetupScene(); + TestScene scene = new SceneHelpers().SetupScene(); string rootPartName = "rootpart"; UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001"); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs index b49c6e7..0a94c19 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs @@ -52,7 +52,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene).ParentGroup; g1.GroupResize(new Vector3(2, 3, 4)); @@ -75,7 +75,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestHelpers.InMethod(); //log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); SceneObjectGroup g1 = SceneHelpers.CreateSceneObject(2, UUID.Zero); g1.RootPart.Scale = new Vector3(2, 3, 4); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs index c582cf6..d2361f8 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs @@ -52,7 +52,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests // UUID itemId = TestHelpers.ParseTail(0x2); string itemName = "Test Script Item"; - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId); scene.AddNewSceneObject(so, true); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs index 9fea3c6..6d255aa 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [SetUp] public void SetUp() { - m_scene = SceneHelpers.SetupScene(); + m_scene = new SceneHelpers().SetupScene(); } [Test] diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index 360566d..742c769 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -52,7 +52,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [SetUp] public void Init() { - m_scene = SceneHelpers.SetupScene(); + m_scene = new SceneHelpers().SetupScene(); m_so1 = SceneHelpers.CreateSceneObject(1, m_ownerId, "so1", 0x10); m_so2 = SceneHelpers.CreateSceneObject(1, m_ownerId, "so2", 0x20); } diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs index c13d82e..c7eaff9 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs @@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); - TestScene scene = SceneHelpers.SetupScene(); + TestScene scene = new SceneHelpers().SetupScene(); IConfigSource configSource = new IniConfigSource(); IConfig startupConfig = configSource.AddConfig("Startup"); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index ed9b179..2e46377 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs @@ -67,10 +67,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests public void Init() { TestHelpers.InMethod(); - - scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); - scene2 = SceneHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); - scene3 = SceneHelpers.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000); + + SceneHelpers sh = new SceneHelpers(); + + scene = sh.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); + scene2 = sh.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); + scene3 = sh.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000); ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); interregionComms.Initialise(new IniConfigSource()); @@ -101,7 +103,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - TestScene scene = SceneHelpers.SetupScene(); + TestScene scene = new SceneHelpers().SetupScene(); ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Not.Null); @@ -126,7 +128,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests IConfig config = configSource.AddConfig("Modules"); config.Set("SimulationServices", "LocalSimulationConnectorModule"); - TestScene scene = SceneHelpers.SetupScene(); + TestScene scene = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(scene, configSource, lsc); UUID agentId = TestHelpers.ParseTail(0x01); @@ -176,8 +178,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests // UUID agent1Id = UUID.Parse("00000000-0000-0000-0000-000000000001"); - TestScene myScene1 = SceneHelpers.SetupScene("Neighbour y", UUID.Random(), 1000, 1000); - TestScene myScene2 = SceneHelpers.SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000); + TestScene myScene1 = new SceneHelpers().SetupScene("Neighbour y", UUID.Random(), 1000, 1000); + TestScene myScene2 = new SceneHelpers().SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000); IConfigSource configSource = new IniConfigSource(); IConfig config = configSource.AddConfig("Startup"); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs index 89f8007..646e5fa 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs @@ -59,7 +59,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - TestScene scene = SceneHelpers.SetupScene(); + TestScene scene = new SceneHelpers().SetupScene(); ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); sp.Flying = true; sp.PhysicsCollisionUpdate(new CollisionEventUpdate()); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs index cfea10d..1d1ff88 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs @@ -64,7 +64,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [SetUp] public void Init() { - m_scene = SceneHelpers.SetupScene(); + m_scene = new SceneHelpers().SetupScene(); } [Test] diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs index b7b8db4..313e350 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests [SetUp] public void Init() { - m_scene = SceneHelpers.SetupScene(); + m_scene = new SceneHelpers().SetupScene(); m_sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); } diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index eb7bfbd..19542ff 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -61,7 +61,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests // Not strictly necessary since FriendsModule assumes it is the default (!) config.Configs["Modules"].Set("EntityTransferModule", etm.Name); - TestScene scene = SceneHelpers.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); + TestScene scene = new SceneHelpers().SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); SceneHelpers.SetupSceneModules(scene, config, etm); Vector3 teleportPosition = new Vector3(10, 11, 12); @@ -83,145 +83,58 @@ namespace OpenSim.Region.Framework.Scenes.Tests // Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); } - /// - /// Test a teleport between two regions that are not neighbours and do not share any neighbours in common. - /// - /// Does not yet do what is says on the tin. - /// Commenting for now - //[Test, LongRunning] - public void TestSimpleNotNeighboursTeleport() + [Test] + public void TestSameSimulatorSeparatedRegionsTeleport() { TestHelpers.InMethod(); - ThreadRunResults results = new ThreadRunResults(); - results.Result = false; - results.Message = "Test did not run"; - TestRunning testClass = new TestRunning(results); +// log4net.Config.XmlConfigurator.Configure(); - Thread testThread = new Thread(testClass.run); + UUID userId = TestHelpers.ParseTail(0x1); - // Seems kind of redundant to start a thread and then join it, however.. We need to protect against - // A thread abort exception in the simulator code. - testThread.Start(); - testThread.Join(); + EntityTransferModule etm = new EntityTransferModule(); + LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); - Assert.That(testClass.results.Result, Is.EqualTo(true), testClass.results.Message); - // Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod()); - } + IConfigSource config = new IniConfigSource(); + config.AddConfig("Modules"); + // Not strictly necessary since FriendsModule assumes it is the default (!) + config.Configs["Modules"].Set("EntityTransferModule", etm.Name); + config.Configs["Modules"].Set("SimulationServices", lscm.Name); - [TearDown] - public void TearDown() - { - try - { - if (MainServer.Instance != null) MainServer.Instance.Stop(); - } - catch (NullReferenceException) - { } - } + SceneHelpers sh = new SceneHelpers(); + TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); + TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000); - } + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); - public class ThreadRunResults - { - public bool Result = false; - public string Message = string.Empty; - } + Vector3 teleportPosition = new Vector3(10, 11, 12); + Vector3 teleportLookAt = new Vector3(20, 21, 22); - public class TestRunning - { - public ThreadRunResults results; - public TestRunning(ThreadRunResults t) - { - results = t; - } - public void run(object o) - { - - //results.Result = true; - log4net.Config.XmlConfigurator.Configure(); - - UUID sceneAId = UUID.Parse("00000000-0000-0000-0000-000000000100"); - UUID sceneBId = UUID.Parse("00000000-0000-0000-0000-000000000200"); - - // shared module - ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); - - - Scene sceneB = SceneHelpers.SetupScene("sceneB", sceneBId, 1010, 1010); - SceneHelpers.SetupSceneModules(sceneB, new IniConfigSource(), interregionComms); - sceneB.RegisterRegionWithGrid(); - - Scene sceneA = SceneHelpers.SetupScene("sceneA", sceneAId, 1000, 1000); - SceneHelpers.SetupSceneModules(sceneA, new IniConfigSource(), interregionComms); - sceneA.RegisterRegionWithGrid(); - - UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000041"); - TestClient client = (TestClient)SceneHelpers.AddScenePresence(sceneA, agentId).ControllingClient; - - ICapabilitiesModule sceneACapsModule = sceneA.RequestModuleInterface(); - - results.Result = (sceneACapsModule.GetCapsPath(agentId) == client.CapsSeedUrl); - - if (!results.Result) - { - results.Message = "Incorrect caps object path set up in sceneA"; - return; - } - - /* - Assert.That( - sceneACapsModule.GetCapsPath(agentId), - Is.EqualTo(client.CapsSeedUrl), - "Incorrect caps object path set up in sceneA"); - */ - // FIXME: This is a hack to get the test working - really the normal OpenSim mechanisms should be used. - - - client.TeleportTargetScene = sceneB; - client.Teleport(sceneB.RegionInfo.RegionHandle, new Vector3(100, 100, 100), new Vector3(40, 40, 40)); - - results.Result = (sceneB.GetScenePresence(agentId) != null); - if (!results.Result) - { - results.Message = "Client does not have an agent in sceneB"; - return; - } - - //Assert.That(sceneB.GetScenePresence(agentId), Is.Not.Null, "Client does not have an agent in sceneB"); - - //Assert.That(sceneA.GetScenePresence(agentId), Is.Null, "Client still had an agent in sceneA"); - - results.Result = (sceneA.GetScenePresence(agentId) == null); - if (!results.Result) - { - results.Message = "Client still had an agent in sceneA"; - return; - } - - ICapabilitiesModule sceneBCapsModule = sceneB.RequestModuleInterface(); - - - results.Result = ("http://" + sceneB.RegionInfo.ExternalHostName + ":" + sceneB.RegionInfo.HttpPort + - "/CAPS/" + sceneBCapsModule.GetCapsPath(agentId) + "0000/" == client.CapsSeedUrl); - if (!results.Result) - { - results.Message = "Incorrect caps object path set up in sceneB"; - return; - } - - // Temporary assertion - caps url construction should at least be doable through a method. - /* - Assert.That( - "http://" + sceneB.RegionInfo.ExternalHostName + ":" + sceneB.RegionInfo.HttpPort + "/CAPS/" + sceneBCapsModule.GetCapsPath(agentId) + "0000/", - Is.EqualTo(client.CapsSeedUrl), - "Incorrect caps object path set up in sceneB"); - */ - // This assertion will currently fail since we don't remove the caps paths when no longer needed - //Assert.That(sceneACapsModule.GetCapsPath(agentId), Is.Null, "sceneA still had a caps object path"); - - // TODO: Check that more of everything is as it should be - - // TODO: test what happens if we try to teleport to a region that doesn't exist + ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId); + sp.AbsolutePosition = new Vector3(30, 31, 32); + + // XXX: A very nasty hack to tell the client about the destination scene without having to crank the whole + // UDP stack (?) + ((TestClient)sp.ControllingClient).TeleportTargetScene = sceneB; + + sceneA.RequestTeleportLocation( + sp.ControllingClient, + sceneB.RegionInfo.RegionHandle, + teleportPosition, + teleportLookAt, + (uint)TeleportFlags.ViaLocation); + + Assert.That(sceneA.GetScenePresence(userId), Is.Null); + + ScenePresence sceneBSp = sceneB.GetScenePresence(userId); + Assert.That(sceneBSp, Is.Not.Null); + Assert.That(sceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName)); + Assert.That(sceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition)); + + // TODO: Add assertions to check correct circuit details in both scenes. + + // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera + // position instead). +// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs index 5c9a77d..d722a09 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs @@ -60,7 +60,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests { TestHelpers.InMethod(); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); scene.Update(1); Assert.That(scene.Frame, Is.EqualTo(1)); diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs index 55c80f5..d15141b 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs @@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); SceneObjectPart sop1 = sog1.RootPart; @@ -81,7 +81,7 @@ namespace OpenSim.Region.Framework.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); SceneObjectPart sop1 = sog1.RootPart; @@ -124,7 +124,7 @@ namespace OpenSim.Region.Framework.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); SceneObjectPart sop1 = sog1.RootPart; @@ -153,7 +153,7 @@ namespace OpenSim.Region.Framework.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); SceneObjectPart sop1 = sog1.RootPart; diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs index 55fc1e7..44d2d45 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs @@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002)); InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID); @@ -85,7 +85,7 @@ namespace OpenSim.Region.Framework.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002)); InventoryFolderBase folder1 diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs index d9fe87c..198e487 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests public void Init() { // FIXME: We don't need a full scene here - it would be enough to set up the asset service. - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); m_assetService = scene.AssetService; m_uuidGatherer = new UuidGatherer(m_assetService); } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index d2f6327..ac638f1 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - TestScene scene = SceneHelpers.SetupScene(); + TestScene scene = new SceneHelpers().SetupScene(); IConfigSource configSource = new IniConfigSource(); IConfig config = configSource.AddConfig("Groups"); config.Set("Enabled", true); diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index eea0b2e..a39257e 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -85,7 +85,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests m_attMod = new AttachmentsModule(); m_npcMod = new NPCModule(); - m_scene = SceneHelpers.SetupScene(); + m_scene = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(m_scene, config, m_afMod, m_umMod, m_attMod, m_npcMod, new BasicInventoryAccessModule()); } diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs index e2d0db2..49266e9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs @@ -63,7 +63,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests IConfig config = initConfigSource.AddConfig("XEngine"); config.Set("Enabled", "true"); - m_scene = SceneHelpers.SetupScene(); + m_scene = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(m_scene, initConfigSource); m_engine = new XEngine.XEngine(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs index 9cf9258..92a63bf 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs @@ -58,7 +58,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests IConfig config = initConfigSource.AddConfig("XEngine"); config.Set("Enabled", "true"); - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); SceneObjectPart part = SceneHelpers.AddSceneObject(scene); XEngine.XEngine engine = new XEngine.XEngine(); @@ -261,7 +261,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests TestHelpers.InMethod(); // Create Prim1. - Scene scene = SceneHelpers.SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); string obj1Name = "Prim1"; UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001"); SceneObjectPart part1 = diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index 7573dff..c51227b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs @@ -67,7 +67,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests config = initConfigSource.AddConfig("NPC"); config.Set("Enabled", "true"); - m_scene = SceneHelpers.SetupScene(); + m_scene = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(m_scene, initConfigSource, new AvatarFactoryModule(), new NPCModule()); m_engine = new XEngine.XEngine(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs index 9d9fc51..9c36108 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs @@ -68,7 +68,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests config = initConfigSource.AddConfig("NPC"); config.Set("Enabled", "true"); - m_scene = SceneHelpers.SetupScene(); + m_scene = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(m_scene, initConfigSource, new AvatarFactoryModule(), new NPCModule()); m_engine = new XEngine.XEngine(); diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs index 7d7bd82..a3f848c 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs @@ -73,7 +73,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine.Tests // to AssemblyResolver.OnAssemblyResolve fails. xEngineConfig.Set("AppDomainLoading", "false"); - m_scene = SceneHelpers.SetupScene("My Test", UUID.Random(), 1000, 1000, null, configSource); + m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource); SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine, wcModule); m_scene.StartScripts(); } diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index 7a6b1cf..8e54707 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs @@ -58,57 +58,67 @@ namespace OpenSim.Tests.Common /// public class SceneHelpers { - public static TestScene SetupScene() + private AgentCircuitManager m_acm = new AgentCircuitManager(); + private ISimulationDataService m_simDataService + = OpenSim.Server.Base.ServerUtils.LoadPlugin("OpenSim.Tests.Common.dll", null); + private IEstateDataService m_estateDataService; + + private LocalAssetServicesConnector m_assetService; + private LocalAuthenticationServicesConnector m_authenticationService; + private LocalInventoryServicesConnector m_inventoryService; + private LocalGridServicesConnector m_gridService; + private LocalUserAccountServicesConnector m_userAccountService; + private LocalPresenceServicesConnector m_presenceService; + + private CoreAssetCache m_cache; + + public SceneHelpers() : this(null) {} + + public SceneHelpers(CoreAssetCache cache) { - return SetupScene(null); + m_assetService = StartAssetService(cache); + m_authenticationService = StartAuthenticationService(); + m_inventoryService = StartInventoryService(); + m_gridService = StartGridService(); + m_userAccountService = StartUserAccountService(); + m_presenceService = StartPresenceService(); + + m_inventoryService.PostInitialise(); + m_assetService.PostInitialise(); + m_userAccountService.PostInitialise(); + m_presenceService.PostInitialise(); + + m_cache = cache; } /// /// Set up a test scene /// /// - /// Automatically starts service threads, as would the normal runtime. + /// Automatically starts services, as would the normal runtime. /// /// - public static TestScene SetupScene(CoreAssetCache cache) + public TestScene SetupScene() { - return SetupScene("Unit test region", UUID.Random(), 1000, 1000, cache); + return SetupScene("Unit test region", UUID.Random(), 1000, 1000); } - public static TestScene SetupScene(string name, UUID id, uint x, uint y) - { - return SetupScene(name, id, x, y, null); - } - - /// - /// Set up a scene. If it's more then one scene, use the same CommunicationsManager to link regions - /// or a different, to get a brand new scene with new shared region modules. - /// - /// Name of the region - /// ID of the region - /// X co-ordinate of the region - /// Y co-ordinate of the region - /// - /// - public static TestScene SetupScene( - string name, UUID id, uint x, uint y, CoreAssetCache cache) + public TestScene SetupScene(string name, UUID id, uint x, uint y) { - return SetupScene(name, id, x, y, cache, new IniConfigSource()); + return SetupScene(name, id, x, y, new IniConfigSource()); } /// - /// Set up a scene. If it's more then one scene, use the same CommunicationsManager to link regions - /// or a different, to get a brand new scene with new shared region modules. + /// Set up a scene. /// /// Name of the region /// ID of the region /// X co-ordinate of the region /// Y co-ordinate of the region - /// /// /// - public static TestScene SetupScene( - string name, UUID id, uint x, uint y, CoreAssetCache cache, IConfigSource configSource) + public TestScene SetupScene( + string name, UUID id, uint x, uint y, IConfigSource configSource) { Console.WriteLine("Setting up test scene {0}", name); @@ -119,30 +129,47 @@ namespace OpenSim.Tests.Common regInfo.RegionName = name; regInfo.RegionID = id; - AgentCircuitManager acm = new AgentCircuitManager(); SceneCommunicationService scs = new SceneCommunicationService(); - ISimulationDataService simDataService = OpenSim.Server.Base.ServerUtils.LoadPlugin("OpenSim.Tests.Common.dll", null); - IEstateDataService estateDataService = null; - TestScene testScene = new TestScene( - regInfo, acm, scs, simDataService, estateDataService, null, false, configSource, null); + regInfo, m_acm, scs, m_simDataService, m_estateDataService, null, false, configSource, null); IRegionModule godsModule = new GodsModule(); godsModule.Initialise(testScene, new IniConfigSource()); testScene.AddModule(godsModule.Name, godsModule); - LocalAssetServicesConnector assetService = StartAssetService(testScene, cache); - StartAuthenticationService(testScene); - LocalInventoryServicesConnector inventoryService = StartInventoryService(testScene); - StartGridService(testScene); - LocalUserAccountServicesConnector userAccountService = StartUserAccountService(testScene); - LocalPresenceServicesConnector presenceService = StartPresenceService(testScene); - - inventoryService.PostInitialise(); - assetService.PostInitialise(); - userAccountService.PostInitialise(); - presenceService.PostInitialise(); + // Add scene to services + m_assetService.AddRegion(testScene); + + if (m_cache != null) + { + m_cache.AddRegion(testScene); + m_cache.RegionLoaded(testScene); + testScene.AddRegionModule(m_cache.Name, m_cache); + } + + m_assetService.RegionLoaded(testScene); + testScene.AddRegionModule(m_assetService.Name, m_assetService); + + m_authenticationService.AddRegion(testScene); + m_authenticationService.RegionLoaded(testScene); + testScene.AddRegionModule(m_authenticationService.Name, m_authenticationService); + + m_inventoryService.AddRegion(testScene); + m_inventoryService.RegionLoaded(testScene); + testScene.AddRegionModule(m_inventoryService.Name, m_inventoryService); + + m_gridService.AddRegion(testScene); + m_gridService.RegionLoaded(testScene); + testScene.AddRegionModule(m_gridService.Name, m_gridService); + + m_userAccountService.AddRegion(testScene); + m_userAccountService.RegionLoaded(testScene); + testScene.AddRegionModule(m_userAccountService.Name, m_userAccountService); + + m_presenceService.AddRegion(testScene); + m_presenceService.RegionLoaded(testScene); + testScene.AddRegionModule(m_presenceService.Name, m_presenceService); testScene.RegionInfo.EstateSettings.EstateOwner = UUID.Random(); testScene.SetModuleInterfaces(); @@ -162,19 +189,17 @@ namespace OpenSim.Tests.Common return testScene; } - private static LocalAssetServicesConnector StartAssetService(Scene testScene, CoreAssetCache cache) + private static LocalAssetServicesConnector StartAssetService(CoreAssetCache cache) { - LocalAssetServicesConnector assetService = new LocalAssetServicesConnector(); IConfigSource config = new IniConfigSource(); - config.AddConfig("Modules"); config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector"); config.AddConfig("AssetService"); config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService"); config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll"); - + + LocalAssetServicesConnector assetService = new LocalAssetServicesConnector(); assetService.Initialise(config); - assetService.AddRegion(testScene); if (cache != null) { @@ -184,56 +209,43 @@ namespace OpenSim.Tests.Common cacheConfig.AddConfig("AssetCache"); cache.Initialise(cacheConfig); - cache.AddRegion(testScene); - cache.RegionLoaded(testScene); - testScene.AddRegionModule(cache.Name, cache); } - - assetService.RegionLoaded(testScene); - testScene.AddRegionModule(assetService.Name, assetService); return assetService; } - private static void StartAuthenticationService(Scene testScene) + private static LocalAuthenticationServicesConnector StartAuthenticationService() { - ISharedRegionModule service = new LocalAuthenticationServicesConnector(); IConfigSource config = new IniConfigSource(); - config.AddConfig("Modules"); config.AddConfig("AuthenticationService"); config.Configs["Modules"].Set("AuthenticationServices", "LocalAuthenticationServicesConnector"); config.Configs["AuthenticationService"].Set( "LocalServiceModule", "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService"); config.Configs["AuthenticationService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); - + + LocalAuthenticationServicesConnector service = new LocalAuthenticationServicesConnector(); service.Initialise(config); - service.AddRegion(testScene); - service.RegionLoaded(testScene); - testScene.AddRegionModule(service.Name, service); - //m_authenticationService = service; + + return service; } - private static LocalInventoryServicesConnector StartInventoryService(Scene testScene) + private static LocalInventoryServicesConnector StartInventoryService() { - LocalInventoryServicesConnector inventoryService = new LocalInventoryServicesConnector(); - IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); config.AddConfig("InventoryService"); config.Configs["Modules"].Set("InventoryServices", "LocalInventoryServicesConnector"); config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Services.InventoryService.dll:InventoryService"); config.Configs["InventoryService"].Set("StorageProvider", "OpenSim.Tests.Common.dll"); - + + LocalInventoryServicesConnector inventoryService = new LocalInventoryServicesConnector(); inventoryService.Initialise(config); - inventoryService.AddRegion(testScene); - inventoryService.RegionLoaded(testScene); - testScene.AddRegionModule(inventoryService.Name, inventoryService); return inventoryService; } - private static LocalGridServicesConnector StartGridService(Scene testScene) + private static LocalGridServicesConnector StartGridService() { IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); @@ -245,8 +257,6 @@ namespace OpenSim.Tests.Common LocalGridServicesConnector gridService = new LocalGridServicesConnector(); gridService.Initialise(config); - gridService.AddRegion(testScene); - gridService.RegionLoaded(testScene); return gridService; } @@ -256,7 +266,7 @@ namespace OpenSim.Tests.Common /// /// /// - private static LocalUserAccountServicesConnector StartUserAccountService(Scene testScene) + private static LocalUserAccountServicesConnector StartUserAccountService() { IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); @@ -268,10 +278,6 @@ namespace OpenSim.Tests.Common LocalUserAccountServicesConnector userAccountService = new LocalUserAccountServicesConnector(); userAccountService.Initialise(config); - - userAccountService.AddRegion(testScene); - userAccountService.RegionLoaded(testScene); - testScene.AddRegionModule(userAccountService.Name, userAccountService); return userAccountService; } @@ -280,7 +286,7 @@ namespace OpenSim.Tests.Common /// Start a presence service /// /// - private static LocalPresenceServicesConnector StartPresenceService(Scene testScene) + private static LocalPresenceServicesConnector StartPresenceService() { IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); @@ -292,10 +298,6 @@ namespace OpenSim.Tests.Common LocalPresenceServicesConnector presenceService = new LocalPresenceServicesConnector(); presenceService.Initialise(config); - - presenceService.AddRegion(testScene); - presenceService.RegionLoaded(testScene); - testScene.AddRegionModule(presenceService.Name, presenceService); return presenceService; } @@ -313,19 +315,51 @@ namespace OpenSim.Tests.Common /// /// Setup modules for a scene. /// - /// + /// + /// If called directly, then all the modules must be shared modules. + /// + /// /// /// public static void SetupSceneModules(Scene scene, IConfigSource config, params object[] modules) { + SetupSceneModules(new Scene[] { scene }, config, modules); + } + + /// + /// Setup modules for a scene using their default settings. + /// + /// + /// + public static void SetupSceneModules(Scene[] scenes, params object[] modules) + { + SetupSceneModules(scenes, new IniConfigSource(), modules); + } + + /// + /// Setup modules for scenes. + /// + /// + /// If called directly, then all the modules must be shared modules. + /// + /// + /// + /// + public static void SetupSceneModules(Scene[] scenes, IConfigSource config, params object[] modules) + { List newModules = new List(); foreach (object module in modules) { if (module is IRegionModule) { IRegionModule m = (IRegionModule)module; - m.Initialise(scene, config); - scene.AddModule(m.Name, m); + + foreach (Scene scene in scenes) + { + m.Initialise(scene, config); + scene.AddModule(m.Name, m); + } + m.PostInitialise(); } else if (module is IRegionModuleBase) @@ -345,15 +379,19 @@ namespace OpenSim.Tests.Common foreach (IRegionModuleBase module in newModules) { - module.AddRegion(scene); - scene.AddRegionModule(module.Name, module); + foreach (Scene scene in scenes) + { + module.AddRegion(scene); + scene.AddRegionModule(module.Name, module); + } } // RegionLoaded is fired after all modules have been appropriately added to all scenes foreach (IRegionModuleBase module in newModules) - module.RegionLoaded(scene); + foreach (Scene scene in scenes) + module.RegionLoaded(scene); - scene.SetModuleInterfaces(); + foreach (Scene scene in scenes) { scene.SetModuleInterfaces(); } } /// diff --git a/OpenSim/Tests/Common/Mock/TestLandChannel.cs b/OpenSim/Tests/Common/Mock/TestLandChannel.cs index 0e4dfb9..4b4d52d 100644 --- a/OpenSim/Tests/Common/Mock/TestLandChannel.cs +++ b/OpenSim/Tests/Common/Mock/TestLandChannel.cs @@ -46,6 +46,14 @@ namespace OpenSim.Tests.Common.Mock { m_scene = scene; m_parcels = new List(); + SetupDefaultParcel(); + } + + private void SetupDefaultParcel() + { + ILandObject obj = new LandObject(UUID.Zero, false, m_scene); + obj.LandData.Name = "Your Parcel"; + m_parcels.Add(obj); } public List ParcelsNearPoint(Vector3 position) @@ -63,11 +71,7 @@ namespace OpenSim.Tests.Common.Mock m_parcels.Clear(); if (setupDefaultParcel) - { - ILandObject obj = new LandObject(UUID.Zero, false, m_scene); - obj.LandData.Name = "Your Parcel"; - m_parcels.Add(obj); - } + SetupDefaultParcel(); } protected ILandObject GetNoLand() @@ -102,6 +106,5 @@ namespace OpenSim.Tests.Common.Mock public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) {} public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) {} - } -} +} \ No newline at end of file diff --git a/OpenSim/Tests/Torture/NPCTortureTests.cs b/OpenSim/Tests/Torture/NPCTortureTests.cs index 0224505..731df68 100644 --- a/OpenSim/Tests/Torture/NPCTortureTests.cs +++ b/OpenSim/Tests/Torture/NPCTortureTests.cs @@ -98,7 +98,7 @@ namespace OpenSim.Tests.Torture umm = new UserManagementModule(); am = new AttachmentsModule(); - scene = SceneHelpers.SetupScene(); + scene = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(scene, config, afm, umm, am, new BasicInventoryAccessModule(), new NPCModule()); } diff --git a/OpenSim/Tests/Torture/ObjectTortureTests.cs b/OpenSim/Tests/Torture/ObjectTortureTests.cs index d0d2199..195d47b 100644 --- a/OpenSim/Tests/Torture/ObjectTortureTests.cs +++ b/OpenSim/Tests/Torture/ObjectTortureTests.cs @@ -126,7 +126,7 @@ namespace OpenSim.Tests.Torture // Using a local variable for scene, at least on mono 2.6.7, means that it's much more likely to be garbage // collected when we teardown this test. If it's done in a member variable, even if that is subsequently // nulled out, the garbage collect can be delayed. - TestScene scene = SceneHelpers.SetupScene(); + TestScene scene = new SceneHelpers().SetupScene(); // Process process = Process.GetCurrentProcess(); // long startProcessMemory = process.PrivateMemorySize64; diff --git a/OpenSim/Tests/Torture/ScriptTortureTests.cs b/OpenSim/Tests/Torture/ScriptTortureTests.cs index 2ef55b3..24f278f 100644 --- a/OpenSim/Tests/Torture/ScriptTortureTests.cs +++ b/OpenSim/Tests/Torture/ScriptTortureTests.cs @@ -84,7 +84,7 @@ namespace OpenSim.Tests.Torture // to AssemblyResolver.OnAssemblyResolve fails. xEngineConfig.Set("AppDomainLoading", "false"); - m_scene = SceneHelpers.SetupScene("My Test", UUID.Random(), 1000, 1000, null, configSource); + m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource); SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine, wcModule); m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; -- cgit v1.1 From e4e754ee93de0e0b6fde3b3ccd20085d3d4a09a1 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 27 Apr 2012 09:23:56 -0700 Subject: MapImageService: added an additional security check for OSGrid and other grids like it. --- .../Server/Handlers/Map/MapAddServerConnector.cs | 48 +++++++++++++++++++--- bin/Robust.HG.ini.example | 4 ++ bin/Robust.ini.example | 4 ++ 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs index 75dd711..c87de92 100644 --- a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs @@ -33,17 +33,24 @@ using System.Xml; using Nini.Config; using log4net; +using OpenMetaverse; +using OpenSim.Framework; using OpenSim.Server.Base; using OpenSim.Services.Interfaces; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Server.Handlers.Base; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + namespace OpenSim.Server.Handlers.MapImage { public class MapAddServiceConnector : ServiceConnector { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private IMapImageService m_MapService; + private IGridService m_GridService; private string m_ConfigName = "MapImageService"; public MapAddServiceConnector(IConfigSource config, IHttpServer server, string configName) : @@ -53,16 +60,26 @@ namespace OpenSim.Server.Handlers.MapImage if (serverConfig == null) throw new Exception(String.Format("No section {0} in config file", m_ConfigName)); - string gridService = serverConfig.GetString("LocalServiceModule", + string mapService = serverConfig.GetString("LocalServiceModule", String.Empty); - if (gridService == String.Empty) + if (mapService == String.Empty) throw new Exception("No LocalServiceModule in config file"); Object[] args = new Object[] { config }; - m_MapService = ServerUtils.LoadPlugin(gridService, args); + m_MapService = ServerUtils.LoadPlugin(mapService, args); + + string gridService = serverConfig.GetString("GridService", String.Empty); + if (gridService != string.Empty) + m_GridService = ServerUtils.LoadPlugin(gridService, args); + + if (m_GridService != null) + m_log.InfoFormat("[MAP IMAGE HANDLER]: GridService check is ON"); + else + m_log.InfoFormat("[MAP IMAGE HANDLER]: GridService check is OFF"); + + server.AddStreamHandler(new MapServerPostHandler(m_MapService, m_GridService)); - server.AddStreamHandler(new MapServerPostHandler(m_MapService)); } } @@ -70,11 +87,13 @@ namespace OpenSim.Server.Handlers.MapImage { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private IMapImageService m_MapService; + private IGridService m_GridService; - public MapServerPostHandler(IMapImageService service) : + public MapServerPostHandler(IMapImageService service, IGridService grid) : base("POST", "/map") { m_MapService = service; + m_GridService = grid; } public override byte[] Handle(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) @@ -105,6 +124,25 @@ namespace OpenSim.Server.Handlers.MapImage // if (request.ContainsKey("TYPE")) // type = request["TYPE"].ToString(); + if (m_GridService != null) + { + GridRegion r = m_GridService.GetRegionByPosition(UUID.Zero, x * (int)Constants.RegionSize, y * (int)Constants.RegionSize); + if (r != null) + { + if (r.ExternalEndPoint.Address != httpRequest.RemoteIPEndPoint.Address) + { + m_log.WarnFormat("[MAP IMAGE HANDLER]: IP address {0} may be rogue", httpRequest.RemoteIPEndPoint.Address); + return FailureResult("IP address of caller does not match IP address of registered region"); + } + + } + else + { + m_log.WarnFormat("[MAP IMAGE HANDLER]: IP address {0} may be rogue", httpRequest.RemoteIPEndPoint.Address); + return FailureResult("Region not found at given coordinates"); + } + } + byte[] data = Convert.FromBase64String(request["DATA"].ToString()); string reason = string.Empty; diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 4ea5ffd..1b5d37c 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -279,6 +279,10 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" ; Set this if you want to change the default ; TilesStoragePath = "maptiles" + ; + ; If for some reason you have the AddMapTile service outside the firewall (e.g. 8002), + ; you may want to set this. Otherwise, don't set it, because it's already protected. + ; GridService = "OpenSim.Services.GridService.dll:GridService" [GridInfoService] ; These settings are used to return information on a get_grid_info call. diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index 69e94a5..40b8d83 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -254,6 +254,10 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" ; Set this if you want to change the default ; TilesStoragePath = "maptiles" + ; + ; If for some reason you have the AddMapTile service outside the firewall (e.g. 8002), + ; you may want to set this. Otherwise, don't set it, because it's already protected. + ; GridService = "OpenSim.Services.GridService.dll:GridService" [GridInfoService] -- cgit v1.1 From c84f63f4dc98613ff286b9d959c71b738e8bc5ed Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 27 Apr 2012 09:24:50 -0700 Subject: Minor change in error message (HG teleport failures) --- .../CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 634fb43..1854b4a 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -173,7 +173,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (sp.UserLevel < m_levelHGTeleport) { m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel."); - reason = "HyperGrid teleport not permitted"; + reason = "Hypergrid teleport not allowed"; return false; } -- cgit v1.1 From ac64fe03d8992a041933c303fa12933393cf1713 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 27 Apr 2012 09:59:46 -0700 Subject: Amend to last commit: account for the existence of proxies. --- .../Server/Handlers/Map/MapAddServerConnector.cs | 35 ++++++++++++++++++++-- bin/Robust.HG.ini.example | 3 ++ bin/Robust.ini.example | 4 +++ 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs index c87de92..cc7ef9d 100644 --- a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs @@ -78,7 +78,8 @@ namespace OpenSim.Server.Handlers.MapImage else m_log.InfoFormat("[MAP IMAGE HANDLER]: GridService check is OFF"); - server.AddStreamHandler(new MapServerPostHandler(m_MapService, m_GridService)); + bool proxy = serverConfig.GetBoolean("HasProxy", false); + server.AddStreamHandler(new MapServerPostHandler(m_MapService, m_GridService, proxy)); } } @@ -88,12 +89,14 @@ namespace OpenSim.Server.Handlers.MapImage private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private IMapImageService m_MapService; private IGridService m_GridService; + bool m_Proxy; - public MapServerPostHandler(IMapImageService service, IGridService grid) : + public MapServerPostHandler(IMapImageService service, IGridService grid, bool proxy) : base("POST", "/map") { m_MapService = service; m_GridService = grid; + m_Proxy = proxy; } public override byte[] Handle(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) @@ -129,7 +132,7 @@ namespace OpenSim.Server.Handlers.MapImage GridRegion r = m_GridService.GetRegionByPosition(UUID.Zero, x * (int)Constants.RegionSize, y * (int)Constants.RegionSize); if (r != null) { - if (r.ExternalEndPoint.Address != httpRequest.RemoteIPEndPoint.Address) + if (r.ExternalEndPoint.Address != GetCallerIP(httpRequest)) { m_log.WarnFormat("[MAP IMAGE HANDLER]: IP address {0} may be rogue", httpRequest.RemoteIPEndPoint.Address); return FailureResult("IP address of caller does not match IP address of registered region"); @@ -221,5 +224,31 @@ namespace OpenSim.Server.Handlers.MapImage return ms.ToArray(); } + + private System.Net.IPAddress GetCallerIP(IOSHttpRequest request) + { + if (!m_Proxy) + return request.RemoteIPEndPoint.Address; + + // We're behind a proxy + string xff = "X-Forwarded-For"; + string xffValue = request.Headers[xff.ToLower()]; + if (xffValue == null || (xffValue != null && xffValue == string.Empty)) + xffValue = request.Headers[xff]; + + if (xffValue == null || (xffValue != null && xffValue == string.Empty)) + { + m_log.WarnFormat("[MAP IMAGE HANDLER]: No XFF header"); + return request.RemoteIPEndPoint.Address; + } + + System.Net.IPEndPoint ep = Util.GetClientIPFromXFF(xffValue); + if (ep != null) + return ep.Address; + + // Oops + return request.RemoteIPEndPoint.Address; + } + } } diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 1b5d37c..be75407 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -283,6 +283,9 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ; If for some reason you have the AddMapTile service outside the firewall (e.g. 8002), ; you may want to set this. Otherwise, don't set it, because it's already protected. ; GridService = "OpenSim.Services.GridService.dll:GridService" + ; + ; Additionally, if you run this server behind a proxy, set this to true + ; HasProxy = false [GridInfoService] ; These settings are used to return information on a get_grid_info call. diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index 40b8d83..582af27 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -258,6 +258,10 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ; If for some reason you have the AddMapTile service outside the firewall (e.g. 8002), ; you may want to set this. Otherwise, don't set it, because it's already protected. ; GridService = "OpenSim.Services.GridService.dll:GridService" + ; + ; Additionally, if you run this server behind a proxy, set this to true + ; HasProxy = false + [GridInfoService] -- cgit v1.1 From 292752bb78984c84b4305f32226d7f226092a08a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 27 Apr 2012 10:22:43 -0700 Subject: MapImage security issue: better error messages --- OpenSim/Server/Handlers/Map/MapAddServerConnector.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs index cc7ef9d..a612114 100644 --- a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs @@ -132,16 +132,18 @@ namespace OpenSim.Server.Handlers.MapImage GridRegion r = m_GridService.GetRegionByPosition(UUID.Zero, x * (int)Constants.RegionSize, y * (int)Constants.RegionSize); if (r != null) { - if (r.ExternalEndPoint.Address != GetCallerIP(httpRequest)) + System.Net.IPAddress ipAddr = GetCallerIP(httpRequest); + if (r.ExternalEndPoint.Address != ipAddr) { - m_log.WarnFormat("[MAP IMAGE HANDLER]: IP address {0} may be rogue", httpRequest.RemoteIPEndPoint.Address); + m_log.WarnFormat("[MAP IMAGE HANDLER]: IP address {0} may be trying to impersonate region in IP {1}", ipAddr, r.ExternalEndPoint.Address); return FailureResult("IP address of caller does not match IP address of registered region"); } } else { - m_log.WarnFormat("[MAP IMAGE HANDLER]: IP address {0} may be rogue", httpRequest.RemoteIPEndPoint.Address); + m_log.WarnFormat("[MAP IMAGE HANDLER]: IP address {0} may be rogue. Region not found at coordinates {1}-{2}", + httpRequest.RemoteIPEndPoint.Address, x, y); return FailureResult("Region not found at given coordinates"); } } -- cgit v1.1 From a9dbe393194b58447f20984eff03d366c03a01e4 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 27 Apr 2012 10:39:20 -0700 Subject: MapImage security issue. Compare strings instead of IPAddresses. --- OpenSim/Server/Handlers/Map/MapAddServerConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs index a612114..8ba188d 100644 --- a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs @@ -133,7 +133,7 @@ namespace OpenSim.Server.Handlers.MapImage if (r != null) { System.Net.IPAddress ipAddr = GetCallerIP(httpRequest); - if (r.ExternalEndPoint.Address != ipAddr) + if (r.ExternalEndPoint.Address.ToString() != ipAddr.ToString()) { m_log.WarnFormat("[MAP IMAGE HANDLER]: IP address {0} may be trying to impersonate region in IP {1}", ipAddr, r.ExternalEndPoint.Address); return FailureResult("IP address of caller does not match IP address of registered region"); -- cgit v1.1 From 9bc94c502a8e30b0d727f15d0e4b4bb22d163d6c Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 27 Apr 2012 11:05:40 -0700 Subject: MapImageService: changed the event at which the map tiles are uploaded, because they were being uploaded before the region was registered with the grid --- .../MapImage/MapImageServiceModule.cs | 15 ++++++++++++--- OpenSim/Server/Handlers/Map/MapAddServerConnector.cs | 4 ++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs index 6d3ace9..322a9f8 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs @@ -146,9 +146,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage lock (m_scenes) m_scenes[scene.RegionInfo.RegionID] = scene; - scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded); + scene.EventManager.OnLoginsEnabled += OnLoginsEnabled; } + /// /// /// @@ -163,9 +164,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage #endregion ISharedRegionModule - void EventManager_OnPrimsLoaded(Scene s) + void OnLoginsEnabled(string regionName) { - UploadMapTile(s); + Scene scene = null; + foreach (Scene s in m_scenes.Values) + if (s.RegionInfo.RegionName == regionName) + { + scene = s; + break; + } + if (scene != null) + UploadMapTile(scene); } diff --git a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs index 8ba188d..4a61969 100644 --- a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs @@ -129,10 +129,10 @@ namespace OpenSim.Server.Handlers.MapImage if (m_GridService != null) { + System.Net.IPAddress ipAddr = GetCallerIP(httpRequest); GridRegion r = m_GridService.GetRegionByPosition(UUID.Zero, x * (int)Constants.RegionSize, y * (int)Constants.RegionSize); if (r != null) { - System.Net.IPAddress ipAddr = GetCallerIP(httpRequest); if (r.ExternalEndPoint.Address.ToString() != ipAddr.ToString()) { m_log.WarnFormat("[MAP IMAGE HANDLER]: IP address {0} may be trying to impersonate region in IP {1}", ipAddr, r.ExternalEndPoint.Address); @@ -143,7 +143,7 @@ namespace OpenSim.Server.Handlers.MapImage else { m_log.WarnFormat("[MAP IMAGE HANDLER]: IP address {0} may be rogue. Region not found at coordinates {1}-{2}", - httpRequest.RemoteIPEndPoint.Address, x, y); + ipAddr, x, y); return FailureResult("Region not found at given coordinates"); } } -- cgit v1.1 From b35a1d56818386fc70a4a71e3cd8f6dd6d0e2193 Mon Sep 17 00:00:00 2001 From: Stefan_Boom Date: Sat, 14 Apr 2012 22:05:16 +0200 Subject: Fixing wrong position of llSensor, SensePoint wasnt following the rotation of the root prim. --- .../Api/Implementation/Plugins/SensorRepeat.cs | 30 ++++++++++++++++------ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index 1c272f8..57f741c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs @@ -308,7 +308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins } SceneObjectPart SensePoint = ts.host; - Vector3 fromRegionPos = SensePoint.AbsolutePosition; + Vector3 fromRegionPos = SensePoint.GetWorldPosition(); // pre define some things to avoid repeated definitions in the loop body Vector3 toRegionPos; @@ -319,14 +319,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins float dy; float dz; - Quaternion q = SensePoint.RotationOffset; + Quaternion q = SensePoint.GetWorldRotation(); if (SensePoint.ParentGroup.IsAttachment) { - // In attachments, the sensor cone always orients with the + // In attachments, rotate the sensor cone with the // avatar rotation. This may include a nonzero elevation if // in mouselook. + // This will not include the rotation and position of the + // attachment point (e.g. your head when a sensor is in your + // hair attached to your scull. Your hair will turn with + // your head but the sensor will stay with your (global) + // avatar rotation and position. + // Position of a sensor in a child prim attached to an avatar + // will be still wrong. ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); - q = avatar.Rotation; + q = avatar.Rotation*q; } LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); @@ -439,16 +446,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins return sensedEntities; SceneObjectPart SensePoint = ts.host; - Vector3 fromRegionPos = SensePoint.AbsolutePosition; + Vector3 fromRegionPos = SensePoint.GetWorldPosition(); - Quaternion q = SensePoint.RotationOffset; + Quaternion q = SensePoint.GetWorldRotation(); if (SensePoint.ParentGroup.IsAttachment) { - // In attachments, the sensor cone always orients with the + // In attachments, rotate the sensor cone with the // avatar rotation. This may include a nonzero elevation if // in mouselook. + // This will not include the rotation and position of the + // attachment point (e.g. your head when a sensor is in your + // hair attached to your scull. Your hair will turn with + // your head but the sensor will stay with your (global) + // avatar rotation and position. + // Position of a sensor in a child prim attached to an avatar + // will be still wrong. ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); - q = avatar.Rotation; + q = avatar.Rotation*q; } LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); -- cgit v1.1 From e39e4f6bfb9d28317c2547094f5fe79969f4ede9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 27 Apr 2012 19:40:19 +0100 Subject: minor: style adjustments in SensorRepeat, mainly related to patch from stoehr --- .../ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index 57f741c..3844753 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs @@ -222,7 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins // Is the sensor type is AGENT and not SCRIPTED then include agents if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0) { - sensedEntities.AddRange(doAgentSensor(ts)); + sensedEntities.AddRange(doAgentSensor(ts)); } // If SCRIPTED or PASSIVE or ACTIVE check objects @@ -333,8 +333,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins // Position of a sensor in a child prim attached to an avatar // will be still wrong. ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); - q = avatar.Rotation*q; + q = avatar.Rotation * q; } + LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); @@ -462,7 +463,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins // Position of a sensor in a child prim attached to an avatar // will be still wrong. ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); - q = avatar.Rotation*q; + q = avatar.Rotation * q; } LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); -- cgit v1.1 From 9d1791def83469a10ba62ca475e934d5547bc2d8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 27 Apr 2012 19:42:12 +0100 Subject: Add Stefan_Boom / stoehr to contributors --- CONTRIBUTORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 1370449..ad95cf7 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -143,6 +143,7 @@ what it is today. * sempuki * SignpostMarv * SpotOn3D +* Stefan_Boom / stoehr * Strawberry Fride * Talun * tglion -- cgit v1.1 From 37d770f814321b461fc3380345d7ffcd1e00acc9 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 23 Apr 2012 18:30:25 +0300 Subject: Use DotNetZip to compress OARs and IARs. DotNetZip provides much better compression than standard .NET. --- .../Archiver/InventoryArchiveWriteRequest.cs | 5 +- .../Archiver/ArchiveWriteRequestPreparation.cs | 5 +- ThirdPartyLicenses/DotNetZip-bzip2.txt | 29 +++++++++ ThirdPartyLicenses/DotNetZip-zlib.txt | 70 +++++++++++++++++++++ ThirdPartyLicenses/DotNetZip.txt | 33 ++++++++++ bin/Ionic.Zip.dll | Bin 0 -> 462336 bytes prebuild.xml | 1 + 7 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 ThirdPartyLicenses/DotNetZip-bzip2.txt create mode 100644 ThirdPartyLicenses/DotNetZip-zlib.txt create mode 100644 ThirdPartyLicenses/DotNetZip.txt create mode 100644 bin/Ionic.Zip.dll diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index 0ee7606..6587ead 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs @@ -39,6 +39,9 @@ using OpenSim.Framework.Serialization.External; using OpenSim.Region.CoreModules.World.Archiver; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; +using Ionic.Zlib; +using GZipStream = Ionic.Zlib.GZipStream; +using CompressionMode = Ionic.Zlib.CompressionMode; namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { @@ -99,7 +102,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver scene, userInfo, invPath, - new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress)) + new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress, CompressionLevel.BestCompression)) { } diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index ab3cc41..eabe46e 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -40,6 +40,9 @@ using OpenSim.Framework.Serialization; using OpenSim.Region.CoreModules.World.Terrain; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using Ionic.Zlib; +using GZipStream = Ionic.Zlib.GZipStream; +using CompressionMode = Ionic.Zlib.CompressionMode; namespace OpenSim.Region.CoreModules.World.Archiver { @@ -82,7 +85,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver { try { - m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress); + m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress, CompressionLevel.BestCompression); } catch (EntryPointNotFoundException e) { diff --git a/ThirdPartyLicenses/DotNetZip-bzip2.txt b/ThirdPartyLicenses/DotNetZip-bzip2.txt new file mode 100644 index 0000000..f8b4346 --- /dev/null +++ b/ThirdPartyLicenses/DotNetZip-bzip2.txt @@ -0,0 +1,29 @@ + +The managed BZIP2 code included in Ionic.BZip2.dll and Ionic.Zip.dll is +modified code, based on the bzip2 code in the Apache commons compress +library. + +The original BZip2 was created by Julian Seward, and is licensed under +the BSD license. + +The following license applies to the Apache code: +----------------------------------------------------------------------- + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ diff --git a/ThirdPartyLicenses/DotNetZip-zlib.txt b/ThirdPartyLicenses/DotNetZip-zlib.txt new file mode 100644 index 0000000..801e941 --- /dev/null +++ b/ThirdPartyLicenses/DotNetZip-zlib.txt @@ -0,0 +1,70 @@ + +The following licenses govern use of the accompanying software, the +DotNetZip library ("the software"). If you use the software, you accept +these licenses. If you do not accept the license, do not use the software. + +The managed ZLIB code included in Ionic.Zlib.dll and Ionic.Zip.dll is +modified code, based on jzlib. + + + +The following notice applies to jzlib: +----------------------------------------------------------------------- + +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. 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. + +3. The names of the authors may not be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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. + +----------------------------------------------------------------------- + +jzlib is based on zlib-1.1.3. + +The following notice applies to zlib: + +----------------------------------------------------------------------- + +Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler + + The ZLIB software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly jloup@gzip.org + Mark Adler madler@alumni.caltech.edu + + +----------------------------------------------------------------------- diff --git a/ThirdPartyLicenses/DotNetZip.txt b/ThirdPartyLicenses/DotNetZip.txt new file mode 100644 index 0000000..c3103fd --- /dev/null +++ b/ThirdPartyLicenses/DotNetZip.txt @@ -0,0 +1,33 @@ +Microsoft Public License (Ms-PL) + +This license governs use of the accompanying software, the DotNetZip library ("the software"). If you use the software, you accept this license. If you do not accept the license, do not use the software. + +1. Definitions + +The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. + +A "contribution" is the original software, or any additions or changes to the software. + +A "contributor" is any person that distributes its contribution under this license. + +"Licensed patents" are a contributor's patent claims that read directly on its contribution. + +2. Grant of Rights + +(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. + +(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. + +3. Conditions and Limitations + +(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. + +(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. + +(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. + +(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. + +(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. + + diff --git a/bin/Ionic.Zip.dll b/bin/Ionic.Zip.dll new file mode 100644 index 0000000..95fa928 Binary files /dev/null and b/bin/Ionic.Zip.dll differ diff --git a/prebuild.xml b/prebuild.xml index 6a90d64..0c90ac0 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1472,6 +1472,7 @@ + -- cgit v1.1 From 9622e8ac72d29b75b96d2dd481671b57d0a204bf Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 23 Apr 2012 19:20:46 +0300 Subject: If a Grid God teleports then include the Godlike teleport flag. This can affect the starting position in the destination region. --- .../EntityTransfer/EntityTransferModule.cs | 6 +++++ .../World/Permissions/PermissionsModule.cs | 31 +++++++++++++++------- .../Region/Framework/Scenes/Scene.Permissions.cs | 17 ++++++++++++ 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index a318a3c..779fd6b 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -161,6 +161,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) { + if (sp.Scene.Permissions.IsGridGod(sp.UUID)) + { + // This user will be a God in the destination scene, too + teleportFlags |= (uint)TeleportFlags.Godlike; + } + if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) return; diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 2032905..7d75fad 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -166,6 +166,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions m_scene.Permissions.OnDeedParcel += CanDeedParcel; m_scene.Permissions.OnDeedObject += CanDeedObject; m_scene.Permissions.OnIsGod += IsGod; + m_scene.Permissions.OnIsGridGod += IsGridGod; m_scene.Permissions.OnIsAdministrator += IsAdministrator; m_scene.Permissions.OnDuplicateObject += CanDuplicateObject; m_scene.Permissions.OnDeleteObject += CanDeleteObject; //MAYBE FULLY IMPLEMENTED @@ -466,22 +467,34 @@ namespace OpenSim.Region.CoreModules.World.Permissions if (IsEstateManager(user) && m_RegionManagerIsGod) return true; + if (IsGridGod(user, null)) + return true; + + return false; + } + + /// + /// Is the given user a God throughout the grid (not just in the current scene)? + /// + /// The user + /// Unused, can be null + /// + protected bool IsGridGod(UUID user, Scene scene) + { + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; + + if (user == UUID.Zero) return false; + if (m_allowGridGods) { ScenePresence sp = m_scene.GetScenePresence(user); if (sp != null) - { - if (sp.UserLevel >= 200) - return true; - return false; - } + return (sp.UserLevel >= 200); UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, user); if (account != null) - { - if (account.UserLevel >= 200) - return true; - } + return (account.UserLevel >= 200); } return false; diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs index e1fedf4..535d87a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs @@ -67,6 +67,7 @@ namespace OpenSim.Region.Framework.Scenes public delegate bool RunConsoleCommandHandler(UUID user, Scene requestFromScene); public delegate bool IssueEstateCommandHandler(UUID user, Scene requestFromScene, bool ownerCommand); public delegate bool IsGodHandler(UUID user, Scene requestFromScene); + public delegate bool IsGridGodHandler(UUID user, Scene requestFromScene); public delegate bool IsAdministratorHandler(UUID user); public delegate bool EditParcelHandler(UUID user, ILandObject parcel, Scene scene); public delegate bool EditParcelPropertiesHandler(UUID user, ILandObject parcel, GroupPowers p, Scene scene); @@ -134,6 +135,7 @@ namespace OpenSim.Region.Framework.Scenes public event RunConsoleCommandHandler OnRunConsoleCommand; public event IssueEstateCommandHandler OnIssueEstateCommand; public event IsGodHandler OnIsGod; + public event IsGridGodHandler OnIsGridGod; public event IsAdministratorHandler OnIsAdministrator; // public event EditParcelHandler OnEditParcel; public event EditParcelPropertiesHandler OnEditParcelProperties; @@ -728,6 +730,21 @@ namespace OpenSim.Region.Framework.Scenes return true; } + public bool IsGridGod(UUID user) + { + IsGridGodHandler handler = OnIsGridGod; + if (handler != null) + { + Delegate[] list = handler.GetInvocationList(); + foreach (IsGridGodHandler h in list) + { + if (h(user, m_scene) == false) + return false; + } + } + return true; + } + public bool IsAdministrator(UUID user) { IsAdministratorHandler handler = OnIsAdministrator; -- cgit v1.1 From 6473674bbf6ce006512083902e8ff1796d8c8b22 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 23 Apr 2012 19:07:36 +0300 Subject: Fixed: custom walking animations didn't stop when the avatar stopped walking. This happened because the scripts were notified about control changes (e.g., the user stopped pressing the Forward key) when the animation was still WALK, so the script didn't stop the walking animation. Fixing this required: a) Update the movement animation *before* notifying the script; b) Add locking to prevent clashes with the Heartbeat thread (which also updates the animations); c) Handle the case of a user who stops walking just as the avatar is in the air: the avatar should STAND in that case, not WALK. This reverts commit feef1dd73243cfdd5322632fb67e64cabc1ad4bc. --- .../Scenes/Animation/ScenePresenceAnimator.cs | 19 +++++++++---- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 33 +++++++++++++--------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index f5623bd..14ae287 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -278,6 +278,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation return "FALLDOWN"; } + // Check if the user has stopped walking just now + if (CurrentMovementAnimation == "WALK" && (move == Vector3.Zero)) + return "STAND"; + return CurrentMovementAnimation; } @@ -402,13 +406,16 @@ namespace OpenSim.Region.Framework.Scenes.Animation /// public void UpdateMovementAnimations() { - CurrentMovementAnimation = DetermineMovementAnimation(); + lock (m_animations) + { + CurrentMovementAnimation = DetermineMovementAnimation(); -// m_log.DebugFormat( -// "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()", -// CurrentMovementAnimation, m_scenePresence.Name); +// m_log.DebugFormat( +// "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()", +// CurrentMovementAnimation, m_scenePresence.Name); - TrySetMovementAnimation(CurrentMovementAnimation); + TrySetMovementAnimation(CurrentMovementAnimation); + } } public UUID[] GetAnimationArray() diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 6b38027..64fe7a8 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -45,6 +45,7 @@ using TeleportFlags = OpenSim.Framework.Constants.TeleportFlags; namespace OpenSim.Region.Framework.Scenes { + [Flags] enum ScriptControlled : uint { CONTROL_ZERO = 0, @@ -1220,7 +1221,7 @@ namespace OpenSim.Region.Framework.Scenes { // m_log.DebugFormat( // "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}", -// Scene.RegionInfo.RegionName, remoteClient.Name, agentData.ControlFlags); +// Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags); if (IsChildAgent) { @@ -1320,14 +1321,8 @@ namespace OpenSim.Region.Framework.Scenes } } - lock (scriptedcontrols) - { - if (scriptedcontrols.Count > 0) - { - SendControlToScripts((uint)flags); - flags = RemoveIgnoredControls(flags, IgnoredControls); - } - } + uint flagsForScripts = (uint)flags; + flags = RemoveIgnoredControls(flags, IgnoredControls); if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) HandleAgentSitOnGround(); @@ -1420,7 +1415,7 @@ namespace OpenSim.Region.Framework.Scenes MovementFlag |= (byte)nudgehack; } -// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF); + //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF); MovementFlag += (byte)(uint)DCF; update_movementflag = true; } @@ -1433,7 +1428,7 @@ namespace OpenSim.Region.Framework.Scenes && ((MovementFlag & (byte)nudgehack) == nudgehack)) ) // This or is for Nudge forward { -// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); + //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); MovementFlag -= ((byte)(uint)DCF); update_movementflag = true; @@ -1514,8 +1509,18 @@ namespace OpenSim.Region.Framework.Scenes // } // } -// if (update_movementflag && ParentID == 0) -// Animator.UpdateMovementAnimations(); + if (update_movementflag && ParentID == 0) + Animator.UpdateMovementAnimations(); + + lock (scriptedcontrols) + { + if (scriptedcontrols.Count > 0) + { + // Notify the scripts only after calling UpdateMovementAnimations(), so that if a script + // (e.g., a walking script) checks which animation is active it will be the correct animation. + SendControlToScripts(flagsForScripts); + } + } } m_scene.EventManager.TriggerOnClientMovement(this); -- cgit v1.1 From db566fbb0958bb054b778a7008e407d8a3fa3e9e Mon Sep 17 00:00:00 2001 From: BlueWall Date: Fri, 27 Apr 2012 16:17:46 -0400 Subject: Fix prebuild.xml adding a reference to a dll requires 'path="..."' --- prebuild.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prebuild.xml b/prebuild.xml index 0c90ac0..5003ae7 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1472,7 +1472,7 @@ - + -- cgit v1.1 From e31e7c68c8abfd61fed6dabac5403d8adf42ae87 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 23 Apr 2012 15:27:04 +0300 Subject: Log the full exception when errors occur in BaseHttpServer --- .../Framework/Servers/HttpServer/BaseHttpServer.cs | 38 +++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 0fbf90a..7d31a89 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -356,7 +356,7 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (Exception e) { - m_log.ErrorFormat("[BASE HTTP SERVER]: OnRequest() failed with {0}{1}", e.Message, e.StackTrace); + m_log.Error(String.Format("[BASE HTTP SERVER]: OnRequest() failed: {0}", e.Message), e); } } @@ -551,11 +551,11 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e.Message), e); } catch (IOException e) { - m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.", e.Message), e); } return; @@ -658,15 +658,15 @@ namespace OpenSim.Framework.Servers.HttpServer // // An alternative may be to turn off all response write exceptions on the HttpListener, but let's go // with the minimum first - m_log.WarnFormat("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e); + m_log.Warn(String.Format("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e.Message), e); } catch (IOException e) { - m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}{1}", e.Message, e.StackTrace); + m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0}", e.Message), e); } catch (Exception e) { - m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}{1}", e.Message, e.StackTrace); + m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0}", e.Message), e); SendHTML500(response); } finally @@ -925,11 +925,11 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e.Message), e); } catch (IOException e) { - m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}", e.Message), e); } } return; @@ -962,11 +962,11 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e.Message), e); } catch (IOException e) { - m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}", e.Message), e); } } } @@ -1077,12 +1077,12 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (IOException e) { - m_log.WarnFormat("[BASE HTTP SERVER]: LLSD IOException {0}.", e); + m_log.Warn(String.Format("[BASE HTTP SERVER]: LLSD IOException {0}", e.Message), e); } catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.WarnFormat("[BASE HTTP SERVER]: LLSD issue {0}.\nNOTE: this may be spurious on Linux.", e); + m_log.Warn(String.Format("[BASE HTTP SERVER]: LLSD issue {0}.\nNOTE: this may be spurious on Linux.", e.Message), e); } } } @@ -1334,8 +1334,8 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException f) { // This has to be here to prevent a Linux/Mono crash - m_log.WarnFormat( - "[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", f); + m_log.Warn( + String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", f.Message), f); } } catch(Exception) @@ -1630,11 +1630,11 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e.Message), e); } catch (IOException e) { - m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}", e.Message), e); } } } @@ -1671,7 +1671,7 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e.Message), e); } } } @@ -1707,7 +1707,7 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); + m_log.Warn(String.Format("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e.Message), e); } } } @@ -1786,7 +1786,7 @@ namespace OpenSim.Framework.Servers.HttpServer public void httpServerException(object source, Exception exception) { - m_log.ErrorFormat("[BASE HTTP SERVER]: {0} had an exception {1}", source.ToString(), exception.ToString()); + m_log.Error(String.Format("[BASE HTTP SERVER]: {0} had an exception: {1}", source.ToString(), exception.Message), exception); /* if (HTTPDRunning)// && NotSocketErrors > 5) { -- cgit v1.1 From d25469f66e0f78f42cc6b77b169047e451e11bdb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 27 Apr 2012 23:38:25 +0100 Subject: Add flags information (phantom, physics, etc.) to "show object" and "show part" console commands --- .../Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index 06fea58..8da9139 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -271,6 +271,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands sb.AppendFormat("Description: {0}\n", so.Description); sb.AppendFormat("Location: {0} @ {1}\n", so.AbsolutePosition, so.Scene.RegionInfo.RegionName); sb.AppendFormat("Parts: {0}\n", so.PrimCount); + sb.AppendFormat("Flags: {0}\n", so.RootPart.Flags); return sb; } @@ -283,6 +284,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands sb.AppendFormat("Parent: {0}", sop.IsRoot ? "Is Root\n" : string.Format("{0} {1}\n", sop.ParentGroup.Name, sop.ParentGroup.UUID)); sb.AppendFormat("Link number: {0}\n", sop.LinkNum); + sb.AppendFormat("Flags: {0}\n", sop.Flags); return sb; } -- cgit v1.1 From a90b0e302c110068cec0ee7109e796d2d5fdab4d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 27 Apr 2012 23:46:33 +0100 Subject: Revert "Implement bulk inventory update over CAPS (not recursive by design," This reverts commit 6e7f13a72d4e43f8ca564247e0b56bf5706bbdb1. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 48 +--------------------- 1 file changed, 1 insertion(+), 47 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index ae5cbff..36ef281 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -12296,7 +12296,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ItemData.Add(ItemDataMap); } - llsd.Add("InventoryData", ItemData); + llsd.Add("ItemData", ItemData); eq.Enqueue(BuildEvent("RemoveInventoryItem", llsd), AgentId); @@ -12340,14 +12340,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP llsd), AgentId); } - private byte[] EncodeU32(uint val) - { - byte[] ret = BitConverter.GetBytes(val); - if (BitConverter.IsLittleEndian) - Array.Reverse(ret); - return ret; - } - public void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items) { IEventQueue eq = Scene.RequestModuleInterface(); @@ -12363,7 +12355,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP OSDMap AgentDataMap = new OSDMap(1); AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId)); AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId)); - AgentDataMap.Add("TransactionID", OSD.FromUUID(UUID.Random())); OSDArray AgentData = new OSDArray(1); AgentData.Add(AgentDataMap); @@ -12391,47 +12382,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP foreach (InventoryItemBase item in items) { OSDMap ItemDataMap = new OSDMap(); - - ItemDataMap.Add("ItemID", OSD.FromUUID(item.ID)); - ItemDataMap.Add("FolderID", OSD.FromUUID(item.Folder)); - - ItemDataMap.Add("CreatorID", OSD.FromUUID(item.CreatorIdAsUuid)); - ItemDataMap.Add("OwnerID", OSD.FromUUID(item.Owner)); - ItemDataMap.Add("GroupID", OSD.FromUUID(item.GroupID)); - ItemDataMap.Add("BaseMask", OSD.FromBinary(EncodeU32((uint)item.BasePermissions))); - ItemDataMap.Add("OwnerMask", OSD.FromBinary(EncodeU32((uint)item.CurrentPermissions))); - ItemDataMap.Add("GroupMask", OSD.FromBinary(EncodeU32((uint)item.GroupPermissions))); - ItemDataMap.Add("EveryoneMask", OSD.FromBinary(EncodeU32((uint)item.EveryOnePermissions))); - ItemDataMap.Add("NextOwnerMask", OSD.FromBinary(EncodeU32((uint)item.NextPermissions))); - ItemDataMap.Add("GroupOwned", OSD.FromBoolean(item.GroupOwned)); - ItemDataMap.Add("AssetID", OSD.FromUUID(item.AssetID)); - ItemDataMap.Add("Type", OSD.FromInteger(item.AssetType)); - ItemDataMap.Add("InvType", OSD.FromInteger(item.InvType)); - ItemDataMap.Add("Flags", OSD.FromBinary(EncodeU32((uint)item.Flags))); - ItemDataMap.Add("SaleType", OSD.FromInteger((byte)item.SaleType)); - ItemDataMap.Add("SalePrice", OSD.FromInteger(item.SalePrice)); - ItemDataMap.Add("Name", OSD.FromString(item.Name)); - ItemDataMap.Add("Description", OSD.FromString(item.Description)); - ItemDataMap.Add("CreationDate", OSD.FromInteger(item.CreationDate)); - - ItemDataMap.Add("CRC", OSD.FromBinary(EncodeU32( - Helpers.InventoryCRC(1000, 0, (sbyte)item.InvType, - (sbyte)item.AssetType, item.AssetID, - item.GroupID, 100, - item.Owner, item.CreatorIdAsUuid, - item.ID, item.Folder, - (uint)PermissionMask.All, 1, (uint)PermissionMask.All, (uint)PermissionMask.All, - (uint)PermissionMask.All) - ))); - ItemDataMap.Add("CallbackID", 0); - ItemData.Add(ItemDataMap); } llsd.Add("ItemData", ItemData); - - eq.Enqueue(BuildEvent("BulkUpdateInventory", - llsd), AgentId); } } } -- cgit v1.1 From 737e1771635061c1f7104499d282bcc279823f98 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 27 Apr 2012 23:46:46 +0100 Subject: Revert "Log the full exception when errors occur in BaseHttpServer" This reverts commit e31e7c68c8abfd61fed6dabac5403d8adf42ae87. Applied for patch assessment and accidentally committed too early. --- .../Framework/Servers/HttpServer/BaseHttpServer.cs | 38 +++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 7d31a89..0fbf90a 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -356,7 +356,7 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (Exception e) { - m_log.Error(String.Format("[BASE HTTP SERVER]: OnRequest() failed: {0}", e.Message), e); + m_log.ErrorFormat("[BASE HTTP SERVER]: OnRequest() failed with {0}{1}", e.Message, e.StackTrace); } } @@ -551,11 +551,11 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e.Message), e); + m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); } catch (IOException e) { - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.", e.Message), e); + m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message); } return; @@ -658,15 +658,15 @@ namespace OpenSim.Framework.Servers.HttpServer // // An alternative may be to turn off all response write exceptions on the HttpListener, but let's go // with the minimum first - m_log.Warn(String.Format("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e.Message), e); + m_log.WarnFormat("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e); } catch (IOException e) { - m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0}", e.Message), e); + m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}{1}", e.Message, e.StackTrace); } catch (Exception e) { - m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0}", e.Message), e); + m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}{1}", e.Message, e.StackTrace); SendHTML500(response); } finally @@ -925,11 +925,11 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e.Message), e); + m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); } catch (IOException e) { - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}", e.Message), e); + m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message); } } return; @@ -962,11 +962,11 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e.Message), e); + m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); } catch (IOException e) { - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}", e.Message), e); + m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message); } } } @@ -1077,12 +1077,12 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (IOException e) { - m_log.Warn(String.Format("[BASE HTTP SERVER]: LLSD IOException {0}", e.Message), e); + m_log.WarnFormat("[BASE HTTP SERVER]: LLSD IOException {0}.", e); } catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.Warn(String.Format("[BASE HTTP SERVER]: LLSD issue {0}.\nNOTE: this may be spurious on Linux.", e.Message), e); + m_log.WarnFormat("[BASE HTTP SERVER]: LLSD issue {0}.\nNOTE: this may be spurious on Linux.", e); } } } @@ -1334,8 +1334,8 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException f) { // This has to be here to prevent a Linux/Mono crash - m_log.Warn( - String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", f.Message), f); + m_log.WarnFormat( + "[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", f); } } catch(Exception) @@ -1630,11 +1630,11 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e.Message), e); + m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); } catch (IOException e) { - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}", e.Message), e); + m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message); } } } @@ -1671,7 +1671,7 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e.Message), e); + m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); } } } @@ -1707,7 +1707,7 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.Warn(String.Format("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e.Message), e); + m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); } } } @@ -1786,7 +1786,7 @@ namespace OpenSim.Framework.Servers.HttpServer public void httpServerException(object source, Exception exception) { - m_log.Error(String.Format("[BASE HTTP SERVER]: {0} had an exception: {1}", source.ToString(), exception.Message), exception); + m_log.ErrorFormat("[BASE HTTP SERVER]: {0} had an exception {1}", source.ToString(), exception.ToString()); /* if (HTTPDRunning)// && NotSocketErrors > 5) { -- cgit v1.1 From ab71779221d580410e8b1c07e94f89ca933f9855 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 27 Apr 2012 23:54:45 +0100 Subject: Revert "Revert "Implement bulk inventory update over CAPS (not recursive by design,"" This reverts commit a90b0e302c110068cec0ee7109e796d2d5fdab4d. Sorry, accidentally reverted this completely by mistake, reverting the revert. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 48 +++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 36ef281..ae5cbff 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -12296,7 +12296,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ItemData.Add(ItemDataMap); } - llsd.Add("ItemData", ItemData); + llsd.Add("InventoryData", ItemData); eq.Enqueue(BuildEvent("RemoveInventoryItem", llsd), AgentId); @@ -12340,6 +12340,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP llsd), AgentId); } + private byte[] EncodeU32(uint val) + { + byte[] ret = BitConverter.GetBytes(val); + if (BitConverter.IsLittleEndian) + Array.Reverse(ret); + return ret; + } + public void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items) { IEventQueue eq = Scene.RequestModuleInterface(); @@ -12355,6 +12363,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP OSDMap AgentDataMap = new OSDMap(1); AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId)); AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId)); + AgentDataMap.Add("TransactionID", OSD.FromUUID(UUID.Random())); OSDArray AgentData = new OSDArray(1); AgentData.Add(AgentDataMap); @@ -12382,10 +12391,47 @@ namespace OpenSim.Region.ClientStack.LindenUDP foreach (InventoryItemBase item in items) { OSDMap ItemDataMap = new OSDMap(); + + ItemDataMap.Add("ItemID", OSD.FromUUID(item.ID)); + ItemDataMap.Add("FolderID", OSD.FromUUID(item.Folder)); + + ItemDataMap.Add("CreatorID", OSD.FromUUID(item.CreatorIdAsUuid)); + ItemDataMap.Add("OwnerID", OSD.FromUUID(item.Owner)); + ItemDataMap.Add("GroupID", OSD.FromUUID(item.GroupID)); + ItemDataMap.Add("BaseMask", OSD.FromBinary(EncodeU32((uint)item.BasePermissions))); + ItemDataMap.Add("OwnerMask", OSD.FromBinary(EncodeU32((uint)item.CurrentPermissions))); + ItemDataMap.Add("GroupMask", OSD.FromBinary(EncodeU32((uint)item.GroupPermissions))); + ItemDataMap.Add("EveryoneMask", OSD.FromBinary(EncodeU32((uint)item.EveryOnePermissions))); + ItemDataMap.Add("NextOwnerMask", OSD.FromBinary(EncodeU32((uint)item.NextPermissions))); + ItemDataMap.Add("GroupOwned", OSD.FromBoolean(item.GroupOwned)); + ItemDataMap.Add("AssetID", OSD.FromUUID(item.AssetID)); + ItemDataMap.Add("Type", OSD.FromInteger(item.AssetType)); + ItemDataMap.Add("InvType", OSD.FromInteger(item.InvType)); + ItemDataMap.Add("Flags", OSD.FromBinary(EncodeU32((uint)item.Flags))); + ItemDataMap.Add("SaleType", OSD.FromInteger((byte)item.SaleType)); + ItemDataMap.Add("SalePrice", OSD.FromInteger(item.SalePrice)); + ItemDataMap.Add("Name", OSD.FromString(item.Name)); + ItemDataMap.Add("Description", OSD.FromString(item.Description)); + ItemDataMap.Add("CreationDate", OSD.FromInteger(item.CreationDate)); + + ItemDataMap.Add("CRC", OSD.FromBinary(EncodeU32( + Helpers.InventoryCRC(1000, 0, (sbyte)item.InvType, + (sbyte)item.AssetType, item.AssetID, + item.GroupID, 100, + item.Owner, item.CreatorIdAsUuid, + item.ID, item.Folder, + (uint)PermissionMask.All, 1, (uint)PermissionMask.All, (uint)PermissionMask.All, + (uint)PermissionMask.All) + ))); + ItemDataMap.Add("CallbackID", 0); + ItemData.Add(ItemDataMap); } llsd.Add("ItemData", ItemData); + + eq.Enqueue(BuildEvent("BulkUpdateInventory", + llsd), AgentId); } } } -- cgit v1.1 From 2bad430ed860987f82e9f074b2a467749d9fddc6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 28 Apr 2012 00:08:04 +0100 Subject: Put scene object related console commands into new "Objects" help category rather than "Regions" --- OpenSim/Region/Application/OpenSim.cs | 8 ++++---- .../World/Objects/Commands/ObjectCommandsModule.cs | 22 +++++++++++++--------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 59b6b21..4ec64ee 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -225,7 +225,7 @@ namespace OpenSim /// private void RegisterConsoleCommands() { - m_console.Commands.AddCommand("Regions", false, "force update", + m_console.Commands.AddCommand("Objects", false, "force update", "force update", "Force the update of all objects on clients", HandleForceUpdate); @@ -306,7 +306,7 @@ namespace OpenSim + " If this is not given then the oar is saved to region.oar in the current directory.", SaveOar); - m_console.Commands.AddCommand("Regions", false, "edit scale", + m_console.Commands.AddCommand("Objects", false, "edit scale", "edit scale ", "Change the scale of a named prim", HandleEditScale); @@ -349,7 +349,7 @@ namespace OpenSim "show ratings", "Show rating data", HandleShow); - m_console.Commands.AddCommand("Regions", false, "backup", + m_console.Commands.AddCommand("Objects", false, "backup", "backup", "Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand); @@ -410,7 +410,7 @@ namespace OpenSim "modules unload ", "Unload a module", HandleModules); - m_console.Commands.AddCommand("Regions", false, "kill uuid", + m_console.Commands.AddCommand("Objects", false, "kill uuid", "kill uuid ", "Kill an object by UUID", KillUUID); } diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index 8da9139..5e928f3 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -78,45 +78,49 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands m_scene = scene; m_console = MainConsole.Instance; - m_console.Commands.AddCommand("Regions", false, "delete object owner", + m_console.Commands.AddCommand("Objects", false, "delete object owner", "delete object owner ", "Delete a scene object by owner", HandleDeleteObject); - m_console.Commands.AddCommand("Regions", false, "delete object creator", + + m_console.Commands.AddCommand("Objects", false, "delete object creator", "delete object creator ", "Delete a scene object by creator", HandleDeleteObject); - m_console.Commands.AddCommand("Regions", false, "delete object uuid", + + m_console.Commands.AddCommand("Objects", false, "delete object uuid", "delete object uuid ", "Delete a scene object by uuid", HandleDeleteObject); - m_console.Commands.AddCommand("Regions", false, "delete object name", + + m_console.Commands.AddCommand("Objects", false, "delete object name", "delete object name ", "Delete a scene object by name", HandleDeleteObject); - m_console.Commands.AddCommand("Regions", false, "delete object outside", + + m_console.Commands.AddCommand("Objects", false, "delete object outside", "delete object outside", "Delete all scene objects outside region boundaries", HandleDeleteObject); m_console.Commands.AddCommand( - "Regions", + "Objects", false, "show object uuid", "show object uuid ", "Show details of a scene object with the given UUID", HandleShowObjectByUuid); m_console.Commands.AddCommand( - "Regions", + "Objects", false, "show object name", "show object name ", "Show details of scene objects with the given name", HandleShowObjectByName); m_console.Commands.AddCommand( - "Regions", + "Objects", false, "show part uuid", "show part uuid ", "Show details of a scene object parts with the given UUID", HandleShowPartByUuid); m_console.Commands.AddCommand( - "Regions", + "Objects", false, "show part name", "show part name ", -- cgit v1.1 From 133f05dc41ce3520c0069407106fef5a83b2e96e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 28 Apr 2012 00:29:08 +0100 Subject: Add text about using double quotes to surround console command arguments containing spaces to "help" text. e.g. show object name "My long object name" --- OpenSim/Framework/Console/CommandConsole.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Console/CommandConsole.cs b/OpenSim/Framework/Console/CommandConsole.cs index c5d6b78..87bdacd 100644 --- a/OpenSim/Framework/Console/CommandConsole.cs +++ b/OpenSim/Framework/Console/CommandConsole.cs @@ -79,7 +79,11 @@ namespace OpenSim.Framework.Console public List fn; } - public const string GeneralHelpText = "For more information, type 'help ' where is one of the following categories:"; + public const string GeneralHelpText + = "To enter an argument that contains spaces, surround the argument with double quotes.\nFor example, show object name \"My long object name\"\n"; + + public const string ItemHelpText + = "For more information, type 'help ' where is one of the following:"; /// /// Commands organized by keyword in a tree @@ -108,7 +112,9 @@ namespace OpenSim.Framework.Console // General help if (helpParts.Count == 0) { + help.Add(""); // Will become a newline. help.Add(GeneralHelpText); + help.Add(ItemHelpText); help.AddRange(CollectModulesHelp(tree)); } else @@ -132,7 +138,7 @@ namespace OpenSim.Framework.Console // Check modules first to see if we just need to display a list of those commands if (TryCollectModuleHelp(originalHelpRequest, help)) { - help.Insert(0, GeneralHelpText); + help.Insert(0, ItemHelpText); return help; } -- cgit v1.1 From cd755fe5983b1960f771bf6f6bf3fa15b338182b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 28 Apr 2012 00:31:11 +0100 Subject: Remove mono compiler warning. Adjust message log to error from info --- .../Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 130513d..5d57f70 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -1401,9 +1401,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { response = WebUtil.PostToService(m_groupsServerURI, requestArgs); } - catch (Exception e) + catch (Exception) { - m_log.InfoFormat("[SIMIAN GROUPS CONNECTOR] request failed {0}",CacheKey); + m_log.ErrorFormat("[SIMIAN GROUPS CONNECTOR]: request failed {0}", CacheKey); } // and cache the response -- cgit v1.1 From 838016625174ae2f56194a61d7139d0ed7aed8cc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 28 Apr 2012 00:39:40 +0100 Subject: Comment out debug [ASYNC DELETER] messages for now. --- .../Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index f678d07..834464b 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs @@ -117,7 +117,7 @@ namespace OpenSim.Region.Framework.Scenes private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e) { - m_log.Debug("[ASYNC DELETER]: Starting send to inventory loop"); +// m_log.Debug("[ASYNC DELETER]: Starting send to inventory loop"); // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved // in a culture where decimal points are commas and then reloaded in a culture which just treats them as @@ -147,9 +147,9 @@ namespace OpenSim.Region.Framework.Scenes { x = m_inventoryDeletes.Dequeue(); - m_log.DebugFormat( - "[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.", - left, x.action, x.objectGroups.Count); +// m_log.DebugFormat( +// "[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.", +// left, x.action, x.objectGroups.Count); try { @@ -185,7 +185,7 @@ namespace OpenSim.Region.Framework.Scenes e.StackTrace); } - m_log.Debug("[ASYNC DELETER]: No objects left in inventory send queue."); +// m_log.Debug("[ASYNC DELETER]: No objects left in inventory send queue."); return false; } -- cgit v1.1 From 522eff61383e9a8acfdf34289cd64a8fdc27bb19 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 30 Apr 2012 15:54:35 +0100 Subject: Consistently use using() to make sure we dispose of used MySqlCommands where this is not already being done. --- OpenSim/Data/MySQL/MySQLAssetData.cs | 180 ++++++++--------- OpenSim/Data/MySQL/MySQLAuthenticationData.cs | 165 ++++++++-------- OpenSim/Data/MySQL/MySQLAvatarData.cs | 17 +- OpenSim/Data/MySQL/MySQLFriendsData.cs | 36 ++-- OpenSim/Data/MySQL/MySQLInventoryData.cs | 130 +++++++------ OpenSim/Data/MySQL/MySQLPresenceData.cs | 36 ++-- OpenSim/Data/MySQL/MySQLRegionData.cs | 13 +- OpenSim/Data/MySQL/MySQLSimulationData.cs | 267 +++++++++++++------------- OpenSim/Data/MySQL/MySQLUserAccountData.cs | 33 ++-- 9 files changed, 446 insertions(+), 431 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLAssetData.cs b/OpenSim/Data/MySQL/MySQLAssetData.cs index a743479..73de64b 100644 --- a/OpenSim/Data/MySQL/MySQLAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLAssetData.cs @@ -163,52 +163,51 @@ namespace OpenSim.Data.MySQL { dbcon.Open(); - MySqlCommand cmd = + using (MySqlCommand cmd = new MySqlCommand( "replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" + "VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)", - dbcon); - - string assetName = asset.Name; - if (asset.Name.Length > 64) - { - assetName = asset.Name.Substring(0, 64); - m_log.Warn("[ASSET DB]: Name field truncated from " + asset.Name.Length + " to " + assetName.Length + " characters on add"); - } - - string assetDescription = asset.Description; - if (asset.Description.Length > 64) - { - assetDescription = asset.Description.Substring(0, 64); - m_log.Warn("[ASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on add"); - } - - // need to ensure we dispose - try + dbcon)) { - using (cmd) + string assetName = asset.Name; + if (asset.Name.Length > 64) { - // create unix epoch time - int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); - cmd.Parameters.AddWithValue("?id", asset.ID); - cmd.Parameters.AddWithValue("?name", assetName); - cmd.Parameters.AddWithValue("?description", assetDescription); - cmd.Parameters.AddWithValue("?assetType", asset.Type); - cmd.Parameters.AddWithValue("?local", asset.Local); - cmd.Parameters.AddWithValue("?temporary", asset.Temporary); - cmd.Parameters.AddWithValue("?create_time", now); - cmd.Parameters.AddWithValue("?access_time", now); - cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID); - cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags); - cmd.Parameters.AddWithValue("?data", asset.Data); - cmd.ExecuteNonQuery(); - cmd.Dispose(); + assetName = asset.Name.Substring(0, 64); + m_log.Warn("[ASSET DB]: Name field truncated from " + asset.Name.Length + " to " + assetName.Length + " characters on add"); + } + + string assetDescription = asset.Description; + if (asset.Description.Length > 64) + { + assetDescription = asset.Description.Substring(0, 64); + m_log.Warn("[ASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on add"); + } + + try + { + using (cmd) + { + // create unix epoch time + int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); + cmd.Parameters.AddWithValue("?id", asset.ID); + cmd.Parameters.AddWithValue("?name", assetName); + cmd.Parameters.AddWithValue("?description", assetDescription); + cmd.Parameters.AddWithValue("?assetType", asset.Type); + cmd.Parameters.AddWithValue("?local", asset.Local); + cmd.Parameters.AddWithValue("?temporary", asset.Temporary); + cmd.Parameters.AddWithValue("?create_time", now); + cmd.Parameters.AddWithValue("?access_time", now); + cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID); + cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags); + cmd.Parameters.AddWithValue("?data", asset.Data); + cmd.ExecuteNonQuery(); + } + } + catch (Exception e) + { + m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}", + asset.FullID, asset.Name, e.Message); } - } - catch (Exception e) - { - m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}", - asset.FullID, asset.Name, e.Message); } } } @@ -221,33 +220,31 @@ namespace OpenSim.Data.MySQL using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); - MySqlCommand cmd = - new MySqlCommand("update assets set access_time=?access_time where id=?id", - dbcon); - // need to ensure we dispose - try + using (MySqlCommand cmd + = new MySqlCommand("update assets set access_time=?access_time where id=?id", dbcon)) { - using (cmd) + try { - // create unix epoch time - int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); - cmd.Parameters.AddWithValue("?id", asset.ID); - cmd.Parameters.AddWithValue("?access_time", now); - cmd.ExecuteNonQuery(); - cmd.Dispose(); + using (cmd) + { + // create unix epoch time + int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); + cmd.Parameters.AddWithValue("?id", asset.ID); + cmd.Parameters.AddWithValue("?access_time", now); + cmd.ExecuteNonQuery(); + } + } + catch (Exception e) + { + m_log.ErrorFormat( + "[ASSETS DB]: " + + "MySql failure updating access_time for asset {0} with name {1}" + Environment.NewLine + e.ToString() + + Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name); } - } - catch (Exception e) - { - m_log.ErrorFormat( - "[ASSETS DB]: " + - "MySql failure updating access_time for asset {0} with name {1}" + Environment.NewLine + e.ToString() - + Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name); } } } - } /// @@ -310,35 +307,41 @@ namespace OpenSim.Data.MySQL using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); - MySqlCommand cmd = new MySqlCommand("SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count", dbcon); - cmd.Parameters.AddWithValue("?start", start); - cmd.Parameters.AddWithValue("?count", count); - try + using (MySqlCommand cmd + = new MySqlCommand( + "SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count", + dbcon)) { - using (MySqlDataReader dbReader = cmd.ExecuteReader()) + cmd.Parameters.AddWithValue("?start", start); + cmd.Parameters.AddWithValue("?count", count); + + try { - while (dbReader.Read()) + using (MySqlDataReader dbReader = cmd.ExecuteReader()) { - AssetMetadata metadata = new AssetMetadata(); - metadata.Name = (string)dbReader["name"]; - metadata.Description = (string)dbReader["description"]; - metadata.Type = (sbyte)dbReader["assetType"]; - metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct. - metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]); - metadata.FullID = DBGuid.FromDB(dbReader["id"]); - metadata.CreatorID = dbReader["CreatorID"].ToString(); - - // Current SHA1s are not stored/computed. - metadata.SHA1 = new byte[] { }; - - retList.Add(metadata); + while (dbReader.Read()) + { + AssetMetadata metadata = new AssetMetadata(); + metadata.Name = (string)dbReader["name"]; + metadata.Description = (string)dbReader["description"]; + metadata.Type = (sbyte)dbReader["assetType"]; + metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct. + metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]); + metadata.FullID = DBGuid.FromDB(dbReader["id"]); + metadata.CreatorID = dbReader["CreatorID"].ToString(); + + // Current SHA1s are not stored/computed. + metadata.SHA1 = new byte[] { }; + + retList.Add(metadata); + } } } - } - catch (Exception e) - { - m_log.Error("[ASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString()); + catch (Exception e) + { + m_log.Error("[ASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString()); + } } } } @@ -353,11 +356,12 @@ namespace OpenSim.Data.MySQL using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); - MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon); - cmd.Parameters.AddWithValue("?id", id); - cmd.ExecuteNonQuery(); - cmd.Dispose(); + using (MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon)) + { + cmd.Parameters.AddWithValue("?id", id); + cmd.ExecuteNonQuery(); + } } } @@ -366,4 +370,4 @@ namespace OpenSim.Data.MySQL #endregion } -} +} \ No newline at end of file diff --git a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs index 664ce84..7627497 100644 --- a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs +++ b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs @@ -70,30 +70,34 @@ namespace OpenSim.Data.MySQL using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); - MySqlCommand cmd = new MySqlCommand("select * from `" + m_Realm + "` where UUID = ?principalID", dbcon); - cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); - - IDataReader result = cmd.ExecuteReader(); - if (result.Read()) + using (MySqlCommand cmd + = new MySqlCommand("select * from `" + m_Realm + "` where UUID = ?principalID", dbcon)) { - ret.PrincipalID = principalID; - - CheckColumnNames(result); + cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); - foreach (string s in m_ColumnNames) + IDataReader result = cmd.ExecuteReader(); + + if (result.Read()) { - if (s == "UUID") - continue; - - ret.Data[s] = result[s].ToString(); + ret.PrincipalID = principalID; + + CheckColumnNames(result); + + foreach (string s in m_ColumnNames) + { + if (s == "UUID") + continue; + + ret.Data[s] = result[s].ToString(); + } + + return ret; + } + else + { + return null; } - - return ret; - } - else - { - return null; } } } @@ -119,57 +123,53 @@ namespace OpenSim.Data.MySQL string[] fields = new List(data.Data.Keys).ToArray(); - MySqlCommand cmd = new MySqlCommand(); - - string update = "update `"+m_Realm+"` set "; - bool first = true; - foreach (string field in fields) + using (MySqlCommand cmd = new MySqlCommand()) { - if (!first) - update += ", "; - update += "`" + field + "` = ?"+field; - - first = false; - - cmd.Parameters.AddWithValue("?"+field, data.Data[field]); - } - - update += " where UUID = ?principalID"; - - cmd.CommandText = update; - cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString()); - - if (ExecuteNonQuery(cmd) < 1) - { - string insert = "insert into `" + m_Realm + "` (`UUID`, `" + - String.Join("`, `", fields) + - "`) values (?principalID, ?" + String.Join(", ?", fields) + ")"; - - cmd.CommandText = insert; - + string update = "update `"+m_Realm+"` set "; + bool first = true; + foreach (string field in fields) + { + if (!first) + update += ", "; + update += "`" + field + "` = ?"+field; + + first = false; + + cmd.Parameters.AddWithValue("?"+field, data.Data[field]); + } + + update += " where UUID = ?principalID"; + + cmd.CommandText = update; + cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString()); + if (ExecuteNonQuery(cmd) < 1) { - cmd.Dispose(); - return false; + string insert = "insert into `" + m_Realm + "` (`UUID`, `" + + String.Join("`, `", fields) + + "`) values (?principalID, ?" + String.Join(", ?", fields) + ")"; + + cmd.CommandText = insert; + + if (ExecuteNonQuery(cmd) < 1) + return false; } } - cmd.Dispose(); - return true; } public bool SetDataItem(UUID principalID, string item, string value) { - MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + - "` set `" + item + "` = ?" + item + " where UUID = ?UUID"); - - - cmd.Parameters.AddWithValue("?"+item, value); - cmd.Parameters.AddWithValue("?UUID", principalID.ToString()); - - if (ExecuteNonQuery(cmd) > 0) - return true; + using (MySqlCommand cmd + = new MySqlCommand("update `" + m_Realm + "` set `" + item + "` = ?" + item + " where UUID = ?UUID")) + { + cmd.Parameters.AddWithValue("?"+item, value); + cmd.Parameters.AddWithValue("?UUID", principalID.ToString()); + + if (ExecuteNonQuery(cmd) > 0) + return true; + } return false; } @@ -179,18 +179,18 @@ namespace OpenSim.Data.MySQL if (System.Environment.TickCount - m_LastExpire > 30000) DoExpire(); - MySqlCommand cmd = new MySqlCommand("insert into tokens (UUID, token, validity) values (?principalID, ?token, date_add(now(), interval ?lifetime minute))"); - cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); - cmd.Parameters.AddWithValue("?token", token); - cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString()); - - if (ExecuteNonQuery(cmd) > 0) + using (MySqlCommand cmd + = new MySqlCommand( + "insert into tokens (UUID, token, validity) values (?principalID, ?token, date_add(now(), interval ?lifetime minute))")) { - cmd.Dispose(); - return true; + cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); + cmd.Parameters.AddWithValue("?token", token); + cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString()); + + if (ExecuteNonQuery(cmd) > 0) + return true; } - cmd.Dispose(); return false; } @@ -199,30 +199,29 @@ namespace OpenSim.Data.MySQL if (System.Environment.TickCount - m_LastExpire > 30000) DoExpire(); - MySqlCommand cmd = new MySqlCommand("update tokens set validity = date_add(now(), interval ?lifetime minute) where UUID = ?principalID and token = ?token and validity > now()"); - cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); - cmd.Parameters.AddWithValue("?token", token); - cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString()); - - if (ExecuteNonQuery(cmd) > 0) + using (MySqlCommand cmd + = new MySqlCommand( + "update tokens set validity = date_add(now(), interval ?lifetime minute) where UUID = ?principalID and token = ?token and validity > now()")) { - cmd.Dispose(); - return true; - } + cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); + cmd.Parameters.AddWithValue("?token", token); + cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString()); - cmd.Dispose(); + if (ExecuteNonQuery(cmd) > 0) + return true; + } return false; } private void DoExpire() { - MySqlCommand cmd = new MySqlCommand("delete from tokens where validity < now()"); - ExecuteNonQuery(cmd); - - cmd.Dispose(); + using (MySqlCommand cmd = new MySqlCommand("delete from tokens where validity < now()")) + { + ExecuteNonQuery(cmd); + } m_LastExpire = System.Environment.TickCount; } } -} +} \ No newline at end of file diff --git a/OpenSim/Data/MySQL/MySQLAvatarData.cs b/OpenSim/Data/MySQL/MySQLAvatarData.cs index 8c841ab..6a2f5d8 100644 --- a/OpenSim/Data/MySQL/MySQLAvatarData.cs +++ b/OpenSim/Data/MySQL/MySQLAvatarData.cs @@ -52,14 +52,15 @@ namespace OpenSim.Data.MySQL public bool Delete(UUID principalID, string name) { - MySqlCommand cmd = new MySqlCommand(); - - cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = ?PrincipalID and `Name` = ?Name", m_Realm); - cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); - cmd.Parameters.AddWithValue("?Name", name); - - if (ExecuteNonQuery(cmd) > 0) - return true; + using (MySqlCommand cmd = new MySqlCommand()) + { + cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = ?PrincipalID and `Name` = ?Name", m_Realm); + cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); + cmd.Parameters.AddWithValue("?Name", name); + + if (ExecuteNonQuery(cmd) > 0) + return true; + } return false; } diff --git a/OpenSim/Data/MySQL/MySQLFriendsData.cs b/OpenSim/Data/MySQL/MySQLFriendsData.cs index 130ba5e..3cd6b8f 100644 --- a/OpenSim/Data/MySQL/MySQLFriendsData.cs +++ b/OpenSim/Data/MySQL/MySQLFriendsData.cs @@ -49,34 +49,38 @@ namespace OpenSim.Data.MySQL public bool Delete(string principalID, string friend) { - MySqlCommand cmd = new MySqlCommand(); + using (MySqlCommand cmd = new MySqlCommand()) + { + cmd.CommandText = String.Format("delete from {0} where PrincipalID = ?PrincipalID and Friend = ?Friend", m_Realm); + cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); + cmd.Parameters.AddWithValue("?Friend", friend); - cmd.CommandText = String.Format("delete from {0} where PrincipalID = ?PrincipalID and Friend = ?Friend", m_Realm); - cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); - cmd.Parameters.AddWithValue("?Friend", friend); - - ExecuteNonQuery(cmd); + ExecuteNonQuery(cmd); + } return true; } public FriendsData[] GetFriends(UUID principalID) { - MySqlCommand cmd = new MySqlCommand(); - - cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = ?PrincipalID", m_Realm); - cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); + using (MySqlCommand cmd = new MySqlCommand()) + { + cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = ?PrincipalID", m_Realm); + cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); - return DoQuery(cmd); + return DoQuery(cmd); + } } public FriendsData[] GetFriends(string principalID) { - MySqlCommand cmd = new MySqlCommand(); + using (MySqlCommand cmd = new MySqlCommand()) + { + cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID LIKE ?PrincipalID", m_Realm); + cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString() + '%'); - cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID LIKE ?PrincipalID", m_Realm); - cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString() + '%'); - return DoQuery(cmd); + return DoQuery(cmd); + } } } -} +} \ No newline at end of file diff --git a/OpenSim/Data/MySQL/MySQLInventoryData.cs b/OpenSim/Data/MySQL/MySQLInventoryData.cs index 1a634e5..e9b10f3 100644 --- a/OpenSim/Data/MySQL/MySQLInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLInventoryData.cs @@ -467,43 +467,43 @@ namespace OpenSim.Data.MySQL { dbcon.Open(); - MySqlCommand result = new MySqlCommand(sql, dbcon); - result.Parameters.AddWithValue("?inventoryID", item.ID.ToString()); - result.Parameters.AddWithValue("?assetID", item.AssetID.ToString()); - result.Parameters.AddWithValue("?assetType", item.AssetType.ToString()); - result.Parameters.AddWithValue("?parentFolderID", item.Folder.ToString()); - result.Parameters.AddWithValue("?avatarID", item.Owner.ToString()); - result.Parameters.AddWithValue("?inventoryName", itemName); - result.Parameters.AddWithValue("?inventoryDescription", itemDesc); - result.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions.ToString()); - result.Parameters.AddWithValue("?inventoryCurrentPermissions", - item.CurrentPermissions.ToString()); - result.Parameters.AddWithValue("?invType", item.InvType); - result.Parameters.AddWithValue("?creatorID", item.CreatorId); - result.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions); - result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions); - result.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions); - result.Parameters.AddWithValue("?salePrice", item.SalePrice); - result.Parameters.AddWithValue("?saleType", unchecked((sbyte)item.SaleType)); - result.Parameters.AddWithValue("?creationDate", item.CreationDate); - result.Parameters.AddWithValue("?groupID", item.GroupID); - result.Parameters.AddWithValue("?groupOwned", item.GroupOwned); - result.Parameters.AddWithValue("?flags", item.Flags); - - lock (m_dbLock) + using (MySqlCommand result = new MySqlCommand(sql, dbcon)) { - result.ExecuteNonQuery(); + result.Parameters.AddWithValue("?inventoryID", item.ID.ToString()); + result.Parameters.AddWithValue("?assetID", item.AssetID.ToString()); + result.Parameters.AddWithValue("?assetType", item.AssetType.ToString()); + result.Parameters.AddWithValue("?parentFolderID", item.Folder.ToString()); + result.Parameters.AddWithValue("?avatarID", item.Owner.ToString()); + result.Parameters.AddWithValue("?inventoryName", itemName); + result.Parameters.AddWithValue("?inventoryDescription", itemDesc); + result.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions.ToString()); + result.Parameters.AddWithValue("?inventoryCurrentPermissions", + item.CurrentPermissions.ToString()); + result.Parameters.AddWithValue("?invType", item.InvType); + result.Parameters.AddWithValue("?creatorID", item.CreatorId); + result.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions); + result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions); + result.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions); + result.Parameters.AddWithValue("?salePrice", item.SalePrice); + result.Parameters.AddWithValue("?saleType", unchecked((sbyte)item.SaleType)); + result.Parameters.AddWithValue("?creationDate", item.CreationDate); + result.Parameters.AddWithValue("?groupID", item.GroupID); + result.Parameters.AddWithValue("?groupOwned", item.GroupOwned); + result.Parameters.AddWithValue("?flags", item.Flags); + + lock (m_dbLock) + result.ExecuteNonQuery(); + + result.Dispose(); } - result.Dispose(); - - result = new MySqlCommand("update inventoryfolders set version=version+1 where folderID = ?folderID", dbcon); - result.Parameters.AddWithValue("?folderID", item.Folder.ToString()); - lock (m_dbLock) + using (MySqlCommand result = new MySqlCommand("update inventoryfolders set version=version+1 where folderID = ?folderID", dbcon)) { - result.ExecuteNonQuery(); + result.Parameters.AddWithValue("?folderID", item.Folder.ToString()); + + lock (m_dbLock) + result.ExecuteNonQuery(); } - result.Dispose(); } } catch (MySqlException e) @@ -533,12 +533,12 @@ namespace OpenSim.Data.MySQL { dbcon.Open(); - MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", dbcon); - cmd.Parameters.AddWithValue("?uuid", itemID.ToString()); - - lock (m_dbLock) + using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", dbcon)) { - cmd.ExecuteNonQuery(); + cmd.Parameters.AddWithValue("?uuid", itemID.ToString()); + + lock (m_dbLock) + cmd.ExecuteNonQuery(); } } } @@ -579,24 +579,26 @@ namespace OpenSim.Data.MySQL { dbcon.Open(); - MySqlCommand cmd = new MySqlCommand(sql, dbcon); - cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString()); - cmd.Parameters.AddWithValue("?agentID", folder.Owner.ToString()); - cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString()); - cmd.Parameters.AddWithValue("?folderName", folderName); - cmd.Parameters.AddWithValue("?type", folder.Type); - cmd.Parameters.AddWithValue("?version", folder.Version); - - try + using (MySqlCommand cmd = new MySqlCommand(sql, dbcon)) { - lock (m_dbLock) + cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString()); + cmd.Parameters.AddWithValue("?agentID", folder.Owner.ToString()); + cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString()); + cmd.Parameters.AddWithValue("?folderName", folderName); + cmd.Parameters.AddWithValue("?type", folder.Type); + cmd.Parameters.AddWithValue("?version", folder.Version); + + try { - cmd.ExecuteNonQuery(); + lock (m_dbLock) + { + cmd.ExecuteNonQuery(); + } + } + catch (Exception e) + { + m_log.Error(e.ToString()); } - } - catch (Exception e) - { - m_log.Error(e.ToString()); } } } @@ -624,20 +626,22 @@ namespace OpenSim.Data.MySQL { dbcon.Open(); - MySqlCommand cmd = new MySqlCommand(sql, dbcon); - cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString()); - cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString()); - - try + using (MySqlCommand cmd = new MySqlCommand(sql, dbcon)) { - lock (m_dbLock) + cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString()); + cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString()); + + try { - cmd.ExecuteNonQuery(); + lock (m_dbLock) + { + cmd.ExecuteNonQuery(); + } + } + catch (Exception e) + { + m_log.Error(e.ToString()); } - } - catch (Exception e) - { - m_log.Error(e.ToString()); } } } diff --git a/OpenSim/Data/MySQL/MySQLPresenceData.cs b/OpenSim/Data/MySQL/MySQLPresenceData.cs index fc625f0..7808060 100644 --- a/OpenSim/Data/MySQL/MySQLPresenceData.cs +++ b/OpenSim/Data/MySQL/MySQLPresenceData.cs @@ -63,13 +63,14 @@ namespace OpenSim.Data.MySQL public void LogoutRegionAgents(UUID regionID) { - MySqlCommand cmd = new MySqlCommand(); - - cmd.CommandText = String.Format("delete from {0} where `RegionID`=?RegionID", m_Realm); - - cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); - - ExecuteNonQuery(cmd); + using (MySqlCommand cmd = new MySqlCommand()) + { + cmd.CommandText = String.Format("delete from {0} where `RegionID`=?RegionID", m_Realm); + + cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); + + ExecuteNonQuery(cmd); + } } public bool ReportAgent(UUID sessionID, UUID regionID) @@ -81,17 +82,18 @@ namespace OpenSim.Data.MySQL if (regionID == UUID.Zero) return false; - MySqlCommand cmd = new MySqlCommand(); - - cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, LastSeen=NOW() where `SessionID`=?SessionID", m_Realm); - - cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString()); - cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); - - if (ExecuteNonQuery(cmd) == 0) - return false; + using (MySqlCommand cmd = new MySqlCommand()) + { + cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, LastSeen=NOW() where `SessionID`=?SessionID", m_Realm); + + cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString()); + cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); + + if (ExecuteNonQuery(cmd) == 0) + return false; + } return true; } } -} +} \ No newline at end of file diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index d1f1932..0614879 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -329,11 +329,12 @@ namespace OpenSim.Data.MySQL if (scopeID != UUID.Zero) command += " and ScopeID = ?scopeID"; - MySqlCommand cmd = new MySqlCommand(command); - - cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); - - return RunCommand(cmd); + using (MySqlCommand cmd = new MySqlCommand(command)) + { + cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); + + return RunCommand(cmd); + } } } -} +} \ No newline at end of file diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 381a514..b36ff5a 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -129,114 +129,114 @@ namespace OpenSim.Data.MySQL using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); - MySqlCommand cmd = dbcon.CreateCommand(); - foreach (SceneObjectPart prim in obj.Parts) + using (MySqlCommand cmd = dbcon.CreateCommand()) { - cmd.Parameters.Clear(); - - cmd.CommandText = "replace into prims (" + - "UUID, CreationDate, " + - "Name, Text, Description, " + - "SitName, TouchName, ObjectFlags, " + - "OwnerMask, NextOwnerMask, GroupMask, " + - "EveryoneMask, BaseMask, PositionX, " + - "PositionY, PositionZ, GroupPositionX, " + - "GroupPositionY, GroupPositionZ, VelocityX, " + - "VelocityY, VelocityZ, AngularVelocityX, " + - "AngularVelocityY, AngularVelocityZ, " + - "AccelerationX, AccelerationY, " + - "AccelerationZ, RotationX, " + - "RotationY, RotationZ, " + - "RotationW, SitTargetOffsetX, " + - "SitTargetOffsetY, SitTargetOffsetZ, " + - "SitTargetOrientW, SitTargetOrientX, " + - "SitTargetOrientY, SitTargetOrientZ, " + - "RegionUUID, CreatorID, " + - "OwnerID, GroupID, " + - "LastOwnerID, SceneGroupID, " + - "PayPrice, PayButton1, " + - "PayButton2, PayButton3, " + - "PayButton4, LoopedSound, " + - "LoopedSoundGain, TextureAnimation, " + - "OmegaX, OmegaY, OmegaZ, " + - "CameraEyeOffsetX, CameraEyeOffsetY, " + - "CameraEyeOffsetZ, CameraAtOffsetX, " + - "CameraAtOffsetY, CameraAtOffsetZ, " + - "ForceMouselook, ScriptAccessPin, " + - "AllowedDrop, DieAtEdge, " + - "SalePrice, SaleType, " + - "ColorR, ColorG, ColorB, ColorA, " + - "ParticleSystem, ClickAction, Material, " + - "CollisionSound, CollisionSoundVolume, " + - "PassTouches, " + - "LinkNumber, MediaURL) values (" + "?UUID, " + - "?CreationDate, ?Name, ?Text, " + - "?Description, ?SitName, ?TouchName, " + - "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " + - "?GroupMask, ?EveryoneMask, ?BaseMask, " + - "?PositionX, ?PositionY, ?PositionZ, " + - "?GroupPositionX, ?GroupPositionY, " + - "?GroupPositionZ, ?VelocityX, " + - "?VelocityY, ?VelocityZ, ?AngularVelocityX, " + - "?AngularVelocityY, ?AngularVelocityZ, " + - "?AccelerationX, ?AccelerationY, " + - "?AccelerationZ, ?RotationX, " + - "?RotationY, ?RotationZ, " + - "?RotationW, ?SitTargetOffsetX, " + - "?SitTargetOffsetY, ?SitTargetOffsetZ, " + - "?SitTargetOrientW, ?SitTargetOrientX, " + - "?SitTargetOrientY, ?SitTargetOrientZ, " + - "?RegionUUID, ?CreatorID, ?OwnerID, " + - "?GroupID, ?LastOwnerID, ?SceneGroupID, " + - "?PayPrice, ?PayButton1, ?PayButton2, " + - "?PayButton3, ?PayButton4, ?LoopedSound, " + - "?LoopedSoundGain, ?TextureAnimation, " + - "?OmegaX, ?OmegaY, ?OmegaZ, " + - "?CameraEyeOffsetX, ?CameraEyeOffsetY, " + - "?CameraEyeOffsetZ, ?CameraAtOffsetX, " + - "?CameraAtOffsetY, ?CameraAtOffsetZ, " + - "?ForceMouselook, ?ScriptAccessPin, " + - "?AllowedDrop, ?DieAtEdge, ?SalePrice, " + - "?SaleType, ?ColorR, ?ColorG, " + - "?ColorB, ?ColorA, ?ParticleSystem, " + - "?ClickAction, ?Material, ?CollisionSound, " + - "?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)"; - - FillPrimCommand(cmd, prim, obj.UUID, regionUUID); - - ExecuteNonQuery(cmd); - - cmd.Parameters.Clear(); - - cmd.CommandText = "replace into primshapes (" + - "UUID, Shape, ScaleX, ScaleY, " + - "ScaleZ, PCode, PathBegin, PathEnd, " + - "PathScaleX, PathScaleY, PathShearX, " + - "PathShearY, PathSkew, PathCurve, " + - "PathRadiusOffset, PathRevolutions, " + - "PathTaperX, PathTaperY, PathTwist, " + - "PathTwistBegin, ProfileBegin, ProfileEnd, " + - "ProfileCurve, ProfileHollow, Texture, " + - "ExtraParams, State, Media) values (?UUID, " + - "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " + - "?PCode, ?PathBegin, ?PathEnd, " + - "?PathScaleX, ?PathScaleY, " + - "?PathShearX, ?PathShearY, " + - "?PathSkew, ?PathCurve, ?PathRadiusOffset, " + - "?PathRevolutions, ?PathTaperX, " + - "?PathTaperY, ?PathTwist, " + - "?PathTwistBegin, ?ProfileBegin, " + - "?ProfileEnd, ?ProfileCurve, " + - "?ProfileHollow, ?Texture, ?ExtraParams, " + - "?State, ?Media)"; - - FillShapeCommand(cmd, prim); - - ExecuteNonQuery(cmd); + foreach (SceneObjectPart prim in obj.Parts) + { + cmd.Parameters.Clear(); + + cmd.CommandText = "replace into prims (" + + "UUID, CreationDate, " + + "Name, Text, Description, " + + "SitName, TouchName, ObjectFlags, " + + "OwnerMask, NextOwnerMask, GroupMask, " + + "EveryoneMask, BaseMask, PositionX, " + + "PositionY, PositionZ, GroupPositionX, " + + "GroupPositionY, GroupPositionZ, VelocityX, " + + "VelocityY, VelocityZ, AngularVelocityX, " + + "AngularVelocityY, AngularVelocityZ, " + + "AccelerationX, AccelerationY, " + + "AccelerationZ, RotationX, " + + "RotationY, RotationZ, " + + "RotationW, SitTargetOffsetX, " + + "SitTargetOffsetY, SitTargetOffsetZ, " + + "SitTargetOrientW, SitTargetOrientX, " + + "SitTargetOrientY, SitTargetOrientZ, " + + "RegionUUID, CreatorID, " + + "OwnerID, GroupID, " + + "LastOwnerID, SceneGroupID, " + + "PayPrice, PayButton1, " + + "PayButton2, PayButton3, " + + "PayButton4, LoopedSound, " + + "LoopedSoundGain, TextureAnimation, " + + "OmegaX, OmegaY, OmegaZ, " + + "CameraEyeOffsetX, CameraEyeOffsetY, " + + "CameraEyeOffsetZ, CameraAtOffsetX, " + + "CameraAtOffsetY, CameraAtOffsetZ, " + + "ForceMouselook, ScriptAccessPin, " + + "AllowedDrop, DieAtEdge, " + + "SalePrice, SaleType, " + + "ColorR, ColorG, ColorB, ColorA, " + + "ParticleSystem, ClickAction, Material, " + + "CollisionSound, CollisionSoundVolume, " + + "PassTouches, " + + "LinkNumber, MediaURL) values (" + "?UUID, " + + "?CreationDate, ?Name, ?Text, " + + "?Description, ?SitName, ?TouchName, " + + "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " + + "?GroupMask, ?EveryoneMask, ?BaseMask, " + + "?PositionX, ?PositionY, ?PositionZ, " + + "?GroupPositionX, ?GroupPositionY, " + + "?GroupPositionZ, ?VelocityX, " + + "?VelocityY, ?VelocityZ, ?AngularVelocityX, " + + "?AngularVelocityY, ?AngularVelocityZ, " + + "?AccelerationX, ?AccelerationY, " + + "?AccelerationZ, ?RotationX, " + + "?RotationY, ?RotationZ, " + + "?RotationW, ?SitTargetOffsetX, " + + "?SitTargetOffsetY, ?SitTargetOffsetZ, " + + "?SitTargetOrientW, ?SitTargetOrientX, " + + "?SitTargetOrientY, ?SitTargetOrientZ, " + + "?RegionUUID, ?CreatorID, ?OwnerID, " + + "?GroupID, ?LastOwnerID, ?SceneGroupID, " + + "?PayPrice, ?PayButton1, ?PayButton2, " + + "?PayButton3, ?PayButton4, ?LoopedSound, " + + "?LoopedSoundGain, ?TextureAnimation, " + + "?OmegaX, ?OmegaY, ?OmegaZ, " + + "?CameraEyeOffsetX, ?CameraEyeOffsetY, " + + "?CameraEyeOffsetZ, ?CameraAtOffsetX, " + + "?CameraAtOffsetY, ?CameraAtOffsetZ, " + + "?ForceMouselook, ?ScriptAccessPin, " + + "?AllowedDrop, ?DieAtEdge, ?SalePrice, " + + "?SaleType, ?ColorR, ?ColorG, " + + "?ColorB, ?ColorA, ?ParticleSystem, " + + "?ClickAction, ?Material, ?CollisionSound, " + + "?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)"; + + FillPrimCommand(cmd, prim, obj.UUID, regionUUID); + + ExecuteNonQuery(cmd); + + cmd.Parameters.Clear(); + + cmd.CommandText = "replace into primshapes (" + + "UUID, Shape, ScaleX, ScaleY, " + + "ScaleZ, PCode, PathBegin, PathEnd, " + + "PathScaleX, PathScaleY, PathShearX, " + + "PathShearY, PathSkew, PathCurve, " + + "PathRadiusOffset, PathRevolutions, " + + "PathTaperX, PathTaperY, PathTwist, " + + "PathTwistBegin, ProfileBegin, ProfileEnd, " + + "ProfileCurve, ProfileHollow, Texture, " + + "ExtraParams, State, Media) values (?UUID, " + + "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " + + "?PCode, ?PathBegin, ?PathEnd, " + + "?PathScaleX, ?PathScaleY, " + + "?PathShearX, ?PathShearY, " + + "?PathSkew, ?PathCurve, ?PathRadiusOffset, " + + "?PathRevolutions, ?PathTaperX, " + + "?PathTaperY, ?PathTwist, " + + "?PathTwistBegin, ?ProfileBegin, " + + "?ProfileEnd, ?ProfileCurve, " + + "?ProfileHollow, ?Texture, ?ExtraParams, " + + "?State, ?Media)"; + + FillShapeCommand(cmd, prim); + + ExecuteNonQuery(cmd); + } } - - cmd.Dispose(); } } } @@ -1804,37 +1804,36 @@ namespace OpenSim.Data.MySQL { dbcon.Open(); - MySqlCommand cmd = dbcon.CreateCommand(); - - if (items.Count == 0) - return; - - cmd.CommandText = "insert into primitems (" + - "invType, assetType, name, " + - "description, creationDate, nextPermissions, " + - "currentPermissions, basePermissions, " + - "everyonePermissions, groupPermissions, " + - "flags, itemID, primID, assetID, " + - "parentFolderID, creatorID, ownerID, " + - "groupID, lastOwnerID) values (?invType, " + - "?assetType, ?name, ?description, " + - "?creationDate, ?nextPermissions, " + - "?currentPermissions, ?basePermissions, " + - "?everyonePermissions, ?groupPermissions, " + - "?flags, ?itemID, ?primID, ?assetID, " + - "?parentFolderID, ?creatorID, ?ownerID, " + - "?groupID, ?lastOwnerID)"; - - foreach (TaskInventoryItem item in items) + using (MySqlCommand cmd = dbcon.CreateCommand()) { - cmd.Parameters.Clear(); - - FillItemCommand(cmd, item); - - ExecuteNonQuery(cmd); + if (items.Count == 0) + return; + + cmd.CommandText = "insert into primitems (" + + "invType, assetType, name, " + + "description, creationDate, nextPermissions, " + + "currentPermissions, basePermissions, " + + "everyonePermissions, groupPermissions, " + + "flags, itemID, primID, assetID, " + + "parentFolderID, creatorID, ownerID, " + + "groupID, lastOwnerID) values (?invType, " + + "?assetType, ?name, ?description, " + + "?creationDate, ?nextPermissions, " + + "?currentPermissions, ?basePermissions, " + + "?everyonePermissions, ?groupPermissions, " + + "?flags, ?itemID, ?primID, ?assetID, " + + "?parentFolderID, ?creatorID, ?ownerID, " + + "?groupID, ?lastOwnerID)"; + + foreach (TaskInventoryItem item in items) + { + cmd.Parameters.Clear(); + + FillItemCommand(cmd, item); + + ExecuteNonQuery(cmd); + } } - - cmd.Dispose(); } } } diff --git a/OpenSim/Data/MySQL/MySQLUserAccountData.cs b/OpenSim/Data/MySQL/MySQLUserAccountData.cs index aa69d68..e964295 100644 --- a/OpenSim/Data/MySQL/MySQLUserAccountData.cs +++ b/OpenSim/Data/MySQL/MySQLUserAccountData.cs @@ -62,23 +62,24 @@ namespace OpenSim.Data.MySQL if (words.Length > 2) return new UserAccountData[0]; - MySqlCommand cmd = new MySqlCommand(); - - if (words.Length == 1) - { - cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search)", m_Realm); - cmd.Parameters.AddWithValue("?search", "%" + words[0] + "%"); - cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString()); - } - else + using (MySqlCommand cmd = new MySqlCommand()) { - cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst or LastName like ?searchLast)", m_Realm); - cmd.Parameters.AddWithValue("?searchFirst", "%" + words[0] + "%"); - cmd.Parameters.AddWithValue("?searchLast", "%" + words[1] + "%"); - cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString()); - } + if (words.Length == 1) + { + cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search)", m_Realm); + cmd.Parameters.AddWithValue("?search", "%" + words[0] + "%"); + cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString()); + } + else + { + cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst or LastName like ?searchLast)", m_Realm); + cmd.Parameters.AddWithValue("?searchFirst", "%" + words[0] + "%"); + cmd.Parameters.AddWithValue("?searchLast", "%" + words[1] + "%"); + cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString()); + } - return DoQuery(cmd); + return DoQuery(cmd); + } } } -} +} \ No newline at end of file -- cgit v1.1 From 4ad45934c67f221fa54e1c7407949b375956eed6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 30 Apr 2012 16:00:31 +0100 Subject: If there are no new prim items to store then don't bother opening the MySqlConnection only to do nothing with it. --- OpenSim/Data/MySQL/MySQLSimulationData.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index b36ff5a..b2a1481 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -1800,15 +1800,15 @@ namespace OpenSim.Data.MySQL { RemoveItems(primID); + if (items.Count == 0) + return; + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); using (MySqlCommand cmd = dbcon.CreateCommand()) { - if (items.Count == 0) - return; - cmd.CommandText = "insert into primitems (" + "invType, assetType, name, " + "description, creationDate, nextPermissions, " + -- cgit v1.1 From fe8e835bfc027696979ff0fb3135e5b2718af9ed Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Sat, 28 Apr 2012 17:42:49 +0300 Subject: Fixed: scripted controls didn't work if the avatar was sitting down This fixes a bug introduced in 6473674bbf6ce006512083902e8ff1796d8c8b22 --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 64fe7a8..3cf7b2a 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1336,6 +1336,7 @@ namespace OpenSim.Region.Framework.Scenes PhysicsActor actor = PhysicsActor; if (actor == null) { + SafeSendControlsToScripts(flagsForScripts); return; } @@ -1512,20 +1513,25 @@ namespace OpenSim.Region.Framework.Scenes if (update_movementflag && ParentID == 0) Animator.UpdateMovementAnimations(); - lock (scriptedcontrols) - { - if (scriptedcontrols.Count > 0) - { - // Notify the scripts only after calling UpdateMovementAnimations(), so that if a script - // (e.g., a walking script) checks which animation is active it will be the correct animation. - SendControlToScripts(flagsForScripts); - } - } + SafeSendControlsToScripts(flagsForScripts); } m_scene.EventManager.TriggerOnClientMovement(this); } + private void SafeSendControlsToScripts(uint flagsForScripts) + { + lock (scriptedcontrols) + { + if (scriptedcontrols.Count > 0) + { + // Notify the scripts only after calling UpdateMovementAnimations(), so that if a script + // (e.g., a walking script) checks which animation is active it will be the correct animation. + SendControlToScripts(flagsForScripts); + } + } + } + /// /// Calculate an update to move the presence to the set target. /// -- cgit v1.1 From d0598c63f38f560ba0daf8ddf71b6218363ac887 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 30 Apr 2012 17:33:08 +0100 Subject: refactor: Simplify by combining SafeSendControlsToScripts() from fe8e835 into SendControlsToScripts() (instead of SendControlToScripts()). --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 148 ++++++++++++----------- 1 file changed, 75 insertions(+), 73 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 3cf7b2a..f1d0926 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1336,7 +1336,7 @@ namespace OpenSim.Region.Framework.Scenes PhysicsActor actor = PhysicsActor; if (actor == null) { - SafeSendControlsToScripts(flagsForScripts); + SendControlsToScripts(flagsForScripts); return; } @@ -1513,25 +1513,12 @@ namespace OpenSim.Region.Framework.Scenes if (update_movementflag && ParentID == 0) Animator.UpdateMovementAnimations(); - SafeSendControlsToScripts(flagsForScripts); + SendControlsToScripts(flagsForScripts); } m_scene.EventManager.TriggerOnClientMovement(this); } - private void SafeSendControlsToScripts(uint flagsForScripts) - { - lock (scriptedcontrols) - { - if (scriptedcontrols.Count > 0) - { - // Notify the scripts only after calling UpdateMovementAnimations(), so that if a script - // (e.g., a walking script) checks which animation is active it will be the correct animation. - SendControlToScripts(flagsForScripts); - } - } - } - /// /// Calculate an update to move the presence to the set target. /// @@ -3687,77 +3674,92 @@ namespace OpenSim.Region.Framework.Scenes } } - internal void SendControlToScripts(uint flags) + private void SendControlsToScripts(uint flags) { - ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; - - if (MouseDown) + // Notify the scripts only after calling UpdateMovementAnimations(), so that if a script + // (e.g., a walking script) checks which animation is active it will be the correct animation. + lock (scriptedcontrols) { - allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0) + if (scriptedcontrols.Count <= 0) + return; + + ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; + + if (MouseDown) { - allflags = ScriptControlled.CONTROL_ZERO; + allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0) + { + allflags = ScriptControlled.CONTROL_ZERO; + MouseDown = true; + } + } + + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) + { + allflags |= ScriptControlled.CONTROL_ML_LBUTTON; MouseDown = true; } - } + + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) + { + allflags |= ScriptControlled.CONTROL_LBUTTON; + MouseDown = true; + } + + // find all activated controls, whether the scripts are interested in them or not + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0) + { + allflags |= ScriptControlled.CONTROL_FWD; + } + + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0) + { + allflags |= ScriptControlled.CONTROL_BACK; + } + + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0) + { + allflags |= ScriptControlled.CONTROL_UP; + } + + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0) + { + allflags |= ScriptControlled.CONTROL_DOWN; + } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) - { - allflags |= ScriptControlled.CONTROL_ML_LBUTTON; - MouseDown = true; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) - { - allflags |= ScriptControlled.CONTROL_LBUTTON; - MouseDown = true; - } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0) + { + allflags |= ScriptControlled.CONTROL_LEFT; + } + + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0) + { + allflags |= ScriptControlled.CONTROL_RIGHT; + } + + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) + { + allflags |= ScriptControlled.CONTROL_ROT_RIGHT; + } + + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0) + { + allflags |= ScriptControlled.CONTROL_ROT_LEFT; + } - // find all activated controls, whether the scripts are interested in them or not - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0) - { - allflags |= ScriptControlled.CONTROL_FWD; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0) - { - allflags |= ScriptControlled.CONTROL_BACK; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0) - { - allflags |= ScriptControlled.CONTROL_UP; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0) - { - allflags |= ScriptControlled.CONTROL_DOWN; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0) - { - allflags |= ScriptControlled.CONTROL_LEFT; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0) - { - allflags |= ScriptControlled.CONTROL_RIGHT; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) - { - allflags |= ScriptControlled.CONTROL_ROT_RIGHT; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0) - { - allflags |= ScriptControlled.CONTROL_ROT_LEFT; - } - // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that - if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands) - { - lock (scriptedcontrols) + // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that + if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands) { foreach (KeyValuePair kvp in scriptedcontrols) { UUID scriptUUID = kvp.Key; ScriptControllers scriptControlData = kvp.Value; - + ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle ScriptControlled localChange = localHeld ^ localLast; // the changed bits + if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO) { // only send if still pressed or just changed @@ -3765,9 +3767,9 @@ namespace OpenSim.Region.Framework.Scenes } } } + + LastCommands = allflags; } - - LastCommands = allflags; } internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored) -- cgit v1.1 From 9c2a73b61ef1e834c77f5d945ebae435b033ca38 Mon Sep 17 00:00:00 2001 From: TBG Renfold Date: Tue, 24 Apr 2012 19:38:37 +0100 Subject: llGenerateKey implementation. Creates a random UUID I.E: UUID.Random().ToString(); Signed-off-by: TBG Renfold --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 7 +++++++ OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | 1 + OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d641958..62b5c0f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1734,6 +1734,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api rgb.y = texcolor.G; rgb.z = texcolor.B; return rgb; + } else { @@ -3192,6 +3193,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return m_host.UUID.ToString(); } + public LSL_Key llGenerateKey() + { + m_host.AddScriptLPS(1); + return UUID.Random().ToString(); + } + public void llSetBuoyancy(double buoyancy) { m_host.AddScriptLPS(1); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 69df392..7a797ac 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -105,6 +105,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Integer llFloor(double f); void llForceMouselook(int mouselook); LSL_Float llFrand(double mag); + LSL_Key llGenerateKey(); LSL_Vector llGetAccel(); LSL_Integer llGetAgentInfo(string id); LSL_String llGetAgentLanguage(string id); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index 3c2f7bd..80fa530 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -369,6 +369,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_LSL_Functions.llFrand(mag); } + public LSL_Key llGenerateKey() + { + return m_LSL_Functions.llGenerateKey(); + } + public LSL_Vector llGetAccel() { return m_LSL_Functions.llGetAccel(); -- cgit v1.1 From cc482d2d5627ead7883f4b529c4221870724ff9c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 30 Apr 2012 17:39:11 +0100 Subject: Add TBG Renfold to contributors --- CONTRIBUTORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index ad95cf7..8a1141f 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -146,6 +146,7 @@ what it is today. * Stefan_Boom / stoehr * Strawberry Fride * Talun +* TBG Renfold * tglion * tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud) * tyre -- cgit v1.1 From b678ea18b238ef1ab816445f48bd1c838f9978fc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 30 Apr 2012 18:44:22 +0100 Subject: Create TestHelpers.EnableLogging() and DisableLogging() to turn logging on and off within tests. This makes *.Tests.dll.config files no longer needed, hence deleted. --- .../Region/Framework/Scenes/Tests/BorderTests.cs | 4 +- .../Framework/Scenes/Tests/SceneGraphTests.cs | 6 +++ .../Scenes/Tests/ScenePresenceTeleportTests.cs | 3 +- OpenSim/Tests/Common/TestHelpers.cs | 46 ++++++++++++++++++++++ ...enSim.Framework.Communications.Tests.dll.config | 33 ---------------- ...penSim.Framework.Serialization.Tests.dll.config | 33 ---------------- bin/OpenSim.Framework.Servers.Tests.dll.config | 33 ---------------- bin/OpenSim.Framework.Tests.dll.config | 33 ---------------- ....Region.ClientStack.LindenCaps.Tests.dll.config | 33 ---------------- ...m.Region.ClientStack.LindenUDP.Tests.dll.config | 33 ---------------- bin/OpenSim.Region.CoreModules.Tests.dll.config | 33 ---------------- bin/OpenSim.Region.Framework.Tests.dll.config | 33 ---------------- ...OpenSim.Region.OptionalModules.Tests.dll.config | 33 ---------------- bin/OpenSim.Region.ScriptEngine.Tests.dll.config | 33 ---------------- bin/OpenSim.Tests.Torture.dll.config | 33 ---------------- 15 files changed, 55 insertions(+), 367 deletions(-) delete mode 100644 bin/OpenSim.Framework.Communications.Tests.dll.config delete mode 100644 bin/OpenSim.Framework.Serialization.Tests.dll.config delete mode 100644 bin/OpenSim.Framework.Servers.Tests.dll.config delete mode 100644 bin/OpenSim.Framework.Tests.dll.config delete mode 100644 bin/OpenSim.Region.ClientStack.LindenCaps.Tests.dll.config delete mode 100644 bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll.config delete mode 100644 bin/OpenSim.Region.CoreModules.Tests.dll.config delete mode 100644 bin/OpenSim.Region.Framework.Tests.dll.config delete mode 100644 bin/OpenSim.Region.OptionalModules.Tests.dll.config delete mode 100644 bin/OpenSim.Region.ScriptEngine.Tests.dll.config delete mode 100644 bin/OpenSim.Tests.Torture.dll.config diff --git a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs index ab6311b..4a21dc9 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Text; using NUnit.Framework; using OpenMetaverse; @@ -68,11 +69,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests Vector3 position = new Vector3(200,200,21); foreach (Border b in testborders) - { Assert.That(!b.TestCross(position)); - } - position = new Vector3(200,280,21); Assert.That(NorthBorder.TestCross(position)); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs index 1c33a5f..d23c965 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs @@ -26,7 +26,9 @@ */ using System; +using System.IO; using System.Reflection; +using System.Text; using NUnit.Framework; using OpenMetaverse; using OpenSim.Framework; @@ -44,6 +46,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests public void TestDuplicateObject() { TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + Scene scene = new SceneHelpers().SetupScene(); UUID ownerId = new UUID("00000000-0000-0000-0000-000000000010"); @@ -82,6 +86,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(dupePart1.PhysActor, Is.Not.Null); Assert.That(dupePart2.PhysActor, Is.Not.Null); */ + +// TestHelpers.DisableLogging(); } } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index 19542ff..c750cc5 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -38,7 +38,8 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; -using System.Threading; +using System.IO; +using System.Text; namespace OpenSim.Region.Framework.Scenes.Tests { diff --git a/OpenSim/Tests/Common/TestHelpers.cs b/OpenSim/Tests/Common/TestHelpers.cs index ced06de..5030d4b 100644 --- a/OpenSim/Tests/Common/TestHelpers.cs +++ b/OpenSim/Tests/Common/TestHelpers.cs @@ -27,6 +27,8 @@ using System; using System.Diagnostics; +using System.IO; +using System.Text; using NUnit.Framework; using OpenMetaverse; @@ -34,6 +36,37 @@ namespace OpenSim.Tests.Common { public class TestHelpers { + private static Stream EnableLoggingConfigStream + = new MemoryStream( + Encoding.UTF8.GetBytes( +@" + + + + + + + + + + + + + + + +")); + + private static Stream DisableLoggingConfigStream + = new MemoryStream( + Encoding.UTF8.GetBytes( + // ""))); + //""))); + //""))); + //""))); + //""))); + "")); + public static bool AssertThisDelegateCausesArgumentException(TestDelegate d) { try @@ -58,6 +91,19 @@ namespace OpenSim.Tests.Common Console.WriteLine("===> In Test Method : {0} <===", stackTrace.GetFrame(1).GetMethod().Name); } + public static void EnableLogging() + { + log4net.Config.XmlConfigurator.Configure(EnableLoggingConfigStream); + } + + /// + /// Disable logging whilst running the tests. + /// + public static void DisableLogging() + { + log4net.Config.XmlConfigurator.Configure(DisableLoggingConfigStream); + } + /// /// Parse tail section into full UUID. /// diff --git a/bin/OpenSim.Framework.Communications.Tests.dll.config b/bin/OpenSim.Framework.Communications.Tests.dll.config deleted file mode 100644 index a3f681d..0000000 --- a/bin/OpenSim.Framework.Communications.Tests.dll.config +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.Framework.Serialization.Tests.dll.config b/bin/OpenSim.Framework.Serialization.Tests.dll.config deleted file mode 100644 index a3f681d..0000000 --- a/bin/OpenSim.Framework.Serialization.Tests.dll.config +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.Framework.Servers.Tests.dll.config b/bin/OpenSim.Framework.Servers.Tests.dll.config deleted file mode 100644 index a3f681d..0000000 --- a/bin/OpenSim.Framework.Servers.Tests.dll.config +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.Framework.Tests.dll.config b/bin/OpenSim.Framework.Tests.dll.config deleted file mode 100644 index a3f681d..0000000 --- a/bin/OpenSim.Framework.Tests.dll.config +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.Region.ClientStack.LindenCaps.Tests.dll.config b/bin/OpenSim.Region.ClientStack.LindenCaps.Tests.dll.config deleted file mode 100644 index a3f681d..0000000 --- a/bin/OpenSim.Region.ClientStack.LindenCaps.Tests.dll.config +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll.config b/bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll.config deleted file mode 100644 index a3f681d..0000000 --- a/bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll.config +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.Region.CoreModules.Tests.dll.config b/bin/OpenSim.Region.CoreModules.Tests.dll.config deleted file mode 100644 index a3f681d..0000000 --- a/bin/OpenSim.Region.CoreModules.Tests.dll.config +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.Region.Framework.Tests.dll.config b/bin/OpenSim.Region.Framework.Tests.dll.config deleted file mode 100644 index a3f681d..0000000 --- a/bin/OpenSim.Region.Framework.Tests.dll.config +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.Region.OptionalModules.Tests.dll.config b/bin/OpenSim.Region.OptionalModules.Tests.dll.config deleted file mode 100644 index a3f681d..0000000 --- a/bin/OpenSim.Region.OptionalModules.Tests.dll.config +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.Region.ScriptEngine.Tests.dll.config b/bin/OpenSim.Region.ScriptEngine.Tests.dll.config deleted file mode 100644 index a3f681d..0000000 --- a/bin/OpenSim.Region.ScriptEngine.Tests.dll.config +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.Tests.Torture.dll.config b/bin/OpenSim.Tests.Torture.dll.config deleted file mode 100644 index a3f681d..0000000 --- a/bin/OpenSim.Tests.Torture.dll.config +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- cgit v1.1 From 37dd174697c0bcc201f8d8e4d7569c2a51f53757 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 1 May 2012 17:52:30 +0100 Subject: refactor: Split most of EntityTransferModule.Teleport() into its same region and different region teleport components. DoTeleport() now retrives IEventQueue itself rather than requiring it to be passed in. --- .../Region/CoreModules/Avatar/Lure/HGLureModule.cs | 10 +- .../EntityTransfer/EntityTransferModule.cs | 266 ++++++++++++--------- .../EntityTransfer/HGEntityTransferModule.cs | 15 +- .../Framework/Interfaces/IEntityTransferModule.cs | 37 ++- 4 files changed, 198 insertions(+), 130 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs index bc5c1ff..92cf9d1 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs @@ -240,13 +240,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure { ScenePresence sp = scene.GetScenePresence(client.AgentId); IEntityTransferModule transferMod = scene.RequestModuleInterface(); - IEventQueue eq = sp.Scene.RequestModuleInterface(); - if (transferMod != null && sp != null && eq != null) - transferMod.DoTeleport(sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags, eq); + + if (transferMod != null && sp != null) + transferMod.DoTeleport( + sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), + Vector3.UnitX, teleportflags); } } } } } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 779fd6b..b547317 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -170,8 +170,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) return; - IEventQueue eq = sp.Scene.RequestModuleInterface(); - // Reset animations; the viewer does that in teleports. sp.Animator.ResetAnimations(); @@ -183,145 +181,183 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { destinationRegionName = sp.Scene.RegionInfo.RegionName; - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", - sp.Name, position, destinationRegionName); + TeleportAgentWithinRegion(sp, position, lookAt, teleportFlags); + } + else // Another region possibly in another simulator + { + GridRegion finalDestination; + TeleportAgentToDifferentRegion( + sp, regionHandle, position, lookAt, teleportFlags, out finalDestination); - // Teleport within the same region - if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) - { - Vector3 emergencyPos = new Vector3(128, 128, 128); + if (finalDestination != null) + destinationRegionName = finalDestination.RegionName; + } + } + catch (Exception e) + { + m_log.ErrorFormat( + "[ENTITY TRANSFER MODULE]: Exception on teleport of {0} from {1}@{2} to {3}@{4}: {5}{6}", + sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName, + e.Message, e.StackTrace); - m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", - position, sp.Name, sp.UUID, emergencyPos); + sp.ControllingClient.SendTeleportFailed("Internal error"); + } + } - position = emergencyPos; - } + /// + /// Teleports the agent within its current region. + /// + /// + /// + /// + /// 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) - { - posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; - } + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", + position, sp.Name, sp.UUID, emergencyPos); - float newPosZ = posZLimit + localAVHeight; - if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) - { - position.Z = newPosZ; - } + position = emergencyPos; + } - sp.ControllingClient.SendTeleportStart(teleportFlags); + // TODO: Get proper AVG Height + float localAVHeight = 1.56f; + float posZLimit = 22; - sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); - sp.Velocity = Vector3.Zero; - sp.Teleport(position); + // TODO: Check other Scene HeightField + if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) + { + posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; + } - foreach (SceneObjectGroup grp in sp.GetAttachments()) - { - sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); - } - } - else // Another region possibly in another simulator - { - uint x = 0, y = 0; - Utils.LongToUInts(regionHandle, out x, out y); - GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); + float newPosZ = posZLimit + localAVHeight; + if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) + { + position.Z = newPosZ; + } - if (reg != null) - { - GridRegion finalDestination = GetFinalDestination(reg); - if (finalDestination == null) - { - m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport {0} {1}", - sp.Name, sp.UUID); + sp.ControllingClient.SendTeleportStart(teleportFlags); - sp.ControllingClient.SendTeleportFailed("Problem at destination"); - return; - } + sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); + sp.Velocity = Vector3.Zero; + sp.Teleport(position); - destinationRegionName = finalDestination.RegionName; + foreach (SceneObjectGroup grp in sp.GetAttachments()) + { + sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); + } + } - uint curX = 0, curY = 0; - Utils.LongToUInts(sp.Scene.RegionInfo.RegionHandle, out curX, out curY); - int curCellX = (int)(curX / Constants.RegionSize); - int curCellY = (int)(curY / Constants.RegionSize); - int destCellX = (int)(finalDestination.RegionLocX / Constants.RegionSize); - int destCellY = (int)(finalDestination.RegionLocY / Constants.RegionSize); + /// + /// Teleports the agent to a different region. + /// + /// + /// /param> + /// + /// + /// + /// + private void TeleportAgentToDifferentRegion( + ScenePresence sp, ulong regionHandle, Vector3 position, + Vector3 lookAt, uint teleportFlags, out GridRegion finalDestination) + { + uint x = 0, y = 0; + Utils.LongToUInts(regionHandle, out x, out y); + GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); + + if (reg != null) + { + finalDestination = GetFinalDestination(reg); + + if (finalDestination == null) + { + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport {0} {1}", + sp.Name, sp.UUID); + + sp.ControllingClient.SendTeleportFailed("Problem at destination"); + return; + } + + uint curX = 0, curY = 0; + Utils.LongToUInts(sp.Scene.RegionInfo.RegionHandle, out curX, out curY); + int curCellX = (int)(curX / Constants.RegionSize); + int curCellY = (int)(curY / Constants.RegionSize); + int destCellX = (int)(finalDestination.RegionLocX / Constants.RegionSize); + int destCellY = (int)(finalDestination.RegionLocY / Constants.RegionSize); // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY); // // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}", // destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI); - // Check that these are not the same coordinates - if (finalDestination.RegionLocX == sp.Scene.RegionInfo.RegionLocX && - finalDestination.RegionLocY == sp.Scene.RegionInfo.RegionLocY) - { - // Can't do. Viewer crashes - sp.ControllingClient.SendTeleportFailed("Space warp! You would crash. Move to a different region and try again."); - return; - } - - if (Math.Abs(curCellX - destCellX) > MaxTransferDistance || Math.Abs(curCellY - destCellY) > MaxTransferDistance) - { - sp.ControllingClient.SendTeleportFailed( - string.Format( - "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", - finalDestination.RegionName, destCellX, destCellY, - sp.Scene.RegionInfo.RegionName, curCellX, curCellY, - MaxTransferDistance)); - - return; - } - - // - // This is it - // - DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags, eq); - // - // - // - } - else - { - // TP to a place that doesn't exist (anymore) - // Inform the viewer about that - sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); - - // and set the map-tile to '(Offline)' - uint regX, regY; - Utils.LongToUInts(regionHandle, out regX, out regY); - - MapBlockData block = new MapBlockData(); - block.X = (ushort)(regX / Constants.RegionSize); - block.Y = (ushort)(regY / Constants.RegionSize); - block.Access = 254; // == not there - - List blocks = new List(); - blocks.Add(block); - sp.ControllingClient.SendMapBlock(blocks, 0); - } + // Check that these are not the same coordinates + if (finalDestination.RegionLocX == sp.Scene.RegionInfo.RegionLocX && + finalDestination.RegionLocY == sp.Scene.RegionInfo.RegionLocY) + { + // Can't do. Viewer crashes + sp.ControllingClient.SendTeleportFailed("Space warp! You would crash. Move to a different region and try again."); + return; + } + + if (Math.Abs(curCellX - destCellX) > MaxTransferDistance || Math.Abs(curCellY - destCellY) > MaxTransferDistance) + { + sp.ControllingClient.SendTeleportFailed( + string.Format( + "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", + finalDestination.RegionName, destCellX, destCellY, + sp.Scene.RegionInfo.RegionName, curCellX, curCellY, + MaxTransferDistance)); + + return; } + + // + // This is it + // + DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags); + // + // + // } - catch (Exception e) + else { - m_log.ErrorFormat( - "[ENTITY TRANSFER MODULE]: Exception on teleport of {0} from {1}@{2} to {3}@{4}: {5}{6}", - sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName, - e.Message, e.StackTrace); - - sp.ControllingClient.SendTeleportFailed("Internal error"); + finalDestination = null; + + // TP to a place that doesn't exist (anymore) + // Inform the viewer about that + sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); + + // and set the map-tile to '(Offline)' + uint regX, regY; + Utils.LongToUInts(regionHandle, out regX, out regY); + + MapBlockData block = new MapBlockData(); + block.X = (ushort)(regX / Constants.RegionSize); + block.Y = (ushort)(regY / Constants.RegionSize); + block.Access = 254; // == not there + + List blocks = new List(); + blocks.Add(block); + sp.ControllingClient.SendMapBlock(blocks, 0); } } - public void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq) + public void DoTeleport( + ScenePresence sp, GridRegion reg, GridRegion finalDestination, + Vector3 position, Vector3 lookAt, uint teleportFlags) { + IEventQueue eq = sp.Scene.RequestModuleInterface(); + if (reg == null || finalDestination == null) { sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 488bbcb..b578bcb 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -242,13 +242,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - IEventQueue eq = sp.Scene.RequestModuleInterface(); GridRegion homeGatekeeper = MakeRegion(aCircuit); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}", aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName); - DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq); + DoTeleport( + sp, homeGatekeeper, finalDestination, + position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome)); } /// @@ -288,17 +289,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId); IEntityTransferModule transferMod = scene.RequestModuleInterface(); - IEventQueue eq = sp.Scene.RequestModuleInterface(); - if (transferMod != null && sp != null && eq != null) - transferMod.DoTeleport(sp, gatekeeper, finalDestination, lm.Position, - Vector3.UnitX, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark), eq); + + if (transferMod != null && sp != null) + transferMod.DoTeleport( + sp, gatekeeper, finalDestination, lm.Position, Vector3.UnitX, + (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); } } // can't find the region: Tell viewer and abort remoteClient.SendTeleportFailed("The teleport destination could not be found."); - } #endregion diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index 07e97d5..18e9e3c 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -37,12 +37,41 @@ namespace OpenSim.Region.Framework.Interfaces { public interface IEntityTransferModule { - void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, - Vector3 lookAt, uint teleportFlags); + /// + /// Teleport an agent within the same or to a different region. + /// + /// + /// + /// The handle of the destination region. If it's the same as the region currently + /// occupied by the agent then the teleport will be within that region. + /// + /// + /// + /// + void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags); - void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, - Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq); + /// + /// Teleport an agent directly to a given region without checking whether the region should be subsituted. + /// + /// + /// Please use Teleport() instead unless you know exactly what you're doing. + /// Do not use for same region teleports. + /// + /// + /// + /// /param> + /// + /// + /// + void DoTeleport( + ScenePresence sp, GridRegion reg, GridRegion finalDestination, + Vector3 position, Vector3 lookAt, uint teleportFlags); + /// + /// Teleports the agent for the given client to their home destination. + /// + /// + /// void TeleportHome(UUID id, IClientAPI client); bool Cross(ScenePresence agent, bool isFlying); -- cgit v1.1 From 5786521103eb6721e86e4abfce742019b960491e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 1 May 2012 18:38:46 +0100 Subject: Move max teleport distance check down into etm.DoTeleport() since this should apply to all teleport calls, not just those through Teleport() --- .../EntityTransfer/EntityTransferModule.cs | 81 +++++++++++----------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index b547317..230706e 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -51,15 +51,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public const int DefaultMaxTransferDistance = 4095; + /// /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer. /// - private int m_MaxTransferDistance = 4095; - public int MaxTransferDistance - { - get { return m_MaxTransferDistance; } - set { m_MaxTransferDistance = value; } - } + public int MaxTransferDistance { get; set; } protected bool m_Enabled = false; protected Scene m_aScene; @@ -102,9 +99,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { IConfig transferConfig = source.Configs["EntityTransfer"]; if (transferConfig != null) - { - MaxTransferDistance = transferConfig.GetInt("max_distance", 4095); - } + MaxTransferDistance = transferConfig.GetInt("max_distance", DefaultMaxTransferDistance); + else + MaxTransferDistance = DefaultMaxTransferDistance; m_agentsInTransit = new List(); m_Enabled = true; @@ -288,18 +285,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - uint curX = 0, curY = 0; - Utils.LongToUInts(sp.Scene.RegionInfo.RegionHandle, out curX, out curY); - int curCellX = (int)(curX / Constants.RegionSize); - int curCellY = (int)(curY / Constants.RegionSize); - int destCellX = (int)(finalDestination.RegionLocX / Constants.RegionSize); - int destCellY = (int)(finalDestination.RegionLocY / Constants.RegionSize); - -// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY); -// -// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}", -// destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI); - // Check that these are not the same coordinates if (finalDestination.RegionLocX == sp.Scene.RegionInfo.RegionLocX && finalDestination.RegionLocY == sp.Scene.RegionInfo.RegionLocY) @@ -309,18 +294,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - if (Math.Abs(curCellX - destCellX) > MaxTransferDistance || Math.Abs(curCellY - destCellY) > MaxTransferDistance) - { - sp.ControllingClient.SendTeleportFailed( - string.Format( - "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", - finalDestination.RegionName, destCellX, destCellY, - sp.Scene.RegionInfo.RegionName, curCellX, curCellY, - MaxTransferDistance)); - - return; - } - // // This is it // @@ -332,7 +305,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer else { finalDestination = null; - + // TP to a place that doesn't exist (anymore) // Inform the viewer about that sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); @@ -352,10 +325,44 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } } + /// + /// Determines whether this instance is within the max transfer distance. + /// + /// + /// + /// + /// true if this instance is within max transfer distance; otherwise, false. + /// + private bool IsWithinMaxTeleportDistance(RegionInfo sourceRegion, GridRegion destRegion) + { +// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY); +// +// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}", +// destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI); + + // Insanely, RegionLoc on RegionInfo is the 256m map co-ord whilst GridRegion.RegionLoc is the raw meters position. + return Math.Abs(sourceRegion.RegionLocX - destRegion.RegionCoordX) <= MaxTransferDistance + && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance; + } + public void DoTeleport( ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags) { + RegionInfo sourceRegion = sp.Scene.RegionInfo; + + if (!IsWithinMaxTeleportDistance(sourceRegion, finalDestination)) + { + sp.ControllingClient.SendTeleportFailed( + string.Format( + "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", + finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY, + sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, + MaxTransferDistance)); + + return; + } + IEventQueue eq = sp.Scene.RequestModuleInterface(); if (reg == null || finalDestination == null) @@ -665,7 +672,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual bool IsOutsideRegion(Scene s, Vector3 pos) { - if (s.TestBorderCross(pos, Cardinals.N)) return true; if (s.TestBorderCross(pos, Cardinals.S)) @@ -806,7 +812,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer neighboury = ba.TriggerRegionY; neighbourx = ba.TriggerRegionX; - Vector3 newposition = pos; newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; @@ -814,7 +819,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); - return true; } @@ -854,8 +858,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize); newpos.Y = enterDistance; } - - } else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) { @@ -882,7 +884,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) { - Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); newpos.Y = enterDistance; -- cgit v1.1 From 9d2e1c67a8969e4769006c7347505b58a7827b3f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 1 May 2012 23:14:12 +0100 Subject: Add regression test for teleporting between neighbouring regions on the same simulator This adds a non-advertised wait_for_callback option in [EntityTransfer]. Default is always true. Teleport tests disable the wait for callback from the destination region in order to run within a single thread. --- .../Linden/UDP/Tests/LLImageManagerTests.cs | 3 +- .../Region/ClientStack/RegionApplicationBase.cs | 2 +- .../EntityTransfer/EntityTransferModule.cs | 30 +++++- .../Tests/InventoryAccessModuleTests.cs | 7 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 4 +- .../Scenes/Tests/ScenePresenceAgentTests.cs | 3 +- .../Scenes/Tests/ScenePresenceTeleportTests.cs | 112 +++++++++++++++++++-- OpenSim/Tests/Common/Helpers/SceneHelpers.cs | 72 ++++++++++++- OpenSim/Tests/Common/Mock/TestClient.cs | 39 +++++-- OpenSim/Tests/Common/TestHelpers.cs | 9 +- 10 files changed, 248 insertions(+), 33 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs index 221f02b..5fcf376 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs @@ -79,7 +79,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests J2KDecoderModule j2kdm = new J2KDecoderModule(); - scene = new SceneHelpers().SetupScene(); + SceneHelpers sceneHelpers = new SceneHelpers(); + scene = sceneHelpers.SetupScene(); SceneHelpers.SetupSceneModules(scene, j2kdm); tc = new TestClient(SceneHelpers.GenerateAgentData(userId), scene); diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs index 6e3a58e..6e78d6d 100644 --- a/OpenSim/Region/ClientStack/RegionApplicationBase.cs +++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs @@ -111,7 +111,7 @@ namespace OpenSim.Region.ClientStack server.Start(); } } - + base.StartupSpecific(); } diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 230706e..35486bb 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -52,12 +52,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public const int DefaultMaxTransferDistance = 4095; + public const bool EnableWaitForCallbackFromTeleportDestDefault = true; + /// /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer. /// public int MaxTransferDistance { get; set; } + /// + /// If true then on a teleport, the source region waits for a callback from the destination region. If + /// a callback fails to arrive within a set time then the user is pulled back into the source region. + /// + public bool EnableWaitForCallbackFromTeleportDest { get; set; } + protected bool m_Enabled = false; protected Scene m_aScene; protected List m_Scenes = new List(); @@ -99,9 +107,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { IConfig transferConfig = source.Configs["EntityTransfer"]; if (transferConfig != null) + { + EnableWaitForCallbackFromTeleportDest + = transferConfig.GetBoolean("wait_for_callback", EnableWaitForCallbackFromTeleportDestDefault); + MaxTransferDistance = transferConfig.GetInt("max_distance", DefaultMaxTransferDistance); + } else + { MaxTransferDistance = DefaultMaxTransferDistance; + } m_agentsInTransit = new List(); m_Enabled = true; @@ -499,6 +514,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } else { + ICapabilitiesModule capModule = sp.Scene.CapsModule; + ulong regionHandle = reg.RegionHandle; + capModule.GetChildSeed(UUID.Zero, regionHandle); agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); } @@ -527,7 +545,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID); + "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", + capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); if (eq != null) { @@ -546,7 +565,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation // that the client contacted the destination before we close things here. - if (!WaitForCallback(sp.UUID)) + if (EnableWaitForCallbackFromTeleportDest && !WaitForCallback(sp.UUID)) { m_log.WarnFormat( "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} failed due to no callback from destination region. Returning avatar to source region.", @@ -1286,7 +1305,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) { - AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); agent.BaseFolder = UUID.Zero; @@ -1311,7 +1329,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer seeds.Add(neighbour.RegionHandle, agent.CapsPath); } else + { agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, neighbour.RegionHandle); + } cagents.Add(agent); } @@ -1926,7 +1946,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer int count = 200; while (m_agentsInTransit.Contains(id) && count-- > 0) { - //m_log.Debug(" >>> Waiting... " + count); +// m_log.Debug(" >>> Waiting... " + count); Thread.Sleep(100); } @@ -1934,6 +1954,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return true; else return false; + + return true; } protected void SetInTransit(UUID id) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs index d6afaa9..21d8bd7 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs @@ -64,8 +64,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); - - m_scene = new SceneHelpers().SetupScene(); + + SceneHelpers sceneHelpers = new SceneHelpers(); + m_scene = sceneHelpers.SetupScene(); SceneHelpers.SetupSceneModules(m_scene, config, m_iam); // Create user @@ -76,7 +77,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests AgentCircuitData acd = new AgentCircuitData(); acd.AgentID = m_userId; - m_tc = new TestClient(acd, m_scene); + m_tc = new TestClient(acd, m_scene); } [Test] diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f1d0926..e5a9a99 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2895,8 +2895,8 @@ namespace OpenSim.Region.Framework.Scenes x = x / Constants.RegionSize; y = y / Constants.RegionSize; - //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); - //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); +// m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); +// m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY)) { byebyeRegions.Add(handle); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index 2e46377..1aa48d7 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs @@ -128,7 +128,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests IConfig config = configSource.AddConfig("Modules"); config.Set("SimulationServices", "LocalSimulationConnectorModule"); - TestScene scene = new SceneHelpers().SetupScene(); + SceneHelpers sceneHelpers = new SceneHelpers(); + TestScene scene = sceneHelpers.SetupScene(); SceneHelpers.SetupSceneModules(scene, configSource, lsc); UUID agentId = TestHelpers.ParseTail(0x01); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index c750cc5..ea4fb66 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -33,8 +33,9 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications; using OpenSim.Framework.Servers; -using OpenSim.Region.CoreModules.Framework.EntityTransfer; using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.CoreModules.Framework; +using OpenSim.Region.CoreModules.Framework.EntityTransfer; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; @@ -49,6 +50,22 @@ namespace OpenSim.Region.Framework.Scenes.Tests [TestFixture] public class ScenePresenceTeleportTests { + [TestFixtureSetUp] + public void FixtureInit() + { + // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. + Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest; + } + + [TestFixtureTearDown] + public void TearDown() + { + // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple + // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression + // tests really shouldn't). + Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; + } + [Test] public void TestSameRegionTeleport() { @@ -96,10 +113,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); - config.AddConfig("Modules"); - // Not strictly necessary since FriendsModule assumes it is the default (!) - config.Configs["Modules"].Set("EntityTransferModule", etm.Name); - config.Configs["Modules"].Set("SimulationServices", lscm.Name); + IConfig modulesConfig = config.AddConfig("Modules"); + modulesConfig.Set("EntityTransferModule", etm.Name); + modulesConfig.Set("SimulationServices", lscm.Name); + IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); + + // In order to run a single threaded regression test we do not want the entity transfer module waiting + // for a callback from the destination scene before removing its avatar data. + entityTransferConfig.Set("wait_for_callback", false); SceneHelpers sh = new SceneHelpers(); TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); @@ -110,12 +131,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); - ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId); + ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager); sp.AbsolutePosition = new Vector3(30, 31, 32); // XXX: A very nasty hack to tell the client about the destination scene without having to crank the whole // UDP stack (?) - ((TestClient)sp.ControllingClient).TeleportTargetScene = sceneB; +// ((TestClient)sp.ControllingClient).TeleportTargetScene = sceneB; sceneA.RequestTeleportLocation( sp.ControllingClient, @@ -124,6 +145,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests teleportLookAt, (uint)TeleportFlags.ViaLocation); + ((TestClient)sp.ControllingClient).CompleteTeleportClientSide(); + Assert.That(sceneA.GetScenePresence(userId), Is.Null); ScenePresence sceneBSp = sceneB.GetScenePresence(userId); @@ -137,5 +160,80 @@ namespace OpenSim.Region.Framework.Scenes.Tests // position instead). // Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); } + + [Test] + public void TestSameSimulatorNeighbouringRegionsTeleport() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID userId = TestHelpers.ParseTail(0x1); + + EntityTransferModule etm = new EntityTransferModule(); + LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); + + IConfigSource config = new IniConfigSource(); + IConfig modulesConfig = config.AddConfig("Modules"); + modulesConfig.Set("EntityTransferModule", etm.Name); + modulesConfig.Set("SimulationServices", lscm.Name); + IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); + + // In order to run a single threaded regression test we do not want the entity transfer module waiting + // for a callback from the destination scene before removing its avatar data. + entityTransferConfig.Set("wait_for_callback", false); + + SceneHelpers sh = new SceneHelpers(); + TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); + TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000); + + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); + SceneHelpers.SetupSceneModules(sceneA, new CapabilitiesModule()); + SceneHelpers.SetupSceneModules(sceneB, new CapabilitiesModule()); + + Vector3 teleportPosition = new Vector3(10, 11, 12); + Vector3 teleportLookAt = new Vector3(20, 21, 22); + + ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager); + originalSp.AbsolutePosition = new Vector3(30, 31, 32); + + ScenePresence beforeSceneASp = sceneA.GetScenePresence(userId); + Assert.That(beforeSceneASp, Is.Not.Null); + Assert.That(beforeSceneASp.IsChildAgent, Is.False); + + ScenePresence beforeSceneBSp = sceneB.GetScenePresence(userId); + Assert.That(beforeSceneBSp, Is.Not.Null); + Assert.That(beforeSceneBSp.IsChildAgent, Is.True); + + // XXX: A very nasty hack to tell the client about the destination scene without having to crank the whole + // UDP stack (?) +// ((TestClient)beforeSceneASp.ControllingClient).TeleportTargetScene = sceneB; + + sceneA.RequestTeleportLocation( + beforeSceneASp.ControllingClient, + sceneB.RegionInfo.RegionHandle, + teleportPosition, + teleportLookAt, + (uint)TeleportFlags.ViaLocation); + + ((TestClient)beforeSceneASp.ControllingClient).CompleteTeleportClientSide(); + + ScenePresence afterSceneASp = sceneA.GetScenePresence(userId); + Assert.That(afterSceneASp, Is.Not.Null); + Assert.That(afterSceneASp.IsChildAgent, Is.True); + + ScenePresence afterSceneBSp = sceneB.GetScenePresence(userId); + Assert.That(afterSceneBSp, Is.Not.Null); + Assert.That(afterSceneBSp.IsChildAgent, Is.False); + Assert.That(afterSceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName)); + Assert.That(afterSceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition)); + + // TODO: Add assertions to check correct circuit details in both scenes. + + // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera + // position instead). +// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); + +// TestHelpers.DisableLogging(); + } } } \ No newline at end of file diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index 8e54707..dc24418 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs @@ -58,6 +58,11 @@ namespace OpenSim.Tests.Common /// public class SceneHelpers { + /// + /// We need a scene manager so that test clients can retrieve a scene when performing teleport tests. + /// + public SceneManager SceneManager { get; private set; } + private AgentCircuitManager m_acm = new AgentCircuitManager(); private ISimulationDataService m_simDataService = OpenSim.Server.Base.ServerUtils.LoadPlugin("OpenSim.Tests.Common.dll", null); @@ -76,6 +81,8 @@ namespace OpenSim.Tests.Common public SceneHelpers(CoreAssetCache cache) { + SceneManager = new SceneManager(); + m_assetService = StartAssetService(cache); m_authenticationService = StartAuthenticationService(); m_inventoryService = StartInventoryService(); @@ -186,6 +193,8 @@ namespace OpenSim.Tests.Common testScene.LoginsDisabled = false; testScene.RegisterRegionWithGrid(); + SceneManager.Add(testScene); + return testScene; } @@ -350,6 +359,7 @@ namespace OpenSim.Tests.Common List newModules = new List(); foreach (object module in modules) { +// Console.WriteLine("MODULE RAW {0}", module); if (module is IRegionModule) { IRegionModule m = (IRegionModule)module; @@ -367,6 +377,7 @@ namespace OpenSim.Tests.Common // for the new system, everything has to be initialised first, // shared modules have to be post-initialised, then all get an AddRegion with the scene IRegionModuleBase m = (IRegionModuleBase)module; +// Console.WriteLine("MODULE {0}", m.Name); m.Initialise(config); newModules.Add(m); } @@ -426,6 +437,10 @@ namespace OpenSim.Tests.Common /// /// Add a root agent where the details of the agent connection (apart from the id) are unimportant for the test /// + /// + /// This can be used for tests where there is only one region or where there are multiple non-neighbour regions + /// and teleport doesn't take place. + /// /// /// /// @@ -435,6 +450,18 @@ namespace OpenSim.Tests.Common } /// + /// Add a root agent where the details of the agent connection (apart from the id) are unimportant for the test + /// + /// + /// + /// + /// + public static ScenePresence AddScenePresence(Scene scene, UUID agentId, SceneManager sceneManager) + { + return AddScenePresence(scene, GenerateAgentData(agentId), sceneManager); + } + + /// /// Add a root agent. /// /// @@ -454,6 +481,30 @@ namespace OpenSim.Tests.Common /// public static ScenePresence AddScenePresence(Scene scene, AgentCircuitData agentData) { + return AddScenePresence(scene, agentData, null); + } + + /// + /// Add a root agent. + /// + /// + /// This function + /// + /// 1) Tells the scene that an agent is coming. Normally, the login service (local if standalone, from the + /// userserver if grid) would give initial login data back to the client and separately tell the scene that the + /// agent was coming. + /// + /// 2) Connects the agent with the scene + /// + /// This function performs actions equivalent with notifying the scene that an agent is + /// coming and then actually connecting the agent to the scene. The one step missed out is the very first + /// + /// + /// + /// + /// + public static ScenePresence AddScenePresence(Scene scene, AgentCircuitData agentData, SceneManager sceneManager) + { // We emulate the proper login sequence here by doing things in four stages // Stage 0: login @@ -463,7 +514,7 @@ namespace OpenSim.Tests.Common lpsc.m_PresenceService.LoginAgent(agentData.AgentID.ToString(), agentData.SessionID, agentData.SecureSessionID); // Stages 1 & 2 - ScenePresence sp = IntroduceClientToScene(scene, agentData, TeleportFlags.ViaLogin); + ScenePresence sp = IntroduceClientToScene(scene, sceneManager, agentData, TeleportFlags.ViaLogin); // Stage 3: Complete the entrance into the region. This converts the child agent into a root agent. sp.CompleteMovement(sp.ControllingClient, true); @@ -471,7 +522,20 @@ namespace OpenSim.Tests.Common return sp; } - private static ScenePresence IntroduceClientToScene(Scene scene, AgentCircuitData agentData, TeleportFlags tf) + /// + /// Introduce an agent into the scene by adding a new client. + /// + /// The scene presence added + /// + /// Scene manager. Can be null if there is only one region in the test or multiple regions that are not + /// neighbours and where no teleporting takes place. + /// + /// + /// + /// + private static ScenePresence IntroduceClientToScene( + Scene scene, SceneManager sceneManager, AgentCircuitData agentData, TeleportFlags tf) { string reason; @@ -480,7 +544,7 @@ namespace OpenSim.Tests.Common Console.WriteLine("NewUserConnection failed: " + reason); // Stage 2: add the new client as a child agent to the scene - TestClient client = new TestClient(agentData, scene); + TestClient client = new TestClient(agentData, scene, sceneManager); scene.AddNewClient(client, PresenceType.User); return scene.GetScenePresence(agentData.AgentID); @@ -492,7 +556,7 @@ namespace OpenSim.Tests.Common acd.child = true; // XXX: ViaLogin may not be correct for child agents - return IntroduceClientToScene(scene, acd, TeleportFlags.ViaLogin); + return IntroduceClientToScene(scene, null, acd, TeleportFlags.ViaLogin); } /// diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index cb9840e..36049a1 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -46,12 +46,10 @@ namespace OpenSim.Tests.Common.Mock EventWaitHandle wh = new EventWaitHandle (false, EventResetMode.AutoReset, "Crossing"); - // TODO: This is a really nasty (and temporary) means of telling the test client which scene to invoke setup - // methods on when a teleport is requested - public Scene TeleportTargetScene; private TestClient TeleportSceneClient; private Scene m_scene; + private SceneManager m_sceneManager; // Properties so that we can get at received data for test purposes public List ReceivedOfflineNotifications { get; private set; } @@ -432,15 +430,29 @@ namespace OpenSim.Tests.Common.Mock /// /// Constructor /// + /// + /// Can be used for a test where there is only one region or where there are multiple regions that are not + /// neighbours and where no teleporting takes place. In other situations, the constructor that takes in a + /// scene manager should be used. + /// /// /// - public TestClient(AgentCircuitData agentData, Scene scene) + public TestClient(AgentCircuitData agentData, Scene scene) : this(agentData, scene, null) {} + + /// + /// Constructor + /// + /// + /// + /// + public TestClient(AgentCircuitData agentData, Scene scene, SceneManager sceneManager) { m_agentId = agentData.AgentID; m_firstName = agentData.firstname; m_lastName = agentData.lastname; m_circuitCode = agentData.circuitcode; m_scene = scene; + m_sceneManager = sceneManager; SessionId = agentData.SessionID; SecureSessionId = agentData.SecureSessionID; CapsSeedUrl = agentData.CapsPath; @@ -590,8 +602,16 @@ namespace OpenSim.Tests.Common.Mock AgentCircuitData newAgent = RequestClientInfo(); // Stage 2: add the new client as a child agent to the scene - TeleportSceneClient = new TestClient(newAgent, TeleportTargetScene); - TeleportTargetScene.AddNewClient(TeleportSceneClient, PresenceType.User); + uint x, y; + Utils.LongToUInts(neighbourHandle, out x, out y); + x /= Constants.RegionSize; + y /= Constants.RegionSize; + + Scene neighbourScene; + m_sceneManager.TryGetScene(x, y, out neighbourScene); + + TeleportSceneClient = new TestClient(newAgent, neighbourScene, m_sceneManager); + neighbourScene.AddNewClient(TeleportSceneClient, PresenceType.User); } public virtual void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint, @@ -601,6 +621,13 @@ namespace OpenSim.Tests.Common.Mock CapsSeedUrl = capsURL; + // We don't do this here so that the source region can complete processing first in a single-threaded + // regression test scenario. The test itself will have to call CompleteTeleportClientSide() after a teleport + // CompleteTeleportClientSide(); + } + + public void CompleteTeleportClientSide() + { TeleportSceneClient.CompleteMovement(); //TeleportTargetScene.AgentCrossing(newAgent.AgentID, new Vector3(90, 90, 90), false); } diff --git a/OpenSim/Tests/Common/TestHelpers.cs b/OpenSim/Tests/Common/TestHelpers.cs index 5030d4b..6744fca 100644 --- a/OpenSim/Tests/Common/TestHelpers.cs +++ b/OpenSim/Tests/Common/TestHelpers.cs @@ -46,7 +46,8 @@ namespace OpenSim.Tests.Common - + + @@ -62,9 +63,9 @@ namespace OpenSim.Tests.Common Encoding.UTF8.GetBytes( // ""))); //""))); - //""))); - //""))); - //""))); +// "")); +// ""))); +// "")); "")); public static bool AssertThisDelegateCausesArgumentException(TestDelegate d) -- cgit v1.1 From a29f7f7551c0b6d783d9c6df9f6a6487901dfd82 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 1 May 2012 23:25:30 +0100 Subject: Remove some test code that accidentally crept in with 9d2e1c67 --- .../CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 35486bb..75d1586 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -514,9 +514,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } else { - ICapabilitiesModule capModule = sp.Scene.CapsModule; - ulong regionHandle = reg.RegionHandle; - capModule.GetChildSeed(UUID.Zero, regionHandle); agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); } -- cgit v1.1 From 40f3c24562e620e8f09b3569c0b643eb5eae013f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 1 May 2012 23:49:02 +0100 Subject: Comment out the five second sleep in etm.DoTeleport() if the old agent needs to be closed because it is no longer in the child's view distance. This sleep appears unnecessary since a sleep has already occurred in WaitForCallback() whilst waiting for the destination region to notify of teleport success. There are no async operations between this sleep and the WaitForCallback() If this sleep is present, then teleporting back to the source region within 5 seconds results in a disconnection. If this sleep is commented out then teleporting quickly back and forth between two simulators appears to work without issue. Tested on standalone, local grid and distributed grid. Please revert if there's something that I've missed. --- .../Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 75d1586..8d5e0a5 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -595,7 +595,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) { - Thread.Sleep(5000); +// Thread.Sleep(5000); sp.Close(); sp.Scene.IncomingCloseAgent(sp.UUID); } -- cgit v1.1 From 231a3bf147315a9284140476d2b09e13c3fee1c0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 3 May 2012 01:45:49 +0100 Subject: Implement optional name and description on http stream handlers so that we can relate a slow request to what the handler actually does and the agent it serves, if applicable. This is most useful for capabilities where the url is not self-describing. --- .../FetchInventory2ServerConnector.cs | 3 +- .../Handlers/GetMesh/GetMeshServerConnector.cs | 15 ++-- .../Handlers/GetTexture/GetTextureHandler.cs | 4 +- .../GetTexture/GetTextureServerConnector.cs | 6 +- .../GetTexture/Tests/GetTextureHandlerTests.cs | 2 +- .../UploadBakedTextureHandler.cs | 4 +- .../WebFetchInvDescServerConnector.cs | 8 +- OpenSim/Capabilities/LLSDStreamHandler.cs | 6 +- .../Servers/HttpServer/BaseHTTPHandler.cs | 10 +-- .../Framework/Servers/HttpServer/BaseHttpServer.cs | 16 +++- .../Servers/HttpServer/BaseRequestHandler.cs | 10 ++- .../Servers/HttpServer/BaseStreamHandler.cs | 9 ++- .../Servers/HttpServer/BinaryStreamHandler.cs | 17 ++-- .../HttpServer/Interfaces/IStreamHandler.cs | 21 ++++- .../Servers/HttpServer/RestDeserialiseHandler.cs | 6 +- .../Servers/HttpServer/RestHTTPHandler.cs | 20 +++-- .../Servers/HttpServer/RestStreamHandler.cs | 14 ++-- OpenSim/Region/Application/OpenSimBase.cs | 11 ++- .../Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 47 ++++++++--- .../Linden/Caps/EventQueue/EventQueueGetModule.cs | 8 +- .../Linden/Caps/FetchInventory2Module.cs | 3 +- .../ClientStack/Linden/Caps/GetMeshModule.cs | 12 +-- .../ClientStack/Linden/Caps/GetTextureModule.cs | 4 +- .../Linden/Caps/MeshUploadFlagModule.cs | 4 +- .../NewFileAgentInventoryVariablePriceModule.cs | 93 ++++++++++++---------- .../Linden/Caps/ObjectCaps/ObjectAdd.cs | 14 ++-- .../Caps/ObjectCaps/UploadObjectAssetModule.cs | 15 ++-- .../Linden/Caps/SimulatorFeaturesModule.cs | 4 +- .../Linden/Caps/UploadBakedTextureModule.cs | 4 +- .../Linden/Caps/WebFetchInvDescModule.cs | 9 ++- .../CoreModules/World/Land/LandManagementModule.cs | 33 ++++---- .../CoreModules/World/Media/Moap/MoapModule.cs | 8 +- .../CoreModules/World/WorldMap/WorldMapModule.cs | 17 ++-- .../Region/Framework/Scenes/RegionStatsHandler.cs | 9 ++- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 53 ++++++------ .../Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 54 +++++++------ OpenSim/Region/UserStatistics/WebStatsModule.cs | 17 ++-- .../Handlers/Authentication/OpenIdServerHandler.cs | 2 + 38 files changed, 375 insertions(+), 217 deletions(-) diff --git a/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2ServerConnector.cs b/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2ServerConnector.cs index 0ba8931..5bab52f 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2ServerConnector.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2ServerConnector.cs @@ -63,7 +63,8 @@ namespace OpenSim.Capabilities.Handlers FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService); IRequestHandler reqHandler - = new RestStreamHandler("POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest); + = new RestStreamHandler( + "POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest, "FetchInventory", null); server.AddStreamHandler(reqHandler); } } diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs index 2ecfa3c..8a275f3 100644 --- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs @@ -66,13 +66,14 @@ namespace OpenSim.Capabilities.Handlers throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService); - IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), - delegate(Hashtable m_dhttpMethod) - { - return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null); - }); + IRequestHandler reqHandler + = new RestHTTPHandler( + "GET", + "/CAPS/" + UUID.Random(), + httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null), + "GetMesh", + null); server.AddStreamHandler(reqHandler); } - } -} +} \ No newline at end of file diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index 217217e..abdbc72 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -58,8 +58,8 @@ namespace OpenSim.Capabilities.Handlers // TODO: Change this to a config option const string REDIRECT_URL = null; - public GetTextureHandler(string path, IAssetService assService) : - base("GET", path) + public GetTextureHandler(string path, IAssetService assService, string name, string description) + : base("GET", path, name, description) { m_assetService = assService; } diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs index 0d072f7..71cf033 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs @@ -62,8 +62,8 @@ namespace OpenSim.Capabilities.Handlers if (m_AssetService == null) throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); - server.AddStreamHandler(new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService)); + server.AddStreamHandler( + new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null)); } - } -} +} \ No newline at end of file diff --git a/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs b/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs index 85e5cc6..761e4e7 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs @@ -52,7 +52,7 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests // Overkill - we only really need the asset service, not a whole scene. Scene scene = new SceneHelpers().SetupScene(); - GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService); + GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService, "TestGetTexture", null); TestOSHttpRequest req = new TestOSHttpRequest(); TestOSHttpResponse resp = new TestOSHttpResponse(); req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012"); diff --git a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs index 594ce9d..8849a59 100644 --- a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs @@ -85,8 +85,8 @@ namespace OpenSim.Capabilities.Handlers uploader.OnUpLoad += BakedTextureUploaded; m_HostCapsObj.HttpListener.AddStreamHandler( - new BinaryStreamHandler("POST", capsBase + uploaderPath, - uploader.uploaderCaps)); + new BinaryStreamHandler( + "POST", capsBase + uploaderPath, uploader.uploaderCaps, "UploadBakedTexture", null)); string protocol = "http://"; diff --git a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescServerConnector.cs b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescServerConnector.cs index 92eeb14..5d86557 100644 --- a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescServerConnector.cs +++ b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescServerConnector.cs @@ -68,7 +68,13 @@ namespace OpenSim.Capabilities.Handlers ServerUtils.LoadPlugin(libService, args); WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService); - IRequestHandler reqHandler = new RestStreamHandler("POST", "/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/, webFetchHandler.FetchInventoryDescendentsRequest); + IRequestHandler reqHandler + = new RestStreamHandler( + "POST", + "/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/, + webFetchHandler.FetchInventoryDescendentsRequest, + "WebFetchInvDesc", + null); server.AddStreamHandler(reqHandler); } diff --git a/OpenSim/Capabilities/LLSDStreamHandler.cs b/OpenSim/Capabilities/LLSDStreamHandler.cs index c7c1fc9..f5c728c 100644 --- a/OpenSim/Capabilities/LLSDStreamHandler.cs +++ b/OpenSim/Capabilities/LLSDStreamHandler.cs @@ -39,7 +39,11 @@ namespace OpenSim.Framework.Capabilities private LLSDMethod m_method; public LLSDStreamhandler(string httpMethod, string path, LLSDMethod method) - : base(httpMethod, path) + : this(httpMethod, path, method, null, null) {} + + public LLSDStreamhandler( + string httpMethod, string path, LLSDMethod method, string name, string description) + : base(httpMethod, path, name, description) { m_method = method; } diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs index 2fe9769..9f8f4a8 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs @@ -33,9 +33,9 @@ namespace OpenSim.Framework.Servers.HttpServer { public abstract Hashtable Handle(string path, Hashtable Request); - protected BaseHTTPHandler(string httpMethod, string path) - : base(httpMethod, path) - { - } + protected BaseHTTPHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {} + + protected BaseHTTPHandler(string httpMethod, string path, string name, string description) + : base(httpMethod, path, name, description) {} } -} +} \ No newline at end of file diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 0fbf90a..4ea4a1a 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -156,7 +156,7 @@ namespace OpenSim.Framework.Servers.HttpServer } } - public List GetStreamHandlerKeys() + public List GetStreamHandlerKeys() { lock (m_streamHandlers) return new List(m_streamHandlers.Keys); @@ -410,6 +410,8 @@ namespace OpenSim.Framework.Servers.HttpServer // string reqnum = "unknown"; int tickstart = Environment.TickCount; + IRequestHandler requestHandler = null; + try { // OpenSim.Framework.WebUtil.OSHeaderRequestID @@ -438,8 +440,6 @@ namespace OpenSim.Framework.Servers.HttpServer //response.KeepAlive = true; response.SendChunked = false; - IRequestHandler requestHandler; - string path = request.RawUrl; string handlerKey = GetHandlerKey(request.HttpMethod, path); @@ -675,8 +675,16 @@ namespace OpenSim.Framework.Servers.HttpServer // since its just for reporting, tickdiff limit can be adjusted int tickdiff = Environment.TickCount - tickstart; if (tickdiff > 3000) + { m_log.InfoFormat( - "[BASE HTTP SERVER]: slow {0} request for {1} from {2} took {3} ms", requestMethod, uriString, request.RemoteIPEndPoint.ToString(), tickdiff); + "[BASE HTTP SERVER]: slow {0} for {1} {2} {3} from {4} took {5} ms", + requestMethod, + uriString, + requestHandler != null ? requestHandler.Name : "", + requestHandler != null ? requestHandler.Description : "", + request.RemoteIPEndPoint.ToString(), + tickdiff); + } } } diff --git a/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs index a2135a3..ae7aaf2 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs @@ -45,8 +45,16 @@ namespace OpenSim.Framework.Servers.HttpServer private readonly string m_path; - protected BaseRequestHandler(string httpMethod, string path) + public string Name { get; private set; } + + public string Description { get; private set; } + + protected BaseRequestHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {} + + protected BaseRequestHandler(string httpMethod, string path, string name, string description) { + Name = name; + Description = description; m_httpMethod = httpMethod; m_path = path; } diff --git a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs index f1cde74..6342983 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs @@ -34,8 +34,9 @@ namespace OpenSim.Framework.Servers.HttpServer public abstract byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse); - protected BaseStreamHandler(string httpMethod, string path) : base(httpMethod, path) - { - } + protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {} + + protected BaseStreamHandler(string httpMethod, string path, string name, string description) + : base(httpMethod, path, name, description) {} } -} +} \ No newline at end of file diff --git a/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs index 1699233..b94bfb4 100644 --- a/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs @@ -36,6 +36,15 @@ namespace OpenSim.Framework.Servers.HttpServer { private BinaryMethod m_method; + public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod) + : this(httpMethod, path, binaryMethod, null, null) {} + + public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod, string name, string description) + : base(httpMethod, path, name, description) + { + m_method = binaryMethod; + } + public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { byte[] data = ReadFully(request); @@ -45,12 +54,6 @@ namespace OpenSim.Framework.Servers.HttpServer return Encoding.UTF8.GetBytes(responseString); } - public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod) - : base(httpMethod, path) - { - m_method = binaryMethod; - } - private static byte[] ReadFully(Stream stream) { byte[] buffer = new byte[1024]; @@ -70,4 +73,4 @@ namespace OpenSim.Framework.Servers.HttpServer } } } -} +} \ No newline at end of file diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs index a449c2d..cb5cce5 100644 --- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs @@ -32,6 +32,25 @@ namespace OpenSim.Framework.Servers.HttpServer { public interface IRequestHandler { + + /// + /// Name for this handler. + /// + /// + /// Used for diagnostics. The path doesn't always describe what the handler does. Can be null if none + /// specified. + /// + string Name { get; } + + /// + /// Description for this handler. + /// + /// + /// Used for diagnostics. The path doesn't always describe what the handler does. Can be null if none + /// specified. + /// + string Description { get; } + // Return response content type string ContentType { get; } @@ -58,4 +77,4 @@ namespace OpenSim.Framework.Servers.HttpServer { Hashtable Handle(string path, Hashtable request); } -} +} \ No newline at end of file diff --git a/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs index a467a83..07082a8 100644 --- a/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs @@ -39,7 +39,11 @@ namespace OpenSim.Framework.Servers.HttpServer private RestDeserialiseMethod m_method; public RestDeserialiseHandler(string httpMethod, string path, RestDeserialiseMethod method) - : base(httpMethod, path) + : this(httpMethod, path, method, null, null) {} + + public RestDeserialiseHandler( + string httpMethod, string path, RestDeserialiseMethod method, string name, string description) + : base(httpMethod, path, name, description) { m_method = method; } diff --git a/OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs index 1f23cac..7f89839 100644 --- a/OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs @@ -38,19 +38,25 @@ namespace OpenSim.Framework.Servers.HttpServer get { return m_dhttpMethod; } } - public override Hashtable Handle(string path, Hashtable request) + public RestHTTPHandler(string httpMethod, string path, GenericHTTPMethod dhttpMethod) + : base(httpMethod, path) { + m_dhttpMethod = dhttpMethod; + } + + public RestHTTPHandler( + string httpMethod, string path, GenericHTTPMethod dhttpMethod, string name, string description) + : base(httpMethod, path, name, description) + { + m_dhttpMethod = dhttpMethod; + } + public override Hashtable Handle(string path, Hashtable request) + { string param = GetParam(path); request.Add("param", param); request.Add("path", path); return m_dhttpMethod(request); } - - public RestHTTPHandler(string httpMethod, string path, GenericHTTPMethod dhttpMethod) - : base(httpMethod, path) - { - m_dhttpMethod = dhttpMethod; - } } } diff --git a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs index d2c4002..1f17fee 100644 --- a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs @@ -39,6 +39,15 @@ namespace OpenSim.Framework.Servers.HttpServer get { return m_restMethod; } } + public RestStreamHandler(string httpMethod, string path, RestMethod restMethod) + : this(httpMethod, path, restMethod, null, null) {} + + public RestStreamHandler(string httpMethod, string path, RestMethod restMethod, string name, string description) + : base(httpMethod, path, name, description) + { + m_restMethod = restMethod; + } + public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { Encoding encoding = Encoding.UTF8; @@ -52,10 +61,5 @@ namespace OpenSim.Framework.Servers.HttpServer return Encoding.UTF8.GetBytes(responseString); } - - public RestStreamHandler(string httpMethod, string path, RestMethod restMethod) : base(httpMethod, path) - { - m_restMethod = restMethod; - } } } diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 5de3f25..79259d8 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -388,7 +388,7 @@ namespace OpenSim scene.LoadPrimsFromStorage(regionInfo.originRegionID); // TODO : Try setting resource for region xstats here on scene - MainServer.Instance.AddStreamHandler(new Region.Framework.Scenes.RegionStatsHandler(regionInfo)); + MainServer.Instance.AddStreamHandler(new RegionStatsHandler(regionInfo)); scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID); scene.EventManager.TriggerParcelPrimCountUpdate(); @@ -773,6 +773,9 @@ namespace OpenSim return Util.UTF8.GetBytes("OK"); } + public string Name { get { return "SimStatus"; } } + public string Description { get { return "Simulator Status"; } } + public string ContentType { get { return "text/plain"; } @@ -797,6 +800,9 @@ namespace OpenSim { OpenSimBase m_opensim; string osXStatsURI = String.Empty; + + public string Name { get { return "XSimStatus"; } } + public string Description { get { return "Simulator XStatus"; } } public XSimStatusHandler(OpenSimBase sim) { @@ -837,6 +843,9 @@ namespace OpenSim { OpenSimBase m_opensim; string osUXStatsURI = String.Empty; + + public string Name { get { return "UXSimStatus"; } } + public string Description { get { return "Simulator UXStatus"; } } public UXSimStatusHandler(OpenSimBase sim) { diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index e20c24f..9791885 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -155,7 +155,9 @@ namespace OpenSim.Region.ClientStack.Linden try { // the root of all evil - m_HostCapsObj.RegisterHandler("SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest)); + m_HostCapsObj.RegisterHandler( + "SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null)); + m_log.DebugFormat( "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID); @@ -163,7 +165,10 @@ namespace OpenSim.Region.ClientStack.Linden // new LLSDStreamhandler("POST", // capsBase + m_mapLayerPath, // GetMapLayer); - IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory); + IRequestHandler req + = new RestStreamHandler( + "POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory, "UpdateScript", null); + m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req); m_HostCapsObj.RegisterHandler("UpdateScriptTask", req); } @@ -178,14 +183,27 @@ namespace OpenSim.Region.ClientStack.Linden try { // I don't think this one works... - m_HostCapsObj.RegisterHandler("NewFileAgentInventory", new LLSDStreamhandler("POST", - capsBase + m_newInventory, - NewAgentInventoryRequest)); - IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory); + m_HostCapsObj.RegisterHandler( + "NewFileAgentInventory", + new LLSDStreamhandler( + "POST", + capsBase + m_newInventory, + NewAgentInventoryRequest, + "NewFileAgentInventory", + null)); + + IRequestHandler req + = new RestStreamHandler( + "POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory, "Update*", null); + m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); - m_HostCapsObj.RegisterHandler("CopyInventoryFromNotecard", new RestStreamHandler("POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard)); + + m_HostCapsObj.RegisterHandler( + "CopyInventoryFromNotecard", + new RestStreamHandler( + "POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard, "CopyInventoryFromNotecard", null)); // As of RC 1.22.9 of the Linden client this is // supported @@ -289,7 +307,9 @@ namespace OpenSim.Region.ClientStack.Linden m_dumpAssetsToFile); uploader.OnUpLoad += TaskScriptUpdated; - m_HostCapsObj.HttpListener.AddStreamHandler(new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); + m_HostCapsObj.HttpListener.AddStreamHandler( + new BinaryStreamHandler( + "POST", capsBase + uploaderPath, uploader.uploaderCaps, "BunchOfCaps", null)); string protocol = "http://"; @@ -416,8 +436,14 @@ namespace OpenSim.Region.ClientStack.Linden AssetUploader uploader = new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile); + m_HostCapsObj.HttpListener.AddStreamHandler( - new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); + new BinaryStreamHandler( + "POST", + capsBase + uploaderPath, + uploader.uploaderCaps, + "NewAgentInventoryRequest", + m_HostCapsObj.AgentID.ToString())); string protocol = "http://"; @@ -733,7 +759,8 @@ namespace OpenSim.Region.ClientStack.Linden uploader.OnUpLoad += ItemUpdated; m_HostCapsObj.HttpListener.AddStreamHandler( - new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); + new BinaryStreamHandler( + "POST", capsBase + uploaderPath, uploader.uploaderCaps, "NoteCardAgentInventory", null)); string protocol = "http://"; diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 7c07c56..1a35d22 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -351,14 +351,18 @@ namespace OpenSim.Region.ClientStack.Linden // EventQueueGet when it receive capability information, but then we replace the rest handler immediately // afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but // really it should be possible to directly register the poll handler as a capability. - caps.RegisterHandler("EventQueueGet", - new RestHTTPHandler("POST", capsBase + EventQueueGetUUID.ToString() + "/", null)); + caps.RegisterHandler( + "EventQueueGet", + new RestHTTPHandler( + "POST", capsBase + EventQueueGetUUID.ToString() + "/", null)); + // delegate(Hashtable m_dhttpMethod) // { // return ProcessQueue(m_dhttpMethod, agentID, caps); // })); // This will persist this beyond the expiry of the caps handlers + // TODO: Add EventQueueGet name/description for diagnostics MainServer.Instance.AddPollServiceHTTPHandler( capsBase + EventQueueGetUUID.ToString() + "/", new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs index 14501c7..cb5afcc 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs @@ -132,7 +132,8 @@ namespace OpenSim.Region.ClientStack.Linden capUrl = "/CAPS/" + UUID.Random(); IRequestHandler reqHandler - = new RestStreamHandler("POST", capUrl, m_fetchHandler.FetchInventoryRequest); + = new RestStreamHandler( + "POST", capUrl, m_fetchHandler.FetchInventoryRequest, capName, agentID.ToString()); caps.RegisterHandler(capName, reqHandler); } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs index e7bd2e7..0d7b1fc 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs @@ -120,11 +120,13 @@ namespace OpenSim.Region.ClientStack.Linden { // m_log.DebugFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService); - IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), - delegate(Hashtable m_dhttpMethod) - { - return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null); - }); + IRequestHandler reqHandler + = new RestHTTPHandler( + "GET", + "/CAPS/" + UUID.Random(), + httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null), + "GetMesh", + agentID.ToString()); caps.RegisterHandler("GetMesh", reqHandler); } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index fffcee2..5ae9cc3 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -130,7 +130,9 @@ namespace OpenSim.Region.ClientStack.Linden if (m_URL == "localhost") { // m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); - caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService)); + caps.RegisterHandler( + "GetTexture", + new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString())); } else { diff --git a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs index 18c7eae..44a6883 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs @@ -117,7 +117,9 @@ namespace OpenSim.Region.ClientStack.Linden public void RegisterCaps(UUID agentID, Caps caps) { - IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag); + IRequestHandler reqHandler + = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag, "MeshUploadFlag", agentID.ToString()); + caps.RegisterHandler("MeshUploadFlag", reqHandler); m_agentID = agentID; } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs index 91872c5..52c4f44 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs @@ -115,67 +115,66 @@ namespace OpenSim.Region.ClientStack.Linden UUID capID = UUID.Random(); // m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID); - caps.RegisterHandler("NewFileAgentInventoryVariablePrice", - - new LLSDStreamhandler("POST", - "/CAPS/" + capID.ToString(), - delegate(LLSDAssetUploadRequest req) - { - return NewAgentInventoryRequest(req,agentID); - })); - + caps.RegisterHandler( + "NewFileAgentInventoryVariablePrice", + new LLSDStreamhandler( + "POST", + "/CAPS/" + capID.ToString(), + req => NewAgentInventoryRequest(req, agentID), + "NewFileAgentInventoryVariablePrice", + agentID.ToString())); } #endregion public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID) { - //TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit - // You need to be aware of this and - + // you need to be aware of this //if (llsdRequest.asset_type == "texture" || // llsdRequest.asset_type == "animation" || // llsdRequest.asset_type == "sound") // { // check user level - ScenePresence avatar = null; - IClientAPI client = null; - m_scene.TryGetScenePresence(agentID, out avatar); - if (avatar != null) + ScenePresence avatar = null; + IClientAPI client = null; + m_scene.TryGetScenePresence(agentID, out avatar); + + if (avatar != null) + { + client = avatar.ControllingClient; + + if (avatar.UserLevel < m_levelUpload) { - client = avatar.ControllingClient; - - if (avatar.UserLevel < m_levelUpload) - { - if (client != null) - client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false); - - LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); - errorResponse.rsvp = ""; - errorResponse.state = "error"; - return errorResponse; - } + if (client != null) + client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false); + + LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); + errorResponse.rsvp = ""; + errorResponse.state = "error"; + return errorResponse; } + } - // check funds - IMoneyModule mm = m_scene.RequestModuleInterface(); + // check funds + IMoneyModule mm = m_scene.RequestModuleInterface(); - if (mm != null) + if (mm != null) + { + if (!mm.UploadCovered(agentID, mm.UploadCharge)) { - if (!mm.UploadCovered(agentID, mm.UploadCharge)) - { - if (client != null) - client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); - - LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); - errorResponse.rsvp = ""; - errorResponse.state = "error"; - return errorResponse; - } + if (client != null) + client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); + + LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); + errorResponse.rsvp = ""; + errorResponse.state = "error"; + return errorResponse; } + } + // } string assetName = llsdRequest.name; @@ -189,8 +188,14 @@ namespace OpenSim.Region.ClientStack.Linden AssetUploader uploader = new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile); + MainServer.Instance.AddStreamHandler( - new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); + new BinaryStreamHandler( + "POST", + capsBase + uploaderPath, + uploader.uploaderCaps, + "NewFileAgentInventoryVariablePrice", + agentID.ToString())); string protocol = "http://"; @@ -199,10 +204,9 @@ namespace OpenSim.Region.ClientStack.Linden string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase + uploaderPath; - + LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); - uploadResponse.rsvp = uploaderURL; uploadResponse.state = "upload"; @@ -220,6 +224,7 @@ namespace OpenSim.Region.ClientStack.Linden pinventoryItem, pparentFolder, pdata, pinventoryType, passetType,agentID); }; + return uploadResponse; } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs index 1c47f0e..4ccfc43 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs @@ -66,12 +66,14 @@ namespace OpenSim.Region.ClientStack.Linden // m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/"); - caps.RegisterHandler("ObjectAdd", - new RestHTTPHandler("POST", "/CAPS/OA/" + capuuid + "/", - delegate(Hashtable m_dhttpMethod) - { - return ProcessAdd(m_dhttpMethod, agentID, caps); - })); + caps.RegisterHandler( + "ObjectAdd", + new RestHTTPHandler( + "POST", + "/CAPS/OA/" + capuuid + "/", + httpMethod => ProcessAdd(httpMethod, agentID, caps), + "ObjectAdd", + agentID.ToString()));; } public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs index 7a3d97e..f0f3984 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs @@ -106,12 +106,15 @@ namespace OpenSim.Region.ClientStack.Linden UUID capID = UUID.Random(); // m_log.Debug("[UPLOAD OBJECT ASSET MODULE]: /CAPS/" + capID); - caps.RegisterHandler("UploadObjectAsset", - new RestHTTPHandler("POST", "/CAPS/OA/" + capID + "/", - delegate(Hashtable m_dhttpMethod) - { - return ProcessAdd(m_dhttpMethod, agentID, caps); - })); + caps.RegisterHandler( + "UploadObjectAsset", + new RestHTTPHandler( + "POST", + "/CAPS/OA/" + capID + "/", + httpMethod => ProcessAdd(httpMethod, agentID, caps), + "UploadObjectAsset", + agentID.ToString())); + /* caps.RegisterHandler("NewFileAgentInventoryVariablePrice", diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index 1dd8938..8ed0fb3 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs @@ -154,7 +154,9 @@ namespace OpenSim.Region.ClientStack.Linden public void RegisterCaps(UUID agentID, Caps caps) { IRequestHandler reqHandler - = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), HandleSimulatorFeaturesRequest); + = new RestHTTPHandler( + "GET", "/CAPS/" + UUID.Random(), + HandleSimulatorFeaturesRequest, "SimulatorFeatures", agentID.ToString()); caps.RegisterHandler("SimulatorFeatures", reqHandler); } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs index 45d6071..b3d61a8 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs @@ -106,7 +106,9 @@ namespace OpenSim.Region.ClientStack.Linden "POST", "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath, new UploadBakedTextureHandler( - caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture)); + caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture, + "UploadBakedTexture", + agentID.ToString())); } } } \ No newline at end of file diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 10f43d1..2359bd6 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -144,7 +144,12 @@ namespace OpenSim.Region.ClientStack.Linden capUrl = "/CAPS/" + UUID.Random(); IRequestHandler reqHandler - = new RestStreamHandler("POST", capUrl, m_webFetchHandler.FetchInventoryDescendentsRequest); + = new RestStreamHandler( + "POST", + capUrl, + m_webFetchHandler.FetchInventoryDescendentsRequest, + "FetchInventoryDescendents2", + agentID.ToString()); caps.RegisterHandler(capName, reqHandler); } @@ -160,4 +165,4 @@ namespace OpenSim.Region.ClientStack.Linden // capName, capUrl, m_scene.RegionInfo.RegionName, agentID); } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index f6d4b40..8b7406d 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -1433,21 +1433,26 @@ namespace OpenSim.Region.CoreModules.World.Land private void EventManagerOnRegisterCaps(UUID agentID, Caps caps) { string capsBase = "/CAPS/" + caps.CapsObjectPath; - caps.RegisterHandler("RemoteParcelRequest", - new RestStreamHandler("POST", capsBase + remoteParcelRequestPath, - delegate(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - return RemoteParcelRequest(request, path, param, agentID, caps); - })); + caps.RegisterHandler( + "RemoteParcelRequest", + new RestStreamHandler( + "POST", + capsBase + remoteParcelRequestPath, + (request, path, param, httpRequest, httpResponse) + => RemoteParcelRequest(request, path, param, agentID, caps), + "RemoteParcelRequest", + agentID.ToString())); + UUID parcelCapID = UUID.Random(); - caps.RegisterHandler("ParcelPropertiesUpdate", - new RestStreamHandler("POST", "/CAPS/" + parcelCapID, - delegate(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - return ProcessPropertiesUpdate(request, path, param, agentID, caps); - })); + caps.RegisterHandler( + "ParcelPropertiesUpdate", + new RestStreamHandler( + "POST", + "/CAPS/" + parcelCapID, + (request, path, param, httpRequest, httpResponse) + => ProcessPropertiesUpdate(request, path, param, agentID, caps), + "ParcelPropertiesUpdate", + agentID.ToString())); } private string ProcessPropertiesUpdate(string request, string path, string param, UUID agentID, Caps caps) { diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs index 5239f50..601e81e 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs @@ -145,7 +145,9 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap // Even though we're registering for POST we're going to get GETS and UPDATES too caps.RegisterHandler( - "ObjectMedia", new RestStreamHandler("POST", omCapUrl, HandleObjectMediaMessage)); + "ObjectMedia", + new RestStreamHandler( + "POST", omCapUrl, HandleObjectMediaMessage, "ObjectMedia", agentID.ToString())); } string omuCapUrl = "/CAPS/" + UUID.Random(); @@ -157,7 +159,9 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap // Even though we're registering for POST we're going to get GETS and UPDATES too caps.RegisterHandler( - "ObjectMediaNavigate", new RestStreamHandler("POST", omuCapUrl, HandleObjectMediaNavigateMessage)); + "ObjectMediaNavigate", + new RestStreamHandler( + "POST", omuCapUrl, HandleObjectMediaNavigateMessage, "ObjectMediaNavigate", agentID.ToString())); } } diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index faaf928..2335bea 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -190,14 +190,15 @@ namespace OpenSim.Region.CoreModules.World.WorldMap { //m_log.DebugFormat("[WORLD MAP]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps); string capsBase = "/CAPS/" + caps.CapsObjectPath; - caps.RegisterHandler("MapLayer", - new RestStreamHandler("POST", capsBase + m_mapLayerPath, - delegate(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - return MapLayerRequest(request, path, param, - agentID, caps); - })); + caps.RegisterHandler( + "MapLayer", + new RestStreamHandler( + "POST", + capsBase + m_mapLayerPath, + (request, path, param, httpRequest, httpResponse) + => MapLayerRequest(request, path, param, agentID, caps), + "MapLayer", + agentID.ToString())); } /// diff --git a/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs b/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs index 6c5685c..1365831 100644 --- a/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs +++ b/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs @@ -48,16 +48,19 @@ namespace OpenSim.Region.Framework.Scenes { public class RegionStatsHandler : IStreamedRequestHandler { + //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private string osRXStatsURI = String.Empty; private string osXStatsURI = String.Empty; //private string osSecret = String.Empty; private OpenSim.Framework.RegionInfo regionInfo; public string localZone = TimeZone.CurrentTimeZone.StandardName; public TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now); - - //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public RegionStatsHandler(OpenSim.Framework.RegionInfo region_info) + public string Name { get { return "RegionStats"; } } + public string Description { get { return "Region Statistics"; } } + + public RegionStatsHandler(RegionInfo region_info) { regionInfo = region_info; osRXStatsURI = Util.SHA1Hash(regionInfo.regionSecret); diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 05678c0..be8873d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -306,30 +306,35 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice agentID, caps, scene.RegionInfo.RegionName); string capsBase = "/CAPS/" + caps.CapsObjectPath; - caps.RegisterHandler("ProvisionVoiceAccountRequest", - new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, - delegate(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - return ProvisionVoiceAccountRequest(scene, request, path, param, - agentID, caps); - })); - caps.RegisterHandler("ParcelVoiceInfoRequest", - new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, - delegate(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - return ParcelVoiceInfoRequest(scene, request, path, param, - agentID, caps); - })); - caps.RegisterHandler("ChatSessionRequest", - new RestStreamHandler("POST", capsBase + m_chatSessionRequestPath, - delegate(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - return ChatSessionRequest(scene, request, path, param, - agentID, caps); - })); + caps.RegisterHandler( + "ProvisionVoiceAccountRequest", + new RestStreamHandler( + "POST", + capsBase + m_provisionVoiceAccountRequestPath, + (request, path, param, httpRequest, httpResponse) + => ProvisionVoiceAccountRequest(scene, request, path, param, agentID, caps), + "ProvisionVoiceAccountRequest", + agentID.ToString())); + + caps.RegisterHandler( + "ParcelVoiceInfoRequest", + new RestStreamHandler( + "POST", + capsBase + m_parcelVoiceInfoRequestPath, + (request, path, param, httpRequest, httpResponse) + => ParcelVoiceInfoRequest(scene, request, path, param, agentID, caps), + "ParcelVoiceInfoRequest", + agentID.ToString())); + + caps.RegisterHandler( + "ChatSessionRequest", + new RestStreamHandler( + "POST", + capsBase + m_chatSessionRequestPath, + (request, path, param, httpRequest, httpResponse) + => ChatSessionRequest(scene, request, path, param, agentID, caps), + "ChatSessionRequest", + agentID.ToString())); } /// diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 738133c..a36fd74 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -406,30 +406,36 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice m_log.DebugFormat("[VivoxVoice] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); string capsBase = "/CAPS/" + caps.CapsObjectPath; - caps.RegisterHandler("ProvisionVoiceAccountRequest", - new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, - delegate(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - return ProvisionVoiceAccountRequest(scene, request, path, param, - agentID, caps); - })); - caps.RegisterHandler("ParcelVoiceInfoRequest", - new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, - delegate(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - return ParcelVoiceInfoRequest(scene, request, path, param, - agentID, caps); - })); - caps.RegisterHandler("ChatSessionRequest", - new RestStreamHandler("POST", capsBase + m_chatSessionRequestPath, - delegate(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - return ChatSessionRequest(scene, request, path, param, - agentID, caps); - })); + + caps.RegisterHandler( + "ProvisionVoiceAccountRequest", + new RestStreamHandler( + "POST", + capsBase + m_provisionVoiceAccountRequestPath, + (request, path, param, httpRequest, httpResponse) + => ProvisionVoiceAccountRequest(scene, request, path, param, agentID, caps), + "ProvisionVoiceAccountRequest", + agentID.ToString())); + + caps.RegisterHandler( + "ParcelVoiceInfoRequest", + new RestStreamHandler( + "POST", + capsBase + m_parcelVoiceInfoRequestPath, + (request, path, param, httpRequest, httpResponse) + => ParcelVoiceInfoRequest(scene, request, path, param, agentID, caps), + "ParcelVoiceInfoRequest", + agentID.ToString())); + + caps.RegisterHandler( + "ChatSessionRequest", + new RestStreamHandler( + "POST", + capsBase + m_chatSessionRequestPath, + (request, path, param, httpRequest, httpResponse) + => ChatSessionRequest(scene, request, path, param, agentID, caps), + "ChatSessionRequest", + agentID.ToString())); } /// diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index 4248035..faf746f 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -282,14 +282,15 @@ namespace OpenSim.Region.UserStatistics // m_log.DebugFormat("[WEB STATS MODULE]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps); string capsPath = "/CAPS/VS/" + UUID.Random(); - caps.RegisterHandler("ViewerStats", - new RestStreamHandler("POST", capsPath, - delegate(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - return ViewerStatsReport(request, path, param, - agentID, caps); - })); + caps.RegisterHandler( + "ViewerStats", + new RestStreamHandler( + "POST", + capsPath, + (request, path, param, httpRequest, httpResponse) + => ViewerStatsReport(request, path, param, agentID, caps), + "ViewerStats", + agentID.ToString())); } private void OnDeRegisterCaps(UUID agentID, Caps caps) diff --git a/OpenSim/Server/Handlers/Authentication/OpenIdServerHandler.cs b/OpenSim/Server/Handlers/Authentication/OpenIdServerHandler.cs index dfed761..18cef15 100644 --- a/OpenSim/Server/Handlers/Authentication/OpenIdServerHandler.cs +++ b/OpenSim/Server/Handlers/Authentication/OpenIdServerHandler.cs @@ -191,6 +191,8 @@ For more information, see http://openid.net/. #endregion HTML + public string Name { get { return "OpenId"; } } + public string Description { get { return null; } } public string ContentType { get { return m_contentType; } } public string HttpMethod { get { return m_httpMethod; } } public string Path { get { return m_path; } } -- cgit v1.1 From 9ffc2c106280a7b5b0eddba8cf906f1f7ad956a6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 3 May 2012 01:56:24 +0100 Subject: minor: resolve some mono compiler warnings --- .../CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 7 +------ .../ServiceConnectorsOut/Authorization/AuthorizationService.cs | 4 ++-- OpenSim/Region/DataSnapshot/DataRequestHandler.cs | 4 ++-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 8d5e0a5..e47c339 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1947,12 +1947,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer Thread.Sleep(100); } - if (count > 0) - return true; - else - return false; - - return true; + return count > 0; } protected void SetInTransit(UUID id) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs index f0d21e6..4470799 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs @@ -55,7 +55,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization MethodBase.GetCurrentMethod().DeclaringType); private IUserManagement m_UserManagement; - private IGridService m_GridService; +// private IGridService m_GridService; private Scene m_Scene; AccessFlags m_accessValue = AccessFlags.None; @@ -65,7 +65,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization { m_Scene = scene; m_UserManagement = scene.RequestModuleInterface(); - m_GridService = scene.GridService; +// m_GridService = scene.GridService; if (config != null) { diff --git a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs b/OpenSim/Region/DataSnapshot/DataRequestHandler.cs index 2f2b3e6..32e93b4 100644 --- a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs +++ b/OpenSim/Region/DataSnapshot/DataRequestHandler.cs @@ -42,13 +42,13 @@ namespace OpenSim.Region.DataSnapshot { public class DataRequestHandler { - private Scene m_scene = null; +// private Scene m_scene = null; private DataSnapshotManager m_externalData = null; private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public DataRequestHandler(Scene scene, DataSnapshotManager externalData) { - m_scene = scene; +// m_scene = scene; m_externalData = externalData; //Register HTTP handler -- cgit v1.1 From bf5f8b54ae24c50e7288d34525962ec174d4b473 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 3 May 2012 02:22:06 +0100 Subject: Remove the somewhat misleading logging of the string length of some unknown requests, as this appeared to be some kind of numbered error code. This brings these messages into line with similar messages that did not do this. --- OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs | 4 ++-- OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs | 2 +- OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs index 59420f5..ef9b96f 100644 --- a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs @@ -95,7 +95,8 @@ namespace OpenSim.Server.Handlers.Friends return DeleteFriendString(request); } - m_log.DebugFormat("[FRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method); + + m_log.DebugFormat("[FRIENDS HANDLER]: unknown method request {0}", method); } catch (Exception e) { @@ -103,7 +104,6 @@ namespace OpenSim.Server.Handlers.Friends } return FailureResult(); - } #region Method-specific handlers diff --git a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs index bebf482..91d14cb 100644 --- a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs @@ -116,7 +116,7 @@ namespace OpenSim.Server.Handlers.Grid return GetRegionFlags(request); } - m_log.DebugFormat("[GRID HANDLER]: unknown method {0} request {1}", method.Length, method); + m_log.DebugFormat("[GRID HANDLER]: unknown method request {0}", method); } catch (Exception e) { diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs index 8ef03e7..c2f127c 100644 --- a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs @@ -122,7 +122,8 @@ namespace OpenSim.Server.Handlers.Hypergrid return GrantRights(request); */ } - m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method); + + m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0}", method); } catch (Exception e) { -- cgit v1.1 From 100e4ca67ea5f9eacc575ac65ce3ac7cd81eeb3d Mon Sep 17 00:00:00 2001 From: Snoopy Pfeffer Date: Thu, 3 May 2012 19:00:09 +0200 Subject: Fixes Mantis #5999. llSetLinkPrimitiveParams with PRIM_BUMP_SHINY did cause a runtime error. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 62b5c0f..704dfc3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7336,7 +7336,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; face = (int)rules.GetLSLIntegerItem(idx++); int shiny = (int)rules.GetLSLIntegerItem(idx++); - Bumpiness bump = (Bumpiness)Convert.ToByte((int)rules.GetLSLIntegerItem(idx++)); + Bumpiness bump = (Bumpiness)(int)rules.GetLSLIntegerItem(idx++); SetShiny(part, face, shiny, bump); -- cgit v1.1 From fcd5b0817be93ccbb9897b424f70c5081a445e9f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 3 May 2012 22:30:36 +0100 Subject: Reinsert a 2000ms delay before closing a no longer required agent on the source region after teleport to resolve Imprudence teleport problems. Viewers 1 and 3 are fine with doing this immediately. However, Imprudence has a small delay (<200ms, >500ms) after receiving the AgentCompleteMovement reply packet on the destination region before regarding that region as the currnet region. If Imprudence receives a DisableSimulator in this period, it quits. We are not restoring the full 5000ms delay since this brings back a bug where teleports permanently fail if an avatar tries to teleport back too quickly. This commit also sends the AgentCompleteMovement packet to the client before telling the source region to release its old agent, in order to further cut down any possibility of the DisableSimulator being recieved before the AgentMovementComplete. --- .../Framework/EntityTransfer/EntityTransferModule.cs | 9 +++++++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 14 ++++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index e47c339..cd588e5 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -30,7 +30,6 @@ using System.Collections.Generic; using System.Net; using System.Reflection; using System.Threading; - using OpenSim.Framework; using OpenSim.Framework.Capabilities; using OpenSim.Framework.Client; @@ -595,7 +594,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) { -// Thread.Sleep(5000); + // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before + // they regard the new region as the current region after receiving the AgentMovementComplete + // response. If close is sent before then, it will cause the viewer to quit instead. + // However, if this delay is longer, then a viewer can teleport back to this region and experience + // a failure because the old ScenePresence has not yet been cleaned up. + Thread.Sleep(2000); + sp.Close(); sp.Scene.IncomingCloseAgent(sp.UUID); } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index e5a9a99..91e6e5a 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1140,9 +1140,19 @@ namespace OpenSim.Region.Framework.Scenes bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); MakeRootAgent(AbsolutePosition, flying); + ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); + +// m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); if ((m_callbackURI != null) && !m_callbackURI.Equals("")) { + // We cannot sleep here since this would hold up the inbound packet processing thread, as + // CompleteMovement() is executed synchronously. However, it might be better to delay the release + // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete + // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this + // region as the current region, meaning that a close sent before then will fail the teleport. +// System.Threading.Thread.Sleep(2000); + m_log.DebugFormat( "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", client.Name, client.AgentId, m_callbackURI); @@ -1151,9 +1161,6 @@ namespace OpenSim.Region.Framework.Scenes m_callbackURI = null; } -// m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); - - ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); ValidateAndSendAppearanceAndAgentData(); // Create child agents in neighbouring regions @@ -1168,7 +1175,6 @@ namespace OpenSim.Region.Framework.Scenes friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); } - // m_log.DebugFormat( // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); -- cgit v1.1 From c9faf0df741c89ec92b09d54ab471b070e5a1dff Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 4 May 2012 01:12:56 +0100 Subject: Extend 'slow' request logging to other server outbound requests (forms, rest, async rest) as well as the existing logging on outbound OSD requests. Also prints out the first 100 chars of any slow request data since this can contain useful info (such as agent ID). --- OpenSim/Framework/WebUtil.cs | 273 ++++++++++++++++++++++++++++++------------- 1 file changed, 194 insertions(+), 79 deletions(-) diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index d2aa538..478d2a7 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs @@ -53,19 +53,36 @@ namespace OpenSim.Framework LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); - private static int m_requestNumber = 0; + /// + /// Request number for diagnostic purposes. + /// + public static int RequestNumber = 0; - // this is the header field used to communicate the local request id - // used for performance and debugging + /// + /// this is the header field used to communicate the local request id + /// used for performance and debugging + /// public const string OSHeaderRequestID = "opensim-request-id"; - // number of milliseconds a call can take before it is considered - // a "long" call for warning & debugging purposes + /// + /// Number of milliseconds a call can take before it is considered + /// a "long" call for warning & debugging purposes + /// public const int LongCallTime = 500; - // dictionary of end points + /// + /// The maximum length of any data logged because of a long request time. + /// + /// + /// This is to truncate any really large post data, such as an asset. In theory, the first section should + /// give us useful information about the call (which agent it relates to if applicable, etc.). + /// + public const int MaxRequestDiagLength = 100; + + /// + /// Dictionary of end points + /// private static Dictionary m_endpointSerializer = new Dictionary(); - private static object EndPointLock(string url) { @@ -128,12 +145,13 @@ namespace OpenSim.Framework private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed) { - int reqnum = m_requestNumber++; + int reqnum = RequestNumber++; // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); string errorMessage = "unknown error"; int tickstart = Util.EnvironmentTickCount(); int tickdata = 0; + string strBuffer = null; try { @@ -148,7 +166,7 @@ namespace OpenSim.Framework // If there is some input, write it into the request if (data != null) { - string strBuffer = OSDParser.SerializeJsonString(data); + strBuffer = OSDParser.SerializeJsonString(data); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer); if (compressed) @@ -208,11 +226,18 @@ namespace OpenSim.Framework } finally { - // This just dumps a warning for any operation that takes more than 100 ms int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); if (tickdiff > LongCallTime) - m_log.DebugFormat("[WEB UTIL]: osd request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing", - reqnum,url,method,tickdiff,tickdata); + m_log.InfoFormat( + "[OSD REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", + reqnum, + method, + url, + tickdiff, + tickdata, + strBuffer != null + ? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer) + : ""); } m_log.DebugFormat( @@ -290,17 +315,17 @@ namespace OpenSim.Framework private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout) { - int reqnum = m_requestNumber++; + int reqnum = RequestNumber++; string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown"; // m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method); string errorMessage = "unknown error"; int tickstart = Util.EnvironmentTickCount(); int tickdata = 0; + string queryString = null; try { - HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); request.Method = "POST"; request.Timeout = timeout; @@ -311,7 +336,7 @@ namespace OpenSim.Framework if (data != null) { - string queryString = BuildQueryString(data); + queryString = BuildQueryString(data); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString); request.ContentLength = buffer.Length; @@ -354,11 +379,19 @@ namespace OpenSim.Framework { int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); if (tickdiff > LongCallTime) - m_log.InfoFormat("[WEB UTIL]: form request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing", - reqnum,url,method,tickdiff,tickdata); + m_log.InfoFormat( + "[SERVICE FORM]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", + reqnum, + method, + url, + tickdiff, + tickdata, + queryString != null + ? (queryString.Length > MaxRequestDiagLength) ? queryString.Remove(MaxRequestDiagLength) : queryString + : ""); } - m_log.WarnFormat("[WEB UTIL]: <{0}> form request to {1} failed: {2}", reqnum, url, errorMessage); + m_log.WarnFormat("[SERVICE FORM]: <{0}> form request to {1} failed: {2}", reqnum, url, errorMessage); return ErrorResponseMap(errorMessage); } @@ -639,8 +672,6 @@ namespace OpenSim.Framework return new string[0]; } - - } public static class AsynchronousRestObjectRequester @@ -663,6 +694,12 @@ namespace OpenSim.Framework public static void MakeRequest(string verb, string requestUrl, TRequest obj, Action action) { + int reqnum = WebUtil.RequestNumber++; + // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); + + int tickstart = Util.EnvironmentTickCount(); + int tickdata = 0; + // m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl); Type type = typeof(TRequest); @@ -673,12 +710,13 @@ namespace OpenSim.Framework XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); request.Method = verb; + MemoryStream buffer = null; if (verb == "POST") { request.ContentType = "text/xml"; - MemoryStream buffer = new MemoryStream(); + buffer = new MemoryStream(); XmlWriterSettings settings = new XmlWriterSettings(); settings.Encoding = Encoding.UTF8; @@ -700,6 +738,9 @@ namespace OpenSim.Framework requestStream.Write(buffer.ToArray(), 0, length); requestStream.Close(); + // capture how much time was spent writing + tickdata = Util.EnvironmentTickCountSubtract(tickstart); + request.BeginGetResponse(delegate(IAsyncResult ar) { response = request.EndGetResponse(ar); @@ -725,88 +766,108 @@ namespace OpenSim.Framework }, null); }, null); - - - return; } - - request.BeginGetResponse(delegate(IAsyncResult res2) + else { - try + request.BeginGetResponse(delegate(IAsyncResult res2) { - // If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't - // documented in MSDN - response = request.EndGetResponse(res2); - - Stream respStream = null; try { - respStream = response.GetResponseStream(); - deserial = (TResponse)deserializer.Deserialize(respStream); - } - catch (System.InvalidOperationException) - { - } - finally - { - respStream.Close(); - response.Close(); + // If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't + // documented in MSDN + response = request.EndGetResponse(res2); + + Stream respStream = null; + try + { + respStream = response.GetResponseStream(); + deserial = (TResponse)deserializer.Deserialize(respStream); + } + catch (System.InvalidOperationException) + { + } + finally + { + respStream.Close(); + response.Close(); + } } - } - catch (WebException e) - { - if (e.Status == WebExceptionStatus.ProtocolError) + catch (WebException e) { - if (e.Response is HttpWebResponse) + if (e.Status == WebExceptionStatus.ProtocolError) { - HttpWebResponse httpResponse = (HttpWebResponse)e.Response; - - if (httpResponse.StatusCode != HttpStatusCode.NotFound) + if (e.Response is HttpWebResponse) { - // We don't appear to be handling any other status codes, so log these feailures to that - // people don't spend unnecessary hours hunting phantom bugs. - m_log.DebugFormat( - "[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}", - verb, requestUrl, httpResponse.StatusCode); + HttpWebResponse httpResponse = (HttpWebResponse)e.Response; + + if (httpResponse.StatusCode != HttpStatusCode.NotFound) + { + // We don't appear to be handling any other status codes, so log these feailures to that + // people don't spend unnecessary hours hunting phantom bugs. + m_log.DebugFormat( + "[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}", + verb, requestUrl, httpResponse.StatusCode); + } } } + else + { + m_log.ErrorFormat( + "[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}", + verb, requestUrl, e.Status, e.Message); + } } - else + catch (Exception e) { m_log.ErrorFormat( - "[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}", - verb, requestUrl, e.Status, e.Message); + "[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}", + verb, requestUrl, e.Message, e.StackTrace); } - } - catch (Exception e) - { - m_log.ErrorFormat( - "[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}", - verb, requestUrl, e.Message, e.StackTrace); - } + + // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString()); + + try + { + action(deserial); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}", + verb, requestUrl, e.Message, e.StackTrace); + } + + }, null); + } - // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString()); + int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); + if (tickdiff > WebUtil.LongCallTime) + { + string originalRequest = null; - try - { - action(deserial); - } - catch (Exception e) + if (buffer != null) { - m_log.ErrorFormat( - "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}", - verb, requestUrl, e.Message, e.StackTrace); + originalRequest = Encoding.UTF8.GetString(buffer.ToArray()); + + if (originalRequest.Length > WebUtil.MaxRequestDiagLength) + originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength); } - }, null); + m_log.InfoFormat( + "[ASYNC REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", + reqnum, + verb, + requestUrl, + tickdiff, + tickdata, + originalRequest); + } } } public static class SynchronousRestFormsRequester { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// /// Perform a synchronous REST request. @@ -820,6 +881,12 @@ namespace OpenSim.Framework /// the request. You'll want to make sure you deal with this as they're not uncommon public static string MakeRequest(string verb, string requestUrl, string obj) { + int reqnum = WebUtil.RequestNumber++; + // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); + + int tickstart = Util.EnvironmentTickCount(); + int tickdata = 0; + WebRequest request = WebRequest.Create(requestUrl); request.Method = verb; string respstring = String.Empty; @@ -855,6 +922,9 @@ namespace OpenSim.Framework { if (requestStream != null) requestStream.Close(); + + // capture how much time was spent writing + tickdata = Util.EnvironmentTickCountSubtract(tickstart); } } @@ -893,6 +963,18 @@ namespace OpenSim.Framework m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving {0} {1}", verb, requestUrl); } } + + int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); + if (tickdiff > WebUtil.LongCallTime) + m_log.InfoFormat( + "[FORMS]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", + reqnum, + verb, + requestUrl, + tickdiff, + tickdata, + obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj); + return respstring; } } @@ -915,17 +997,24 @@ namespace OpenSim.Framework /// the request. You'll want to make sure you deal with this as they're not uncommon public static TResponse MakeRequest(string verb, string requestUrl, TRequest obj) { + int reqnum = WebUtil.RequestNumber++; + // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); + + int tickstart = Util.EnvironmentTickCount(); + int tickdata = 0; + Type type = typeof(TRequest); TResponse deserial = default(TResponse); WebRequest request = WebRequest.Create(requestUrl); request.Method = verb; + MemoryStream buffer = null; if ((verb == "POST") || (verb == "PUT")) { request.ContentType = "text/xml"; - MemoryStream buffer = new MemoryStream(); + buffer = new MemoryStream(); XmlWriterSettings settings = new XmlWriterSettings(); settings.Encoding = Encoding.UTF8; @@ -958,6 +1047,9 @@ namespace OpenSim.Framework { if (requestStream != null) requestStream.Close(); + + // capture how much time was spent writing + tickdata = Util.EnvironmentTickCountSubtract(tickstart); } } @@ -1005,6 +1097,29 @@ namespace OpenSim.Framework verb, requestUrl, e.Message, e.StackTrace); } + int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); + if (tickdiff > WebUtil.LongCallTime) + { + string originalRequest = null; + + if (buffer != null) + { + originalRequest = Encoding.UTF8.GetString(buffer.ToArray()); + + if (originalRequest.Length > WebUtil.MaxRequestDiagLength) + originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength); + } + + m_log.InfoFormat( + "[SynchronousRestObjectRequester]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", + reqnum, + verb, + requestUrl, + tickdiff, + tickdata, + originalRequest); + } + return deserial; } } -- cgit v1.1 From fb99ee67743dddd75c2b65039f227188f46cc389 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 4 May 2012 01:16:56 +0100 Subject: minor: Tweak BaseHttpServer message to make it clear that this relates to slow handling of inbound requests. --- OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 4ea4a1a..6fa36b5 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -677,7 +677,7 @@ namespace OpenSim.Framework.Servers.HttpServer if (tickdiff > 3000) { m_log.InfoFormat( - "[BASE HTTP SERVER]: slow {0} for {1} {2} {3} from {4} took {5} ms", + "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms", requestMethod, uriString, requestHandler != null ? requestHandler.Name : "", -- cgit v1.1 From cccef2e56dc8b02ccd83fb1c832e4ce026cdcaf9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 4 May 2012 19:21:43 +0100 Subject: Calculate the Daylight Savings Time information sent to the viewer based on US Pacific Standard Time rather than whatever timezone the login server is set to. This is because the viewer doesn't receive a timezone from the server but bases its displays on Pacific Standard Time. However, it still expects to receive notification from the server as to whether or not Daylight Savings Time for PST is in operation. This commit introduces a new DSTZone setting in the [LoginService] config setting that accepts a list of timezone names valid across different platforms to calculate Pacific DST. If you need the old behaviour of calculating DST based on the local timezone of the server running the login service, then please override DSTZone with "local". A mailing list announcement will be made later. Thanks to Olivier Van Helden and Gudule Lapointe for determining this behaviour and providing this patch. From http://opensimulator.org/mantis/view.php?id=5972 --- OpenSim/Services/LLLoginService/LLLoginResponse.cs | 43 +++++++++++++++++++++- OpenSim/Services/LLLoginService/LLLoginService.cs | 17 +++++++-- bin/Robust.HG.ini.example | 12 ++++++ bin/Robust.ini.example | 21 +++++++++++ bin/config-include/Standalone.ini | 12 ++++++ 5 files changed, 100 insertions(+), 5 deletions(-) diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs index 01de159..6b3bc84 100644 --- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs +++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs @@ -226,7 +226,8 @@ namespace OpenSim.Services.LLLoginService public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, GridUserInfo pinfo, GridRegion destination, List invSkel, FriendInfo[] friendsList, ILibraryService libService, string where, string startlocation, Vector3 position, Vector3 lookAt, List gestures, string message, - GridRegion home, IPEndPoint clientIP, string mapTileURL, string profileURL, string openIDURL, string searchURL, string currency) + GridRegion home, IPEndPoint clientIP, string mapTileURL, string profileURL, string openIDURL, string searchURL, string currency, + string DSTZone) : this() { FillOutInventoryData(invSkel, libService); @@ -255,7 +256,45 @@ namespace OpenSim.Services.LLLoginService FillOutRegionData(destination); FillOutSeedCap(aCircuit, destination, clientIP); - + + switch (DSTZone) + { + case "none": + DST = "N"; + break; + case "local": + DST = TimeZone.CurrentTimeZone.IsDaylightSavingTime(DateTime.Now) ? "Y" : "N"; + break; + default: + TimeZoneInfo dstTimeZone = null; + string[] tzList = DSTZone.Split(';'); + + foreach (string tzName in tzList) + { + try + { + dstTimeZone = TimeZoneInfo.FindSystemTimeZoneById(tzName); + } + catch (Exception e) + { + continue; + } + break; + } + + if (dstTimeZone == null) + { + m_log.WarnFormat( + "[LLOGIN RESPONSE]: No valid timezone found for DST in {0}, falling back to system time.", tzList); + DST = TimeZone.CurrentTimeZone.IsDaylightSavingTime(DateTime.Now) ? "Y" : "N"; + } + else + { + DST = dstTimeZone.IsDaylightSavingTime(DateTime.Now) ? "Y" : "N"; + } + + break; + } } private void FillOutInventoryData(List invSkel, ILibraryService libService) diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index db8a9cb..9acba11 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -82,6 +82,8 @@ namespace OpenSim.Services.LLLoginService protected string m_AllowedClients; protected string m_DeniedClients; + protected string m_DSTZone; + IConfig m_LoginServerConfig; // IConfig m_ClientsConfig; @@ -118,6 +120,8 @@ namespace OpenSim.Services.LLLoginService m_AllowedClients = m_LoginServerConfig.GetString("AllowedClients", string.Empty); m_DeniedClients = m_LoginServerConfig.GetString("DeniedClients", string.Empty); + m_DSTZone = m_LoginServerConfig.GetString("DSTZone", "America/Los_Angeles;Pacific Standard Time"); + // Clean up some of these vars if (m_MapTileURL != String.Empty) { @@ -240,6 +244,7 @@ namespace OpenSim.Services.LLLoginService m_log.InfoFormat("[LLOGIN SERVICE]: Login request for {0} {1} at {2} using viewer {3}, channel {4}, IP {5}, Mac {6}, Id0 {7}", firstName, lastName, startLocation, clientVersion, channel, clientIP.Address.ToString(), mac, id0); + try { // @@ -416,8 +421,11 @@ namespace OpenSim.Services.LLLoginService // // Finally, fill out the response and return it // - LLLoginResponse response = new LLLoginResponse(account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService, - where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP, m_MapTileURL, m_ProfileURL, m_OpenIDURL, m_SearchURL, m_Currency); + LLLoginResponse response + = new LLLoginResponse( + account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService, + where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP, + m_MapTileURL, m_ProfileURL, m_OpenIDURL, m_SearchURL, m_Currency, m_DSTZone); m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to client."); return response; @@ -431,7 +439,10 @@ namespace OpenSim.Services.LLLoginService } } - protected GridRegion FindDestination(UserAccount account, UUID scopeID, GridUserInfo pinfo, UUID sessionID, string startLocation, GridRegion home, out GridRegion gatekeeper, out string where, out Vector3 position, out Vector3 lookAt, out TeleportFlags flags) + protected GridRegion FindDestination( + UserAccount account, UUID scopeID, GridUserInfo pinfo, UUID sessionID, string startLocation, + GridRegion home, out GridRegion gatekeeper, + out string where, out Vector3 position, out Vector3 lookAt, out TeleportFlags flags) { flags = TeleportFlags.ViaLogin; diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index be75407..00e2fd7 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -275,6 +275,18 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ;AllowedClients = "" ;DeniedClients = "" + ;# {DSTZone} {} {Override Daylight Saving Time rules} {* none local} "America/Los_Angeles;Pacific Standard Time" + ;; Viewers do not receive timezone information from the server - almost all (?) default to Pacific Standard Time + ;; However, they do rely on the server to tell them whether it's Daylight Saving Time or not. + ;; Hence, calculating DST based on a different timezone can result in a misleading viewer display and inconsistencies between grids. + ;; By default, this setting uses various timezone names to calculate DST with regards to the viewer's standard PST. + ;; Options are + ;; "none" no DST + ;; "local" use the server's only timezone to calculate DST. This is previous OpenSimulator behaviour. + ;; "America/Los_Angeles;Pacific Standard Time" use these timezone names to look up Daylight savings. + ;; 'America/Los_Angeles' is used on Linux/Mac systems whilst 'Pacific Standard Time' is used on Windows + DSTZone = "America/Los_Angeles;Pacific Standard Time" + [MapImageService] LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" ; Set this if you want to change the default diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index 582af27..1c04ab5 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -250,6 +250,27 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ;AllowedClients = "" ;DeniedClients = "" + ;# {DSTZone} {} {Override Daylight Saving Time rules} {* none local} "America/Los_Angeles;Pacific Standard Time" + ;; Viewers do not listen to timezone sent by the server. They use Pacific Standard Time instead, + ;; but rely on the server to calculate Daylight Saving Time. Sending another DST than US Pacific + ;; would result in time inconsistencies between grids (during summer and around DST transition period) + ;; default let OpenSim calculate US Pacific DST + ;; "none" disable DST (equivallent to "local" with system set to GMT) + ;; "local" force legacy behaviour (using local system time to calculate DST) + ; DSTZone = "America/Los_Angeles;Pacific Standard Time" + + ;# {DSTZone} {} {Override Daylight Saving Time rules} {* none local} "America/Los_Angeles;Pacific Standard Time" + ;; Viewers do not receive timezone information from the server - almost all (?) default to Pacific Standard Time + ;; However, they do rely on the server to tell them whether it's Daylight Saving Time or not. + ;; Hence, calculating DST based on a different timezone can result in a misleading viewer display and inconsistencies between grids. + ;; By default, this setting uses various timezone names to calculate DST with regards to the viewer's standard PST. + ;; Options are + ;; "none" no DST + ;; "local" use the server's only timezone to calculate DST. This is previous OpenSimulator behaviour. + ;; "America/Los_Angeles;Pacific Standard Time" use these timezone names to look up Daylight savings. + ;; 'America/Los_Angeles' is used on Linux/Mac systems whilst 'Pacific Standard Time' is used on Windows + DSTZone = "America/Los_Angeles;Pacific Standard Time" + [MapImageService] LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" ; Set this if you want to change the default diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini index d307387..74d9d2e 100644 --- a/bin/config-include/Standalone.ini +++ b/bin/config-include/Standalone.ini @@ -95,6 +95,18 @@ WelcomeMessage = "Welcome, Avatar!" + ;# {DSTZone} {} {Override Daylight Saving Time rules} {* none local} "America/Los_Angeles;Pacific Standard Time" + ;; Viewers do not receive timezone information from the server - almost all (?) default to Pacific Standard Time + ;; However, they do rely on the server to tell them whether it's Daylight Saving Time or not. + ;; Hence, calculating DST based on a different timezone can result in a misleading viewer display and inconsistencies between grids. + ;; By default, this setting uses various timezone names to calculate DST with regards to the viewer's standard PST. + ;; Options are + ;; "none" no DST + ;; "local" use the server's only timezone to calculate DST. This is previous OpenSimulator behaviour. + ;; "America/Los_Angeles;Pacific Standard Time" use these timezone names to look up Daylight savings. + ;; 'America/Los_Angeles' is used on Linux/Mac systems whilst 'Pacific Standard Time' is used on Windows + DSTZone = "America/Los_Angeles;Pacific Standard Time" + [MapImageService] LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" ; in minutes -- cgit v1.1 From ad23774433b55e0cfbfc50208b247f0c3f41e8ea Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 23 Apr 2012 18:36:36 +0300 Subject: Allow deleting folders even if they're not in the Trash The functions DeleteFolders() and PurgeFolder() still work as before, i.e. they only allow deleting folders that are in the Trash. However, the functions DeleteFoldersEx() and PurgeFolderEx() can now be used to delete any folder. --- .../Services/InventoryService/XInventoryService.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 0e7a358..37a6a42 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -364,6 +364,11 @@ namespace OpenSim.Services.InventoryService // public virtual bool DeleteFolders(UUID principalID, List folderIDs) { + return DeleteFoldersEx(principalID, folderIDs, true); + } + + public bool DeleteFoldersEx(UUID principalID, List folderIDs, bool onlyIfTrash) + { if (!m_AllowDelete) return false; @@ -371,11 +376,12 @@ namespace OpenSim.Services.InventoryService // foreach (UUID id in folderIDs) { - if (!ParentIsTrash(id)) + if (onlyIfTrash && !ParentIsTrash(id)) continue; + //m_log.InfoFormat("[XINVENTORY SERVICE]: Delete folder {0}", id); InventoryFolderBase f = new InventoryFolderBase(); f.ID = id; - PurgeFolder(f); + PurgeFolderEx(f, onlyIfTrash); m_Database.DeleteFolders("folderID", id.ToString()); } @@ -384,10 +390,15 @@ namespace OpenSim.Services.InventoryService public virtual bool PurgeFolder(InventoryFolderBase folder) { + return PurgeFolderEx(folder, true); + } + + private bool PurgeFolderEx(InventoryFolderBase folder, bool onlyIfTrash) + { if (!m_AllowDelete) return false; - if (!ParentIsTrash(folder.ID)) + if (onlyIfTrash && !ParentIsTrash(folder.ID)) return false; XInventoryFolder[] subFolders = m_Database.GetFolders( @@ -396,7 +407,7 @@ namespace OpenSim.Services.InventoryService foreach (XInventoryFolder x in subFolders) { - PurgeFolder(ConvertToOpenSim(x)); + PurgeFolderEx(ConvertToOpenSim(x), onlyIfTrash); m_Database.DeleteFolders("folderID", x.folderID.ToString()); } -- cgit v1.1 From e83bc049dffba51a4d739d150cbd82a68453a0c6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 4 May 2012 20:37:21 +0100 Subject: refactor: Rename new DeleteFoldersEx/PurgeFoldersEx methods to DeleteFolders/PurgeFolders overloads as previously discussed with Oren - I think this makes more sense on balance These overloads are not publicly available on core connectors or IInventoryService. --- OpenSim/Services/InventoryService/XInventoryService.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 37a6a42..15156d0 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -52,6 +52,7 @@ namespace OpenSim.Services.InventoryService : this(config, "InventoryService") { } + public XInventoryService(IConfigSource config, string configName) : base(config) { if (configName != string.Empty) @@ -364,10 +365,10 @@ namespace OpenSim.Services.InventoryService // public virtual bool DeleteFolders(UUID principalID, List folderIDs) { - return DeleteFoldersEx(principalID, folderIDs, true); + return DeleteFolders(principalID, folderIDs, true); } - public bool DeleteFoldersEx(UUID principalID, List folderIDs, bool onlyIfTrash) + public virtual bool DeleteFolders(UUID principalID, List folderIDs, bool onlyIfTrash) { if (!m_AllowDelete) return false; @@ -381,7 +382,7 @@ namespace OpenSim.Services.InventoryService //m_log.InfoFormat("[XINVENTORY SERVICE]: Delete folder {0}", id); InventoryFolderBase f = new InventoryFolderBase(); f.ID = id; - PurgeFolderEx(f, onlyIfTrash); + PurgeFolder(f, onlyIfTrash); m_Database.DeleteFolders("folderID", id.ToString()); } @@ -390,10 +391,10 @@ namespace OpenSim.Services.InventoryService public virtual bool PurgeFolder(InventoryFolderBase folder) { - return PurgeFolderEx(folder, true); + return PurgeFolder(folder, true); } - private bool PurgeFolderEx(InventoryFolderBase folder, bool onlyIfTrash) + public virtual bool PurgeFolder(InventoryFolderBase folder, bool onlyIfTrash) { if (!m_AllowDelete) return false; @@ -407,7 +408,7 @@ namespace OpenSim.Services.InventoryService foreach (XInventoryFolder x in subFolders) { - PurgeFolderEx(ConvertToOpenSim(x), onlyIfTrash); + PurgeFolder(ConvertToOpenSim(x), onlyIfTrash); m_Database.DeleteFolders("folderID", x.folderID.ToString()); } -- cgit v1.1 From 6096a1f30ed7857b1dbacf152dba4f0aa7e6e1e9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 4 May 2012 20:53:30 +0100 Subject: Change LongCallTime on WebUtil to 3000, to match the time where request handling is considered "slow". This may be the wrong thing to do but stops lots of log spam in HG setups now that the monitoring is extended to other outgoing calls. LongCallTime may need to be made configurable. --- OpenSim/Framework/WebUtil.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index 478d2a7..2aa4af5 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs @@ -68,7 +68,7 @@ namespace OpenSim.Framework /// Number of milliseconds a call can take before it is considered /// a "long" call for warning & debugging purposes /// - public const int LongCallTime = 500; + public const int LongCallTime = 3000; /// /// The maximum length of any data logged because of a long request time. -- cgit v1.1 From 92fde6ed268f4c7357ca5ad96b967db0f0658446 Mon Sep 17 00:00:00 2001 From: Talun Date: Fri, 4 May 2012 19:37:13 +0100 Subject: Mantis 60004 problems with damage and llSetDamage. In damage enabled areas this patch - Deletes any objects that have damage set > 0 that deliver that damage to an avatar Stops Gods receiving damage, Stops volume detect objects causing damage Deletes NPCS when their helth reduces to zero Gradually "heals" damage to an avatar Resets health on going to a non damage area --- .../CoreModules/Avatar/Combat/CombatModule.cs | 17 +++++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 53 +++++++++++++++++++--- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs index 0babeb5..3a91465 100644 --- a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs @@ -96,6 +96,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule ScenePresence killingAvatar = null; // string killingAvatarMessage; + // check to see if it is an NPC and just remove it + INPCModule NPCmodule = deadAvatar.Scene.RequestModuleInterface(); + if (NPCmodule != null && NPCmodule.DeleteNPC(deadAvatar.UUID, deadAvatar.Scene)) + { + return; + } + if (killerObjectLocalID == 0) deadAvatarMessage = "You committed suicide!"; else @@ -145,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule catch (InvalidOperationException) { } - deadAvatar.Health = 100; + deadAvatar.setHealthWithUpdate(100.0f); deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient); } @@ -154,14 +161,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule try { ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); - - if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) + if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0 + || avatar.Scene.RegionInfo.RegionSettings.AllowDamage) { avatar.Invulnerable = false; } else { avatar.Invulnerable = true; + if (avatar.Health < 100.0f) + { + avatar.setHealthWithUpdate(100.0f); + } } } catch (Exception) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 91e6e5a..7e49a5e 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3312,23 +3312,53 @@ namespace OpenSim.Region.Framework.Scenes } } - if (Invulnerable) + // Gods do not take damage and Invulnerable is set depending on parcel/region flags + if (Invulnerable || GodLevel > 0) return; - + + // The following may be better in the ICombatModule + // probably tweaking of the values for ground and normal prim collisions will be needed float starthealth = Health; uint killerObj = 0; + SceneObjectPart part = null; foreach (uint localid in coldata.Keys) { - SceneObjectPart part = Scene.GetSceneObjectPart(localid); - - if (part != null && part.ParentGroup.Damage != -1.0f) - Health -= part.ParentGroup.Damage; + if (localid == 0) + { + part = null; + } + else + { + part = Scene.GetSceneObjectPart(localid); + } + if (part != null) + { + // Ignore if it has been deleted or volume detect + if (!part.ParentGroup.IsDeleted && !part.ParentGroup.IsVolumeDetect) + { + if (part.ParentGroup.Damage > 0.0f) + { + // Something with damage... + Health -= part.ParentGroup.Damage; + part.ParentGroup.Scene.DeleteSceneObject(part.ParentGroup, false); + } + else + { + // An ordinary prim + if (coldata[localid].PenetrationDepth >= 0.10f) + Health -= coldata[localid].PenetrationDepth * 5.0f; + } + } + } else { - if (coldata[localid].PenetrationDepth >= 0.10f) + // 0 is the ground + // what about collisions with other avatars? + if (localid == 0 && coldata[localid].PenetrationDepth >= 0.10f) Health -= coldata[localid].PenetrationDepth * 5.0f; } + if (Health <= 0.0f) { if (localid != 0) @@ -3344,7 +3374,16 @@ namespace OpenSim.Region.Framework.Scenes ControllingClient.SendHealth(Health); } if (Health <= 0) + { m_scene.EventManager.TriggerAvatarKill(killerObj, this); + } + if (starthealth == Health && Health < 100.0f) + { + Health += 0.03f; + if (Health > 100.0f) + Health = 100.0f; + ControllingClient.SendHealth(Health); + } } } -- cgit v1.1 From c84ef57e5273ac2c8703c75406138c58f9c19d0f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 4 May 2012 21:04:42 +0100 Subject: minor: remove mono compiler warning --- OpenSim/Services/LLLoginService/LLLoginResponse.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs index 6b3bc84..9ec744f 100644 --- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs +++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs @@ -275,7 +275,7 @@ namespace OpenSim.Services.LLLoginService { dstTimeZone = TimeZoneInfo.FindSystemTimeZoneById(tzName); } - catch (Exception e) + catch { continue; } -- cgit v1.1 From da4819a170071d2acae309606c4ac2cf9f772a39 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 4 May 2012 22:11:25 +0100 Subject: Temporarily add debug log lines to lsl url request and release To help with http://opensimulator.org/mantis/view.php?id=5993 --- OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 93e75b3..d58fc0f 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -146,6 +146,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp public void Close() { } + public UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID) { UUID urlcode = UUID.Random(); @@ -175,6 +176,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp uri, new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); + m_log.DebugFormat( + "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", + uri, itemID, host.Name, host.LocalId); + engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); } @@ -217,6 +222,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp uri, new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); + m_log.DebugFormat( + "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", + uri, itemID, host.Name, host.LocalId); + engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); } @@ -237,6 +246,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp foreach (UUID req in data.requests.Keys) m_RequestMap.Remove(req); + m_log.DebugFormat( + "[URL MODULE]: Releasing url {0} for {1} in {2}", + url, data.itemID, data.hostID); + RemoveUrl(data); m_UrlMap.Remove(url); } -- cgit v1.1 From dec6ad2933f75d4ac475a5e1c4302fe758c60d6d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 4 May 2012 22:57:33 +0100 Subject: Don't try and update the access time of a file that is actively being cached. This may cause IOErrors on Windows. Aims to help with http://opensimulator.org/mantis/view.php?id=6003 --- OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 389fb7b..a25976d 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -261,10 +261,14 @@ namespace Flotsam.RegionModules.AssetCache try { - // If the file is already cached, don't cache it, just touch it so access time is updated + // If the file is already cached just update access time. if (File.Exists(filename)) { - File.SetLastAccessTime(filename, DateTime.Now); + lock (m_CurrentlyWriting) + { + if (!m_CurrentlyWriting.Contains(filename)) + File.SetLastAccessTime(filename, DateTime.Now); + } } else { -- cgit v1.1 From e18686528ea09d72dd75da341da7bbb6f1fad5aa Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 4 May 2012 23:03:33 +0100 Subject: Use the more efficient HashSet instead of List for FlotasmAssetCache.m_CurrentlyWriting --- OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index a25976d..dd6026b 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -83,7 +83,7 @@ namespace Flotsam.RegionModules.AssetCache private Dictionary m_CurrentlyWriting = new Dictionary(); private int m_WaitOnInprogressTimeout = 3000; #else - private List m_CurrentlyWriting = new List(); + private HashSet m_CurrentlyWriting = new HashSet(); #endif private bool m_FileCacheEnabled = true; -- cgit v1.1 From 01b00ad0d57d828028379875a382965b44073497 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 5 May 2012 00:29:14 +0100 Subject: Fire the scripting changed event with CHANGED_OWNER when an object that has changed owners is rezzed. This needs to occur after the script is resumed rather than before, when the event is just dropped. Addresses http://opensimulator.org/mantis/view.php?id=5890 and http://opensimulator.org/mantis/view.php?id=5952 --- OpenSim/Framework/TaskInventoryItem.cs | 16 +++++++++++++--- .../Avatar/Attachments/AttachmentsModule.cs | 18 +++++++++--------- .../Region/CoreModules/World/Land/PrimCountModule.cs | 1 - .../Framework/Scenes/SceneObjectPartInventory.cs | 10 ++++++++-- 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/OpenSim/Framework/TaskInventoryItem.cs b/OpenSim/Framework/TaskInventoryItem.cs index d4bbbfb..362d365 100644 --- a/OpenSim/Framework/TaskInventoryItem.cs +++ b/OpenSim/Framework/TaskInventoryItem.cs @@ -26,6 +26,8 @@ */ using System; +using System.Reflection; +using log4net; using OpenMetaverse; namespace OpenSim.Framework @@ -35,6 +37,8 @@ namespace OpenSim.Framework /// public class TaskInventoryItem : ICloneable { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + /// /// XXX This should really be factored out into some constants class. /// @@ -331,12 +335,18 @@ namespace OpenSim.Framework } } - public bool OwnerChanged { - get { + public bool OwnerChanged + { + get + { return _ownerChanged; } - set { + set + { _ownerChanged = value; +// m_log.DebugFormat( +// "[TASK INVENTORY ITEM]: Owner changed set {0} for {1} {2} owned by {3}", +// _ownerChanged, Name, ItemID, OwnerID); } } diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 7200c4b..2e1948d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -527,9 +527,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments private void AttachToAgent( IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) { - // m_log.DebugFormat( - // "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", - // so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", +// so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); so.DetachFromBackup(); @@ -788,9 +788,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) { - // m_log.DebugFormat( - // "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", - // att.Name, sp.Name, AttachmentPt, itemID); +// m_log.DebugFormat( +// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", +// att.Name, sp.Name, AttachmentPt, itemID); if (UUID.Zero == itemID) { @@ -853,9 +853,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) { - // m_log.DebugFormat( - // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", - // objectLocalID, remoteClient.Name, AttachmentPt, silent); +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", +// objectLocalID, remoteClient.Name, AttachmentPt, silent); if (!Enabled) return; diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs index efede5c..b2f71d1 100644 --- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs @@ -126,7 +126,6 @@ namespace OpenSim.Region.CoreModules.World.Land // m_log.DebugFormat( // "[PRIM COUNT MODULE]: Ignoring OnParcelPrimCountAdd() for {0} on {1} since count is tainted", // obj.Name, m_Scene.RegionInfo.RegionName); - } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index aacad98..3734e03 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -1219,13 +1219,19 @@ namespace OpenSim.Region.Framework.Scenes { if (engine != null) { +// m_log.DebugFormat( +// "[PRIM INVENTORY]: Resuming script {0} {1} for {2}, OwnerChanged {3}", +// item.Name, item.ItemID, item.OwnerID, item.OwnerChanged); + + engine.ResumeScript(item.ItemID); + if (item.OwnerChanged) engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); + item.OwnerChanged = false; - engine.ResumeScript(item.ItemID); } } } } } -} +} \ No newline at end of file -- cgit v1.1 From 9317b888f99257ba2612cc8700ffa4055f25369e Mon Sep 17 00:00:00 2001 From: nebadon Date: Sat, 5 May 2012 13:49:10 -0700 Subject: testing new opensimulator.org hardware out to make sure git still works! --- CONTRIBUTORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 8a1141f..cb61931 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -205,3 +205,4 @@ In addition, we would like to thank: * The Mono Project * The NANT Developers * Microsoft (.NET, MSSQL-Adapters) +- -- cgit v1.1 From 531c52abe3e7397141f423d2617351d97cf3aa09 Mon Sep 17 00:00:00 2001 From: nebadon Date: Sat, 5 May 2012 13:59:40 -0700 Subject: test #2 --- CONTRIBUTORS.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index cb61931..d80ead8 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -205,4 +205,4 @@ In addition, we would like to thank: * The Mono Project * The NANT Developers * Microsoft (.NET, MSSQL-Adapters) -- +-- -- cgit v1.1 From 8d070cf47babb947fce4d938f820452d4bfb7ca2 Mon Sep 17 00:00:00 2001 From: nebadon Date: Sat, 5 May 2012 14:32:40 -0700 Subject: last test clean up the mess.. --- CONTRIBUTORS.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index d80ead8..1d20dff 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -205,4 +205,4 @@ In addition, we would like to thank: * The Mono Project * The NANT Developers * Microsoft (.NET, MSSQL-Adapters) --- + -- cgit v1.1 From 86dd5adceb08d6044471b85e4982f01f9318403d Mon Sep 17 00:00:00 2001 From: nebadon Date: Sat, 5 May 2012 14:42:33 -0700 Subject: one last test.. --- CONTRIBUTORS.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 1d20dff..49e6478 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -205,4 +205,4 @@ In addition, we would like to thank: * The Mono Project * The NANT Developers * Microsoft (.NET, MSSQL-Adapters) - +* -- cgit v1.1 From f19fe50629bfee151286da487ba58e0f35f78329 Mon Sep 17 00:00:00 2001 From: nebadon Date: Sat, 5 May 2012 14:45:53 -0700 Subject: never say last test!! --- CONTRIBUTORS.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 49e6478..1d20dff 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -205,4 +205,4 @@ In addition, we would like to thank: * The Mono Project * The NANT Developers * Microsoft (.NET, MSSQL-Adapters) -* + -- cgit v1.1 From c11b3760daee51ac32c78d7787771ec800573d3c Mon Sep 17 00:00:00 2001 From: nebadon Date: Sat, 5 May 2012 14:49:10 -0700 Subject: just another test :) --- CONTRIBUTORS.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 1d20dff..8350802 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -205,4 +205,4 @@ In addition, we would like to thank: * The Mono Project * The NANT Developers * Microsoft (.NET, MSSQL-Adapters) - +*x -- cgit v1.1 From b60f51dafc364435796718807d211a17bfc35e12 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 6 May 2012 19:21:54 +0100 Subject: Stop llSetPos from sending one update per child prim --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 2686004..05bea8d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2771,7 +2771,7 @@ namespace OpenSim.Region.Framework.Scenes //we need to do a terse update even if the move wasn't allowed // so that the position is reset in the client (the object snaps back) - ScheduleGroupForTerseUpdate(); + RootPart.ScheduleTerseUpdate(); } /// -- cgit v1.1 From b697d0e895dc7670e160188501da88a780455500 Mon Sep 17 00:00:00 2001 From: dahlia Date: Sun, 6 May 2012 23:54:50 -0700 Subject: add OS_NPC_RUNNING option to osNpcMoveToTarget() to allow running speed for moving NPCs --- OpenSim/Region/Framework/Interfaces/INPCModule.cs | 6 ++++-- OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 3 ++- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 3 ++- OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs | 1 + 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs index b4dc3c3..e071ea3 100644 --- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs +++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs @@ -113,9 +113,11 @@ namespace OpenSim.Region.Framework.Interfaces /// /// /// If true and the avatar is flying when it reaches the target, land. - /// + /// name="running"> + /// If true, NPC moves with running speed. /// True if the operation succeeded, false if there was no such agent or the agent was not an NPC - bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget); + /// + bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget, bool running = false); /// /// Stop the NPC's current movement. diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 3ac1eb1..541ad7d 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -169,7 +169,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC } } - public bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget) + public bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget, bool running = false) { lock (m_avatars) { @@ -183,6 +183,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget); sp.MoveToTarget(pos, noFly, landAtTarget); + sp.SetAlwaysRun = running; return true; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 0d4ea19..3659687 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2474,7 +2474,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api World, pos, (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0, - (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0); + (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0, + (options & ScriptBaseClass.OS_NPC_RUNNING) != 0); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index fd7c41e..2a28542 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -626,6 +626,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int OS_NPC_FLY = 0; public const int OS_NPC_NO_FLY = 1; public const int OS_NPC_LAND_AT_TARGET = 2; + public const int OS_NPC_RUNNING = 4; public const int OS_NPC_SIT_NOW = 0; -- cgit v1.1 From 4186fa10f0eba3628ef8222db2e4b0e2b69df5cd Mon Sep 17 00:00:00 2001 From: dahlia Date: Mon, 7 May 2012 00:08:56 -0700 Subject: remove default values from prior commit since mono cant deal with them --- OpenSim/Region/Framework/Interfaces/INPCModule.cs | 2 +- .../Region/OptionalModules/World/NPC/NPCModule.cs | 2 +- .../World/NPC/Tests/NPCModuleTests.cs | 4 ++-- .../Shared/Api/Implementation/OSSL_Api.cs | 2 +- bin/PrimMesher.dll | Bin 37376 -> 46592 bytes 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs index e071ea3..860483d 100644 --- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs +++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs @@ -117,7 +117,7 @@ namespace OpenSim.Region.Framework.Interfaces /// If true, NPC moves with running speed. /// True if the operation succeeded, false if there was no such agent or the agent was not an NPC /// - bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget, bool running = false); + bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget, bool running); /// /// Stop the NPC's current movement. diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 541ad7d..d3456ab 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -169,7 +169,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC } } - public bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget, bool running = false) + public bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget, bool running) { lock (m_avatars) { diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index a39257e..65dad2d 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -242,7 +242,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); Vector3 targetPos = startPos + new Vector3(0, 10, 0); - m_npcMod.MoveToTarget(npc.UUID, m_scene, targetPos, false, false); + m_npcMod.MoveToTarget(npc.UUID, m_scene, targetPos, false, false, false); Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); //Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0.7071068f, 0.7071068f))); @@ -267,7 +267,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests // Try a second movement startPos = npc.AbsolutePosition; targetPos = startPos + new Vector3(10, 0, 0); - m_npcMod.MoveToTarget(npc.UUID, m_scene, targetPos, false, false); + m_npcMod.MoveToTarget(npc.UUID, m_scene, targetPos, false, false, false); Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); // Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0, 1))); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 3659687..ed9a4e0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2449,7 +2449,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); - module.MoveToTarget(npcId, World, pos, false, true); + module.MoveToTarget(npcId, World, pos, false, true, false); } } diff --git a/bin/PrimMesher.dll b/bin/PrimMesher.dll index 249e91c..87022b7 100755 Binary files a/bin/PrimMesher.dll and b/bin/PrimMesher.dll differ -- cgit v1.1 From 40324553322d1cf211eec32041bad5a2dc197f6d Mon Sep 17 00:00:00 2001 From: dahlia Date: Mon, 7 May 2012 00:33:50 -0700 Subject: add a null check for Primitive.Sculpt in PrimitiveBaseShape constructor for OpenMetaverse.Primitive object --- OpenSim/Framework/PrimitiveBaseShape.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs index 1b6a1d2..76dcfca 100644 --- a/OpenSim/Framework/PrimitiveBaseShape.cs +++ b/OpenSim/Framework/PrimitiveBaseShape.cs @@ -241,10 +241,14 @@ namespace OpenSim.Framework m_textureEntry = prim.Textures.GetBytes(); - SculptEntry = (prim.Sculpt.Type != OpenMetaverse.SculptType.None); - SculptData = prim.Sculpt.GetBytes(); - SculptTexture = prim.Sculpt.SculptTexture; - SculptType = (byte)prim.Sculpt.Type; + if (prim.Sculpt != null) + { + SculptEntry = (prim.Sculpt.Type != OpenMetaverse.SculptType.None); + SculptData = prim.Sculpt.GetBytes(); + SculptTexture = prim.Sculpt.SculptTexture; + SculptType = (byte)prim.Sculpt.Type; + } + else SculptType = (byte)OpenMetaverse.SculptType.None; } [XmlIgnore] -- cgit v1.1 From cdf97ab3a654581fe5c3f29b1b3a6459c8c73378 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 7 May 2012 17:21:45 +0100 Subject: Fix a bug in FriendsModule.StatusNotify() where all subsequent friends would not be notified once a non-local friend was found. --- OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index fc6325d..98afbc9 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -498,7 +498,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends Util.FireAndForget( delegate { - m_log.DebugFormat("[FRIENDS MODULE]: Notifying {0} friends", friendList.Count); + m_log.DebugFormat( + "[FRIENDS MODULE]: Notifying {0} friends of {1} of online status {2}", + friendList.Count, agentID, online); + // Notify about this user status StatusNotify(friendList, agentID, online); } @@ -515,7 +518,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { // Try local if (LocalStatusNotification(userID, friendID, online)) - return; + continue; // The friend is not here [as root]. Let's forward. PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); @@ -523,11 +526,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { PresenceInfo friendSession = null; foreach (PresenceInfo pinfo in friendSessions) + { if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad { friendSession = pinfo; break; } + } if (friendSession != null) { -- cgit v1.1 From 5053506d88ac8b06be27ffb404bcc120e3f48241 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 7 May 2012 18:27:33 +0100 Subject: refactor: Instead of performing a ScenePresence lookup twice over LocateClientObject() and GetClientScene(), do the lookup just once in LocateClientObject() --- .../CoreModules/Avatar/Friends/FriendsModule.cs | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 98afbc9..24ec435 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -449,29 +449,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends /// public IClientAPI LocateClientObject(UUID agentID) { - Scene scene = GetClientScene(agentID); - if (scene != null) - { - ScenePresence presence = scene.GetScenePresence(agentID); - if (presence != null) - return presence.ControllingClient; - } - - return null; - } - - /// - /// Find the scene for an agent - /// - private Scene GetClientScene(UUID agentId) - { lock (m_Scenes) { foreach (Scene scene in m_Scenes) { - ScenePresence presence = scene.GetScenePresence(agentId); + ScenePresence presence = scene.GetScenePresence(agentID); if (presence != null && !presence.IsChildAgent) - return scene; + return presence.ControllingClient; } } -- cgit v1.1 From a82dc263abe5ef2a7221609da14f75d7026f9fbe Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 7 May 2012 19:05:21 +0100 Subject: For osGetGridNick(), osGetGridName(), osGetGridLoginURI() and osGetGridCustom(), try to read from the [GridInfoService] section on standalone rather than [GridInfo] [GridInfoService] is the section that's actually in bin/config-include/StandaloneCommon.ini.example --- .../ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index ed9a4e0..3b67966 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -128,6 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public const string GridInfoServiceConfigSectionName = "GridInfoService"; + internal IScriptEngine m_ScriptEngine; internal ILSL_Api m_LSL_Api = null; // get a reference to the LSL API so we can call methods housed there internal SceneObjectPart m_host; @@ -2032,8 +2034,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api string nick = String.Empty; IConfigSource config = m_ScriptEngine.ConfigSource; - if (config.Configs["GridInfo"] != null) - nick = config.Configs["GridInfo"].GetString("gridnick", nick); + if (config.Configs[GridInfoServiceConfigSectionName] != null) + nick = config.Configs[GridInfoServiceConfigSectionName].GetString("gridnick", nick); if (String.IsNullOrEmpty(nick)) nick = GridUserInfo(InfoType.Nick); @@ -2049,8 +2051,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api string name = String.Empty; IConfigSource config = m_ScriptEngine.ConfigSource; - if (config.Configs["GridInfo"] != null) - name = config.Configs["GridInfo"].GetString("gridname", name); + if (config.Configs[GridInfoServiceConfigSectionName] != null) + name = config.Configs[GridInfoServiceConfigSectionName].GetString("gridname", name); if (String.IsNullOrEmpty(name)) name = GridUserInfo(InfoType.Name); @@ -2066,8 +2068,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api string loginURI = String.Empty; IConfigSource config = m_ScriptEngine.ConfigSource; - if (config.Configs["GridInfo"] != null) - loginURI = config.Configs["GridInfo"].GetString("login", loginURI); + if (config.Configs[GridInfoServiceConfigSectionName] != null) + loginURI = config.Configs[GridInfoServiceConfigSectionName].GetString("login", loginURI); if (String.IsNullOrEmpty(loginURI)) loginURI = GridUserInfo(InfoType.Login); @@ -2114,8 +2116,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api string retval = String.Empty; IConfigSource config = m_ScriptEngine.ConfigSource; - if (config.Configs["GridInfo"] != null) - retval = config.Configs["GridInfo"].GetString(key, retval); + if (config.Configs[GridInfoServiceConfigSectionName] != null) + retval = config.Configs[GridInfoServiceConfigSectionName].GetString(key, retval); if (String.IsNullOrEmpty(retval)) retval = GridUserInfo(InfoType.Custom, key); -- cgit v1.1 From 65c88b2ff4e2616fa5c1d4c5e75298ed1eb1c0d8 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Sun, 29 Apr 2012 08:53:33 +0300 Subject: Better error handling if Load OAR or Save OAR fail --- .../CoreModules/World/Archiver/ArchiveReadRequest.cs | 20 ++++++++++++++++---- .../World/Archiver/ArchiveWriteRequestExecution.cs | 7 ++++++- .../World/Archiver/ArchiveWriteRequestPreparation.cs | 11 ++++++++++- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index a6dbaba..e360f93 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -200,8 +200,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver } catch (Exception e) { - m_log.ErrorFormat( - "[ARCHIVER]: Aborting load with error in archive file {0}. {1}", filePath, e); + m_log.Error( + String.Format("[ARCHIVER]: Aborting load with error in archive file {0} ", filePath), e); m_errorMessage += e.ToString(); m_scene.EventManager.TriggerOarFileLoaded(m_requestId, m_errorMessage); return; @@ -219,6 +219,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver { m_log.ErrorFormat("[ARCHIVER]: Failed to load {0} assets", failedAssetRestores); m_errorMessage += String.Format("Failed to load {0} assets", failedAssetRestores); + // Continue, because we allow the OAR to be loaded even if some assets fail } } @@ -228,8 +229,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver m_scene.DeleteAllSceneObjects(); } - LoadParcels(serialisedParcels); - LoadObjects(serialisedSceneObjects); + try + { + LoadParcels(serialisedParcels); + LoadObjects(serialisedSceneObjects); + } + catch (Exception e) + { + m_log.Error("[ARCHIVER]: Error loading parcels or objects ", e); + m_errorMessage += e.ToString(); + m_scene.EventManager.TriggerOarFileLoaded(m_requestId, m_errorMessage); + return; + } + m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs index c179a34..2b40a9e 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs @@ -87,6 +87,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver { Save(assetsFoundUuids, assetsNotFoundUuids); } + catch (Exception e) + { + m_scene.EventManager.TriggerOarFileSaved(m_requestId, e.ToString()); + throw; + } finally { m_archiveWriter.Close(); @@ -150,4 +155,4 @@ namespace OpenSim.Region.CoreModules.World.Archiver } } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index eabe46e..384d81b 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -124,6 +124,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver if (options.ContainsKey("noassets") && (bool)options["noassets"]) SaveAssets = false; + // Whether someone else (i.e., ReceivedAllAssets()) is responsible for calling TriggerOarFileSaved() when we're done + bool eventHandled = false; + try { Dictionary assetUuids = new Dictionary(); @@ -230,15 +233,21 @@ namespace OpenSim.Region.CoreModules.World.Archiver m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets); Util.FireAndForget(o => ar.Execute()); + eventHandled = true; } else { awre.ReceivedAllAssets(new List(), new List()); + eventHandled = true; } } - catch (Exception) + catch (Exception e) { m_saveStream.Close(); + + if (!eventHandled) + m_scene.EventManager.TriggerOarFileSaved(m_requestId, e.ToString()); + throw; } } -- cgit v1.1 From 15844da3af92fc6e874d6b2df8f5da3b490179ec Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 23 Apr 2012 15:27:04 +0300 Subject: Log the full exception when errors occur in BaseHttpServer --- .../Framework/Servers/HttpServer/BaseHttpServer.cs | 38 +++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 6fa36b5..d0463c8 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -356,7 +356,7 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (Exception e) { - m_log.ErrorFormat("[BASE HTTP SERVER]: OnRequest() failed with {0}{1}", e.Message, e.StackTrace); + m_log.Error(String.Format("[BASE HTTP SERVER]: OnRequest() failed: {0} ", e.Message), e); } } @@ -551,11 +551,11 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); } catch (IOException e) { - m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}. ", e.Message), e); } return; @@ -658,15 +658,15 @@ namespace OpenSim.Framework.Servers.HttpServer // // An alternative may be to turn off all response write exceptions on the HttpListener, but let's go // with the minimum first - m_log.WarnFormat("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e); + m_log.Warn(String.Format("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux ", e.Message), e); } catch (IOException e) { - m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}{1}", e.Message, e.StackTrace); + m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e); } catch (Exception e) { - m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}{1}", e.Message, e.StackTrace); + m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e); SendHTML500(response); } finally @@ -933,11 +933,11 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); } catch (IOException e) { - m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0} ", e.Message), e); } } return; @@ -970,11 +970,11 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); } catch (IOException e) { - m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0} ", e.Message), e); } } } @@ -1085,12 +1085,12 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (IOException e) { - m_log.WarnFormat("[BASE HTTP SERVER]: LLSD IOException {0}.", e); + m_log.Warn(String.Format("[BASE HTTP SERVER]: LLSD IOException {0} ", e.Message), e); } catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.WarnFormat("[BASE HTTP SERVER]: LLSD issue {0}.\nNOTE: this may be spurious on Linux.", e); + m_log.Warn(String.Format("[BASE HTTP SERVER]: LLSD issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); } } } @@ -1342,8 +1342,8 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException f) { // This has to be here to prevent a Linux/Mono crash - m_log.WarnFormat( - "[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", f); + m_log.Warn( + String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", f.Message), f); } } catch(Exception) @@ -1638,11 +1638,11 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); } catch (IOException e) { - m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0} ", e.Message), e); } } } @@ -1679,7 +1679,7 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); + m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); } } } @@ -1715,7 +1715,7 @@ namespace OpenSim.Framework.Servers.HttpServer catch (SocketException e) { // This has to be here to prevent a Linux/Mono crash - m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); + m_log.Warn(String.Format("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); } } } @@ -1794,7 +1794,7 @@ namespace OpenSim.Framework.Servers.HttpServer public void httpServerException(object source, Exception exception) { - m_log.ErrorFormat("[BASE HTTP SERVER]: {0} had an exception {1}", source.ToString(), exception.ToString()); + m_log.Error(String.Format("[BASE HTTP SERVER]: {0} had an exception: {1} ", source.ToString(), exception.Message), exception); /* if (HTTPDRunning)// && NotSocketErrors > 5) { -- cgit v1.1 From 5d1d47e1f9327c29ba26d231c8d18680d06cb1d9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 7 May 2012 20:01:17 +0100 Subject: Revert "Better error handling if Load OAR or Save OAR fail" This reverts commit 65c88b2ff4e2616fa5c1d4c5e75298ed1eb1c0d8. Yet again I accidentally committed something whilst evaluating it. --- .../CoreModules/World/Archiver/ArchiveReadRequest.cs | 20 ++++---------------- .../World/Archiver/ArchiveWriteRequestExecution.cs | 7 +------ .../World/Archiver/ArchiveWriteRequestPreparation.cs | 11 +---------- 3 files changed, 6 insertions(+), 32 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index e360f93..a6dbaba 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -200,8 +200,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver } catch (Exception e) { - m_log.Error( - String.Format("[ARCHIVER]: Aborting load with error in archive file {0} ", filePath), e); + m_log.ErrorFormat( + "[ARCHIVER]: Aborting load with error in archive file {0}. {1}", filePath, e); m_errorMessage += e.ToString(); m_scene.EventManager.TriggerOarFileLoaded(m_requestId, m_errorMessage); return; @@ -219,7 +219,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver { m_log.ErrorFormat("[ARCHIVER]: Failed to load {0} assets", failedAssetRestores); m_errorMessage += String.Format("Failed to load {0} assets", failedAssetRestores); - // Continue, because we allow the OAR to be loaded even if some assets fail } } @@ -229,19 +228,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver m_scene.DeleteAllSceneObjects(); } - try - { - LoadParcels(serialisedParcels); - LoadObjects(serialisedSceneObjects); - } - catch (Exception e) - { - m_log.Error("[ARCHIVER]: Error loading parcels or objects ", e); - m_errorMessage += e.ToString(); - m_scene.EventManager.TriggerOarFileLoaded(m_requestId, m_errorMessage); - return; - } - + LoadParcels(serialisedParcels); + LoadObjects(serialisedSceneObjects); m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs index 2b40a9e..c179a34 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs @@ -87,11 +87,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver { Save(assetsFoundUuids, assetsNotFoundUuids); } - catch (Exception e) - { - m_scene.EventManager.TriggerOarFileSaved(m_requestId, e.ToString()); - throw; - } finally { m_archiveWriter.Close(); @@ -155,4 +150,4 @@ namespace OpenSim.Region.CoreModules.World.Archiver } } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index 384d81b..eabe46e 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -124,9 +124,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver if (options.ContainsKey("noassets") && (bool)options["noassets"]) SaveAssets = false; - // Whether someone else (i.e., ReceivedAllAssets()) is responsible for calling TriggerOarFileSaved() when we're done - bool eventHandled = false; - try { Dictionary assetUuids = new Dictionary(); @@ -233,21 +230,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets); Util.FireAndForget(o => ar.Execute()); - eventHandled = true; } else { awre.ReceivedAllAssets(new List(), new List()); - eventHandled = true; } } - catch (Exception e) + catch (Exception) { m_saveStream.Close(); - - if (!eventHandled) - m_scene.EventManager.TriggerOarFileSaved(m_requestId, e.ToString()); - throw; } } -- cgit v1.1 From abbd050a13e2b4f174c37979b46cf83f6b2f62dc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 8 May 2012 21:31:35 +0100 Subject: Perform SceneGraph.DuplicateObject() under existing m_updateLock already used for link and delinking, in order to avoid race conditions. DuplicateObject() relies on source object having correct link numbers for the duration of the dupe. Both link and delink can change link numbers such that they are not consistent for short periods of time. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 164 ++++++++++++++------------ 1 file changed, 89 insertions(+), 75 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 67eb0fe..4815922 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -92,8 +92,12 @@ namespace OpenSim.Region.Framework.Scenes protected internal Dictionary SceneObjectGroupsByLocalPartID = new Dictionary(); /// - /// Lock to prevent object group update, linking and delinking operations from running concurrently. + /// Lock to prevent object group update, linking, delinking and duplication operations from running concurrently. /// + /// + /// These operations rely on the parts composition of the object. If allowed to run concurrently then race + /// conditions can occur. + /// private Object m_updateLock = new Object(); #endregion @@ -1844,96 +1848,106 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - public SceneObjectGroup DuplicateObject(uint originalPrimID, Vector3 offset, uint flags, UUID AgentID, UUID GroupID, Quaternion rot) + /// null if duplication fails, otherwise the duplicated object + public SceneObjectGroup DuplicateObject( + uint originalPrimID, Vector3 offset, uint flags, UUID AgentID, UUID GroupID, Quaternion rot) { -// m_log.DebugFormat( -// "[SCENE]: Duplication of object {0} at offset {1} requested by agent {2}", -// originalPrimID, offset, AgentID); - - SceneObjectGroup original = GetGroupByPrim(originalPrimID); - if (original != null) + Monitor.Enter(m_updateLock); + + try { - if (m_parentScene.Permissions.CanDuplicateObject( - original.PrimCount, original.UUID, AgentID, original.AbsolutePosition)) + // m_log.DebugFormat( + // "[SCENE]: Duplication of object {0} at offset {1} requested by agent {2}", + // originalPrimID, offset, AgentID); + + SceneObjectGroup original = GetGroupByPrim(originalPrimID); + if (original == null) { - SceneObjectGroup copy = original.Copy(true); - copy.AbsolutePosition = copy.AbsolutePosition + offset; + m_log.WarnFormat( + "[SCENEGRAPH]: Attempt to duplicate nonexistant prim id {0} by {1}", originalPrimID, AgentID); - if (original.OwnerID != AgentID) - { - copy.SetOwnerId(AgentID); - copy.SetRootPartOwner(copy.RootPart, AgentID, GroupID); + return null; + } - SceneObjectPart[] partList = copy.Parts; + if (!m_parentScene.Permissions.CanDuplicateObject( + original.PrimCount, original.UUID, AgentID, original.AbsolutePosition)) + return null; - if (m_parentScene.Permissions.PropagatePermissions()) - { - foreach (SceneObjectPart child in partList) - { - child.Inventory.ChangeInventoryOwner(AgentID); - child.TriggerScriptChangedEvent(Changed.OWNER); - child.ApplyNextOwnerPermissions(); - } - } + SceneObjectGroup copy = original.Copy(true); + copy.AbsolutePosition = copy.AbsolutePosition + offset; - copy.RootPart.ObjectSaleType = 0; - copy.RootPart.SalePrice = 10; - } + if (original.OwnerID != AgentID) + { + copy.SetOwnerId(AgentID); + copy.SetRootPartOwner(copy.RootPart, AgentID, GroupID); - // FIXME: This section needs to be refactored so that it just calls AddSceneObject() - Entities.Add(copy); - - lock (SceneObjectGroupsByFullID) - SceneObjectGroupsByFullID[copy.UUID] = copy; - - SceneObjectPart[] children = copy.Parts; - - lock (SceneObjectGroupsByFullPartID) - { - SceneObjectGroupsByFullPartID[copy.UUID] = copy; - foreach (SceneObjectPart part in children) - SceneObjectGroupsByFullPartID[part.UUID] = copy; - } - - lock (SceneObjectGroupsByLocalPartID) - { - SceneObjectGroupsByLocalPartID[copy.LocalId] = copy; - foreach (SceneObjectPart part in children) - SceneObjectGroupsByLocalPartID[part.LocalId] = copy; - } - // PROBABLE END OF FIXME - - // Since we copy from a source group that is in selected - // state, but the copy is shown deselected in the viewer, - // We need to clear the selection flag here, else that - // prim never gets persisted at all. The client doesn't - // think it's selected, so it will never send a deselect... - copy.IsSelected = false; - - m_numPrim += copy.Parts.Length; - - if (rot != Quaternion.Identity) + SceneObjectPart[] partList = copy.Parts; + + if (m_parentScene.Permissions.PropagatePermissions()) { - copy.UpdateGroupRotationR(rot); + foreach (SceneObjectPart child in partList) + { + child.Inventory.ChangeInventoryOwner(AgentID); + child.TriggerScriptChangedEvent(Changed.OWNER); + child.ApplyNextOwnerPermissions(); + } } - copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 1); - copy.HasGroupChanged = true; - copy.ScheduleGroupForFullUpdate(); - copy.ResumeScripts(); - - // required for physics to update it's position - copy.AbsolutePosition = copy.AbsolutePosition; + copy.RootPart.ObjectSaleType = 0; + copy.RootPart.SalePrice = 10; + } - return copy; + // FIXME: This section needs to be refactored so that it just calls AddSceneObject() + Entities.Add(copy); + + lock (SceneObjectGroupsByFullID) + SceneObjectGroupsByFullID[copy.UUID] = copy; + + SceneObjectPart[] children = copy.Parts; + + lock (SceneObjectGroupsByFullPartID) + { + SceneObjectGroupsByFullPartID[copy.UUID] = copy; + foreach (SceneObjectPart part in children) + SceneObjectGroupsByFullPartID[part.UUID] = copy; + } + + lock (SceneObjectGroupsByLocalPartID) + { + SceneObjectGroupsByLocalPartID[copy.LocalId] = copy; + foreach (SceneObjectPart part in children) + SceneObjectGroupsByLocalPartID[part.LocalId] = copy; + } + // PROBABLE END OF FIXME + + // Since we copy from a source group that is in selected + // state, but the copy is shown deselected in the viewer, + // We need to clear the selection flag here, else that + // prim never gets persisted at all. The client doesn't + // think it's selected, so it will never send a deselect... + copy.IsSelected = false; + + m_numPrim += copy.Parts.Length; + + if (rot != Quaternion.Identity) + { + copy.UpdateGroupRotationR(rot); } + + copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 1); + copy.HasGroupChanged = true; + copy.ScheduleGroupForFullUpdate(); + copy.ResumeScripts(); + + // required for physics to update it's position + copy.AbsolutePosition = copy.AbsolutePosition; + + return copy; } - else + finally { - m_log.WarnFormat("[SCENE]: Attempted to duplicate nonexistant prim id {0}", GroupID); + Monitor.Exit(m_updateLock); } - - return null; } /// -- cgit v1.1 From 01b78235db71994ba3e37bd6ea297bed7e4576b9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 8 May 2012 22:58:34 +0100 Subject: Instead of constantly looking up unchanging self item in script code, pass in self item on initialization. --- .../Region/ScriptEngine/Interfaces/IScriptApi.cs | 20 +- .../Shared/Api/Implementation/LSL_Api.cs | 244 +++++++++------------ .../Shared/Api/Implementation/LS_Api.cs | 4 +- .../Shared/Api/Implementation/MOD_Api.cs | 10 +- .../Shared/Api/Implementation/OSSL_Api.cs | 29 +-- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 2 +- .../Shared/Tests/LSL_ApiInventoryTests.cs | 9 +- .../ScriptEngine/Shared/Tests/LSL_ApiTest.cs | 3 +- .../Shared/Tests/OSSL_ApiAppearanceTest.cs | 8 +- .../ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs | 6 +- 10 files changed, 145 insertions(+), 190 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs index bb5bacc..cced522 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs @@ -27,17 +27,23 @@ using System; using OpenMetaverse; +using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; - namespace OpenSim.Region.ScriptEngine.Interfaces { public interface IScriptApi { - // - // Each API has an identifier, which is used to load the - // proper runtime assembly at load time. - // - void Initialize(IScriptEngine engine, SceneObjectPart part, uint localID, UUID item); + /// + /// Initialize the API + /// + /// + /// Each API has an identifier, which is used to load the + /// proper runtime assembly at load time. + /// /param> + /// + /// + /// + void Initialize(IScriptEngine engine, SceneObjectPart part, uint localID, TaskInventoryItem item); } -} +} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 704dfc3..e8e4dab 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -87,9 +87,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected uint m_localID; /// - /// The UUID of the item that hosts this script + /// The item that hosts this script /// - protected UUID m_itemID; + protected TaskInventoryItem m_item; protected bool throwErrorOnNotImplemented = true; protected AsyncCommandManager AsyncCommands = null; @@ -108,12 +108,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected Dictionary m_userInfoCache = new Dictionary(); - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) + public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, TaskInventoryItem item) { m_ScriptEngine = ScriptEngine; m_host = host; m_localID = localID; - m_itemID = itemID; + m_item = item; m_ScriptDelayFactor = m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); @@ -163,7 +163,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void state(string newState) { - m_ScriptEngine.SetState(m_itemID, newState); + m_ScriptEngine.SetState(m_item.ItemID, newState); } /// @@ -173,7 +173,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llResetScript() { m_host.AddScriptLPS(1); - m_ScriptEngine.ApiResetScript(m_itemID); + m_ScriptEngine.ApiResetScript(m_item.ItemID); } public void llResetOtherScript(string name) @@ -272,20 +272,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - /// - /// Get the inventory item that hosts ourselves. - /// - /// - /// FIXME: It would be far easier to pass in TaskInventoryItem rather than just m_itemID so that we don't need - /// to keep looking ourselves up. - /// - /// - protected TaskInventoryItem GetSelfInventoryItem() - { - lock (m_host.TaskInventory) - return m_host.TaskInventory[m_itemID]; - } - protected UUID InventoryKey(string name, int type) { m_host.AddScriptLPS(1); @@ -857,7 +843,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID.TryParse(ID, out keyID); IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); if (wComm != null) - return wComm.Listen(m_localID, m_itemID, m_host.UUID, channelID, name, keyID, msg); + return wComm.Listen(m_localID, m_item.ItemID, m_host.UUID, channelID, name, keyID, msg); else return -1; } @@ -867,7 +853,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); if (wComm != null) - wComm.ListenControl(m_itemID, number, active); + wComm.ListenControl(m_item.ItemID, number, active); } public void llListenRemove(int number) @@ -875,7 +861,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); if (wComm != null) - wComm.ListenRemove(m_itemID, number); + wComm.ListenRemove(m_item.ItemID, number); } public void llSensor(string name, string id, int type, double range, double arc) @@ -884,7 +870,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID keyID = UUID.Zero; UUID.TryParse(id, out keyID); - AsyncCommands.SensorRepeatPlugin.SenseOnce(m_localID, m_itemID, name, keyID, type, range, arc, m_host); + AsyncCommands.SensorRepeatPlugin.SenseOnce(m_localID, m_item.ItemID, name, keyID, type, range, arc, m_host); } public void llSensorRepeat(string name, string id, int type, double range, double arc, double rate) @@ -893,13 +879,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID keyID = UUID.Zero; UUID.TryParse(id, out keyID); - AsyncCommands.SensorRepeatPlugin.SetSenseRepeatEvent(m_localID, m_itemID, name, keyID, type, range, arc, rate, m_host); + AsyncCommands.SensorRepeatPlugin.SetSenseRepeatEvent(m_localID, m_item.ItemID, name, keyID, type, range, arc, rate, m_host); } public void llSensorRemove() { m_host.AddScriptLPS(1); - AsyncCommands.SensorRepeatPlugin.UnSetSenseRepeaterEvents(m_localID, m_itemID); + AsyncCommands.SensorRepeatPlugin.UnSetSenseRepeaterEvents(m_localID, m_item.ItemID); } public string resolveName(UUID objecUUID) @@ -940,7 +926,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String llDetectedName(int number) { m_host.AddScriptLPS(1); - DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); + DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); if (detectedParams == null) return String.Empty; return detectedParams.Name; @@ -949,7 +935,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String llDetectedKey(int number) { m_host.AddScriptLPS(1); - DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); + DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); if (detectedParams == null) return String.Empty; return detectedParams.Key.ToString(); @@ -958,7 +944,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String llDetectedOwner(int number) { m_host.AddScriptLPS(1); - DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); + DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); if (detectedParams == null) return String.Empty; return detectedParams.Owner.ToString(); @@ -967,7 +953,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llDetectedType(int number) { m_host.AddScriptLPS(1); - DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); + DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); if (detectedParams == null) return 0; return new LSL_Integer(detectedParams.Type); @@ -976,7 +962,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llDetectedPos(int number) { m_host.AddScriptLPS(1); - DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); + DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); if (detectedParams == null) return new LSL_Vector(); return detectedParams.Position; @@ -985,7 +971,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llDetectedVel(int number) { m_host.AddScriptLPS(1); - DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); + DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); if (detectedParams == null) return new LSL_Vector(); return detectedParams.Velocity; @@ -994,7 +980,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llDetectedGrab(int number) { m_host.AddScriptLPS(1); - DetectParams parms = m_ScriptEngine.GetDetectParams(m_itemID, number); + DetectParams parms = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); if (parms == null) return new LSL_Vector(0, 0, 0); @@ -1004,7 +990,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Rotation llDetectedRot(int number) { m_host.AddScriptLPS(1); - DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); + DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); if (detectedParams == null) return new LSL_Rotation(); return detectedParams.Rotation; @@ -1013,7 +999,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llDetectedGroup(int number) { m_host.AddScriptLPS(1); - DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); + DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); if (detectedParams == null) return new LSL_Integer(0); if (m_host.GroupID == detectedParams.Group) @@ -1024,7 +1010,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llDetectedLinkNumber(int number) { m_host.AddScriptLPS(1); - DetectParams parms = m_ScriptEngine.GetDetectParams(m_itemID, number); + DetectParams parms = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); if (parms == null) return new LSL_Integer(0); @@ -1037,7 +1023,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llDetectedTouchBinormal(int index) { m_host.AddScriptLPS(1); - DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index); + DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); if (detectedParams == null) return new LSL_Vector(); return detectedParams.TouchBinormal; @@ -1049,7 +1035,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llDetectedTouchFace(int index) { m_host.AddScriptLPS(1); - DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index); + DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); if (detectedParams == null) return new LSL_Integer(-1); return new LSL_Integer(detectedParams.TouchFace); @@ -1061,7 +1047,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llDetectedTouchNormal(int index) { m_host.AddScriptLPS(1); - DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index); + DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); if (detectedParams == null) return new LSL_Vector(); return detectedParams.TouchNormal; @@ -1073,7 +1059,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llDetectedTouchPos(int index) { m_host.AddScriptLPS(1); - DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index); + DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); if (detectedParams == null) return new LSL_Vector(); return detectedParams.TouchPos; @@ -1085,7 +1071,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llDetectedTouchST(int index) { m_host.AddScriptLPS(1); - DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index); + DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); if (detectedParams == null) return new LSL_Vector(-1.0, -1.0, 0.0); return detectedParams.TouchST; @@ -1097,7 +1083,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llDetectedTouchUV(int index) { m_host.AddScriptLPS(1); - DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index); + DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); if (detectedParams == null) return new LSL_Vector(-1.0, -1.0, 0.0); return detectedParams.TouchUV; @@ -2702,12 +2688,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - TaskInventoryItem item = GetSelfInventoryItem(); - - if (item.PermsGranter == UUID.Zero) + if (m_item.PermsGranter == UUID.Zero) return 0; - if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) { LSLError("No permissions to give money"); return 0; @@ -2890,7 +2874,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api sec = m_MinTimerInterval; m_host.AddScriptLPS(1); // Setting timer repeat - AsyncCommands.TimerPlugin.SetTimerEvent(m_localID, m_itemID, sec); + AsyncCommands.TimerPlugin.SetTimerEvent(m_localID, m_item.ItemID, sec); } public virtual void llSleep(double sec) @@ -2945,17 +2929,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llTakeControls(int controls, int accept, int pass_on) { - TaskInventoryItem item = GetSelfInventoryItem(); - - if (item.PermsGranter != UUID.Zero) + if (m_item.PermsGranter != UUID.Zero) { - ScenePresence presence = World.GetScenePresence(item.PermsGranter); + ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); if (presence != null) { - if ((item.PermsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) { - presence.RegisterControlEventsToScript(controls, accept, pass_on, m_localID, m_itemID); + presence.RegisterControlEventsToScript(controls, accept, pass_on, m_localID, m_item.ItemID); } } } @@ -2967,20 +2949,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - TaskInventoryItem item = GetSelfInventoryItem(); - - if (item.PermsGranter != UUID.Zero) + if (m_item.PermsGranter != UUID.Zero) { - ScenePresence presence = World.GetScenePresence(item.PermsGranter); + ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); if (presence != null) { - if ((item.PermsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) { // Unregister controls from Presence - presence.UnRegisterControlEventsToScript(m_localID, m_itemID); + presence.UnRegisterControlEventsToScript(m_localID, m_item.ItemID); // Remove Take Control permission. - item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS; + m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS; } } } @@ -3042,12 +3022,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // if (m_host.ParentGroup.RootPart.AttachmentPoint == 0) // return; - TaskInventoryItem item = GetSelfInventoryItem(); - - if (item.PermsGranter != m_host.OwnerID) + if (m_item.PermsGranter != m_host.OwnerID) return; - if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0) + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0) AttachToAvatar(attachmentPoint); } @@ -3058,12 +3036,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_host.ParentGroup.AttachmentPoint == 0) return; - TaskInventoryItem item = GetSelfInventoryItem(); - - if (item.PermsGranter != m_host.OwnerID) + if (m_item.PermsGranter != m_host.OwnerID) return; - if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0) + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0) DetachFromAvatar(); } @@ -3245,7 +3221,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); try { - m_ScriptEngine.SetMinEventDelay(m_itemID, delay); + m_ScriptEngine.SetMinEventDelay(m_item.ItemID, delay); } catch (NotImplementedException) { @@ -3298,14 +3274,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - TaskInventoryItem item = GetSelfInventoryItem(); - - if (item.PermsGranter == UUID.Zero) + if (m_item.PermsGranter == UUID.Zero) return; - if ((item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0) + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0) { - ScenePresence presence = World.GetScenePresence(item.PermsGranter); + ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); if (presence != null) { @@ -3323,21 +3297,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - TaskInventoryItem item = GetSelfInventoryItem(); - - if (item.PermsGranter == UUID.Zero) + if (m_item.PermsGranter == UUID.Zero) return; - if ((item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0) + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0) { UUID animID = new UUID(); if (!UUID.TryParse(anim, out animID)) { - animID=InventoryKey(anim); + animID = InventoryKey(anim); } - ScenePresence presence = World.GetScenePresence(item.PermsGranter); + ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); if (presence != null) { @@ -3373,7 +3345,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llGetStartParameter() { m_host.AddScriptLPS(1); - return m_ScriptEngine.GetStartParameter(m_itemID); + return m_ScriptEngine.GetStartParameter(m_item.ItemID); } public void llRequestPermissions(string agent, int perm) @@ -3383,16 +3355,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(agent, out agentID)) return; - TaskInventoryItem item = GetSelfInventoryItem(); - if (agentID == UUID.Zero || perm == 0) // Releasing permissions { llReleaseControls(); - item.PermsGranter = UUID.Zero; - item.PermsMask = 0; + m_item.PermsGranter = UUID.Zero; + m_item.PermsMask = 0; - m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( + m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( "run_time_permissions", new Object[] { new LSL_Integer(0) }, new DetectParams[0])); @@ -3400,7 +3370,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; } - if (item.PermsGranter != agentID || (perm & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) + if (m_item.PermsGranter != agentID || (perm & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) llReleaseControls(); m_host.AddScriptLPS(1); @@ -3417,11 +3387,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { lock (m_host.TaskInventory) { - m_host.TaskInventory[m_itemID].PermsGranter = agentID; - m_host.TaskInventory[m_itemID].PermsMask = perm; + m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; + m_host.TaskInventory[m_item.ItemID].PermsMask = perm; } - m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( + m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( "run_time_permissions", new Object[] { new LSL_Integer(perm) }, new DetectParams[0])); @@ -3441,11 +3411,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { lock (m_host.TaskInventory) { - m_host.TaskInventory[m_itemID].PermsGranter = agentID; - m_host.TaskInventory[m_itemID].PermsMask = perm; + m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; + m_host.TaskInventory[m_item.ItemID].PermsMask = perm; } - m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( + m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( "run_time_permissions", new Object[] { new LSL_Integer(perm) }, new DetectParams[0])); @@ -3466,8 +3436,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { lock (m_host.TaskInventory) { - m_host.TaskInventory[m_itemID].PermsGranter = agentID; - m_host.TaskInventory[m_itemID].PermsMask = 0; + m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; + m_host.TaskInventory[m_item.ItemID].PermsMask = 0; } presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; @@ -3475,13 +3445,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } presence.ControllingClient.SendScriptQuestion( - m_host.UUID, m_host.ParentGroup.RootPart.Name, ownerName, m_itemID, perm); + m_host.UUID, m_host.ParentGroup.RootPart.Name, ownerName, m_item.ItemID, perm); return; } // Requested agent is not in range, refuse perms - m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( + m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( "run_time_permissions", new Object[] { new LSL_Integer(0) }, new DetectParams[0])); @@ -3500,10 +3470,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api lock (m_host.TaskInventory) { - m_host.TaskInventory[m_itemID].PermsMask = answer; + m_host.TaskInventory[m_item.ItemID].PermsMask = answer; } - m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( + m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( "run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); @@ -3513,14 +3483,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - return GetSelfInventoryItem().PermsGranter.ToString(); + return m_item.PermsGranter.ToString(); } public LSL_Integer llGetPermissions() { m_host.AddScriptLPS(1); - int perms = GetSelfInventoryItem().PermsMask; + int perms = m_item.PermsMask; if (m_automaticLinkPermission) perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; @@ -3558,9 +3528,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(target, out targetID)) return; - TaskInventoryItem item = GetSelfInventoryItem(); - - if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 && !m_automaticLinkPermission) { ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); @@ -3568,7 +3536,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } IClientAPI client = null; - ScenePresence sp = World.GetScenePresence(item.PermsGranter); + ScenePresence sp = World.GetScenePresence(m_item.PermsGranter); if (sp != null) client = sp.ControllingClient; @@ -3615,7 +3583,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - if ((GetSelfInventoryItem().PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 && !m_automaticLinkPermission) { ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); @@ -3986,7 +3954,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (item.Name == name) { - if (item.ItemID == m_itemID) + if (item.ItemID == m_item.ItemID) throw new ScriptDeleteException(); else m_host.Inventory.RemoveInventoryItem(item.ItemID); @@ -4122,7 +4090,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID tid = AsyncCommands. DataserverPlugin.RegisterRequest(m_localID, - m_itemID, rq.ToString()); + m_item.ItemID, rq.ToString()); AsyncCommands. DataserverPlugin.DataserverReply(rq.ToString(), reply); @@ -4143,7 +4111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { UUID tid = AsyncCommands. DataserverPlugin.RegisterRequest(m_localID, - m_itemID, item.AssetID.ToString()); + m_item.ItemID, item.AssetID.ToString()); Vector3 region = new Vector3( World.RegionInfo.RegionLocX * Constants.RegionSize, @@ -4498,9 +4466,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - TaskInventoryItem item = GetSelfInventoryItem(); - - return item.Name != null ? item.Name : String.Empty; + return m_item.Name != null ? m_item.Name : String.Empty; } public LSL_Integer llGetLinkNumberOfSides(int link) @@ -6598,14 +6564,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); if (xmlrpcMod.IsEnabled()) { - UUID channelID = xmlrpcMod.OpenXMLRPCChannel(m_localID, m_itemID, UUID.Zero); + UUID channelID = xmlrpcMod.OpenXMLRPCChannel(m_localID, m_item.ItemID, UUID.Zero); IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface(); if (xmlRpcRouter != null) { string ExternalHostName = m_ScriptEngine.World.RegionInfo.ExternalHostName; xmlRpcRouter.RegisterNewReceiver(m_ScriptEngine.ScriptModule, channelID, m_host.UUID, - m_itemID, String.Format("http://{0}:{1}/", ExternalHostName, + m_item.ItemID, String.Format("http://{0}:{1}/", ExternalHostName, xmlrpcMod.Port.ToString())); } object[] resobj = new object[] @@ -6617,7 +6583,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api new LSL_Integer(0), new LSL_String(String.Empty) }; - m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams("remote_data", resobj, + m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams("remote_data", resobj, new DetectParams[0])); } ScriptSleep(1000); @@ -6628,7 +6594,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); ScriptSleep(3000); - return (xmlrpcMod.SendRemoteData(m_localID, m_itemID, channel, dest, idata, sdata)).ToString(); + return (xmlrpcMod.SendRemoteData(m_localID, m_item.ItemID, channel, dest, idata, sdata)).ToString(); } public void llRemoteDataReply(string channel, string message_id, string sdata, int idata) @@ -9049,13 +9015,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); if (m_UrlModule != null) - return m_UrlModule.RequestSecureURL(m_ScriptEngine.ScriptModule, m_host, m_itemID).ToString(); + return m_UrlModule.RequestSecureURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID).ToString(); return UUID.Zero.ToString(); } public LSL_String llRequestSimulatorData(string simulator, int data) { - IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); + IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); try { @@ -9117,7 +9083,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID rq = UUID.Random(); UUID tid = AsyncCommands. - DataserverPlugin.RegisterRequest(m_localID, m_itemID, rq.ToString()); + DataserverPlugin.RegisterRequest(m_localID, m_item.ItemID, rq.ToString()); AsyncCommands. DataserverPlugin.DataserverReply(rq.ToString(), reply); @@ -9136,7 +9102,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); if (m_UrlModule != null) - return m_UrlModule.RequestURL(m_ScriptEngine.ScriptModule, m_host, m_itemID).ToString(); + return m_UrlModule.RequestURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID).ToString(); return UUID.Zero.ToString(); } @@ -9602,12 +9568,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - TaskInventoryItem item = GetSelfInventoryItem(); - - if (item.PermsGranter == UUID.Zero) + if (m_item.PermsGranter == UUID.Zero) return new LSL_Vector(); - if ((item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) { ShoutError("No permissions to track the camera"); return new LSL_Vector(); @@ -9626,12 +9590,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - TaskInventoryItem item = GetSelfInventoryItem(); - - if (item.PermsGranter == UUID.Zero) + if (m_item.PermsGranter == UUID.Zero) return new LSL_Rotation(); - if ((item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) { ShoutError("No permissions to track the camera"); return new LSL_Rotation(); @@ -9696,7 +9658,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llMapDestination(string simname, LSL_Vector pos, LSL_Vector lookAt) { m_host.AddScriptLPS(1); - DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); + DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); if (detectedParams == null) return; // only works on the first detected avatar ScenePresence avatar = World.GetScenePresence(detectedParams.Key); @@ -9813,15 +9775,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (objectID == UUID.Zero) return; - TaskInventoryItem item = GetSelfInventoryItem(); - // we need the permission first, to know which avatar we want to set the camera for - UUID agentID = item.PermsGranter; + UUID agentID = m_item.PermsGranter; if (agentID == UUID.Zero) return; - if ((item.PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; ScenePresence presence = World.GetScenePresence(agentID); @@ -9867,15 +9827,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (objectID == UUID.Zero) return; - TaskInventoryItem item = GetSelfInventoryItem(); - // we need the permission first, to know which avatar we want to clear the camera for - UUID agentID = item.PermsGranter; + UUID agentID = m_item.PermsGranter; if (agentID == UUID.Zero) return; - if ((item.PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; ScenePresence presence = World.GetScenePresence(agentID); @@ -10025,7 +9983,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } UUID reqID = httpScriptMod. - StartHttpRequest(m_localID, m_itemID, url, param, httpHeaders, body); + StartHttpRequest(m_localID, m_item.ItemID, url, param, httpHeaders, body); if (reqID != UUID.Zero) return reqID.ToString(); @@ -10455,7 +10413,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } // was: UUID tid = tid = AsyncCommands. - UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_itemID, assetID.ToString()); + UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_item.ItemID, assetID.ToString()); if (NotecardCache.IsCached(assetID)) { @@ -10517,7 +10475,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } // was: UUID tid = tid = AsyncCommands. - UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_itemID, assetID.ToString()); + UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_item.ItemID, assetID.ToString()); if (NotecardCache.IsCached(assetID)) { @@ -10575,7 +10533,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void print(string str) { // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print - IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); + IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); if (ossl != null) { ossl.CheckThreatLevel(ThreatLevel.High, "print"); @@ -10603,7 +10561,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { UUID rq = UUID.Random(); - AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_itemID, rq.ToString()); + AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_item.ItemID, rq.ToString()); AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), Name2Username(llKey2Name(id))); @@ -10619,7 +10577,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { UUID rq = UUID.Random(); - AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_itemID, rq.ToString()); + AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_item.ItemID, rq.ToString()); AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), llKey2Name(id)); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index df20126..cd47d96 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs @@ -59,16 +59,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal IScriptEngine m_ScriptEngine; internal SceneObjectPart m_host; internal uint m_localID; - internal UUID m_itemID; internal bool m_LSFunctionsEnabled = false; internal IScriptModuleComms m_comms = null; - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) + public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, TaskInventoryItem item) { m_ScriptEngine = ScriptEngine; m_host = host; m_localID = localID; - m_itemID = itemID; if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) m_LSFunctionsEnabled = true; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index 7c07e15..a578b50 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs @@ -58,16 +58,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal IScriptEngine m_ScriptEngine; internal SceneObjectPart m_host; internal uint m_localID; - internal UUID m_itemID; + internal TaskInventoryItem m_item; internal bool m_MODFunctionsEnabled = false; internal IScriptModuleComms m_comms = null; - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) + public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, TaskInventoryItem item) { m_ScriptEngine = ScriptEngine; m_host = host; m_localID = localID; - m_itemID = itemID; + m_item = item; if (m_ScriptEngine.Config.GetBoolean("AllowMODFunctions", false)) m_MODFunctionsEnabled = true; @@ -252,7 +252,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // non-null but don't trust it completely try { - object result = m_comms.InvokeOperation(m_host.UUID, m_itemID, fname, convertedParms); + object result = m_comms.InvokeOperation(m_host.UUID, m_item.ItemID, fname, convertedParms); if (result != null) return result; @@ -279,7 +279,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID req = UUID.Random(); - m_comms.RaiseEvent(m_itemID, req.ToString(), module, command, k); + m_comms.RaiseEvent(m_item.ItemID, req.ToString(), module, command, k); return req.ToString(); } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 3b67966..9b2022a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -134,19 +134,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal ILSL_Api m_LSL_Api = null; // get a reference to the LSL API so we can call methods housed there internal SceneObjectPart m_host; internal uint m_localID; - internal UUID m_itemID; + internal TaskInventoryItem m_item; internal bool m_OSFunctionsEnabled = false; internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; internal float m_ScriptDelayFactor = 1.0f; internal float m_ScriptDistanceFactor = 1.0f; internal Dictionary m_FunctionPerms = new Dictionary(); - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) + public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, TaskInventoryItem item) { m_ScriptEngine = ScriptEngine; m_host = host; m_localID = localID; - m_itemID = itemID; + m_item = item; if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) m_OSFunctionsEnabled = true; @@ -224,7 +224,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_LSL_Api != null) return; - m_LSL_Api = (ILSL_Api)m_ScriptEngine.GetApi(m_itemID, "LSL"); + m_LSL_Api = (ILSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "LSL"); } // @@ -343,22 +343,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; } - TaskInventoryItem ti = m_host.Inventory.GetInventoryItem(m_itemID); - if (ti == null) - { - OSSLError( - String.Format("{0} permission error. Can't find script in prim inventory.", - function)); - } - - UUID ownerID = ti.OwnerID; + UUID ownerID = m_item.OwnerID; //OSSL only may be used if object is in the same group as the parcel if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_GROUP_MEMBER")) { ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); - if (land.LandData.GroupID == ti.GroupID && land.LandData.GroupID != UUID.Zero) + if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero) { return; } @@ -394,13 +386,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - if (!m_FunctionPerms[function].AllowedCreators.Contains(ti.CreatorID)) + if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID)) OSSLError( String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function and prim owner also has no permission.", function)); - if (ti.CreatorID != ownerID) + + if (m_item.CreatorID != ownerID) { - if ((ti.CurrentPermissions & (uint)PermissionMask.Modify) != 0) + if ((m_item.CurrentPermissions & (uint)PermissionMask.Modify) != 0) OSSLError( String.Format("{0} permission denied. Script permissions error.", function)); @@ -1183,7 +1176,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api CheckThreatLevel(ThreatLevel.High, "osSetStateEvents"); m_host.AddScriptLPS(1); - m_host.SetScriptEvents(m_itemID, events); + m_host.SetScriptEvents(m_item.ItemID, events); } public void osSetRegionWaterHeight(double height) diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 2c8af81..dd47393 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -232,7 +232,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance foreach (string api in am.GetApis()) { m_Apis[api] = am.CreateApi(api); - m_Apis[api].Initialize(engine, part, LocalID, itemID); + m_Apis[api].Initialize(engine, part, LocalID, ScriptTask); } try diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs index 49266e9..f480e1d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs @@ -88,10 +88,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests // Create an object embedded inside the first UUID itemId = TestHelpers.ParseTail(0x20); - TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, userId); + TaskInventoryItem item + = TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, userId); LSL_Api api = new LSL_Api(); - api.Initialize(m_engine, so1.RootPart, so1.RootPart.LocalId, so1.RootPart.UUID); + api.Initialize(m_engine, so1.RootPart, so1.RootPart.LocalId, null); // Create a second object SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, userId, "so2", 0x100); @@ -124,7 +125,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, user1Id, "so1", 0x10); m_scene.AddSceneObject(so1); LSL_Api api = new LSL_Api(); - api.Initialize(m_engine, so1.RootPart, so1.RootPart.LocalId, so1.RootPart.UUID); + api.Initialize(m_engine, so1.RootPart, so1.RootPart.LocalId, null); // Create an object embedded inside the first UUID itemId = TestHelpers.ParseTail(0x20); @@ -134,7 +135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, user2Id, "so2", 0x100); m_scene.AddSceneObject(so2); LSL_Api api2 = new LSL_Api(); - api2.Initialize(m_engine, so2.RootPart, so2.RootPart.LocalId, so2.RootPart.UUID); + api2.Initialize(m_engine, so2.RootPart, so2.RootPart.LocalId, null); // *** Firstly, we test where llAllowInventoryDrop() has not been called. *** api.llGiveInventory(so2.UUID.ToString(), inventoryItemName); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs index 92a63bf..bba6c56 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs @@ -66,8 +66,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests engine.AddRegion(scene); m_lslApi = new LSL_Api(); - m_lslApi.Initialize(engine, part, part.LocalId, part.UUID); - + m_lslApi.Initialize(engine, part, part.LocalId, null); } [Test] diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index c51227b..dff8f6e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs @@ -95,7 +95,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, part.LocalId, part.UUID); + osslApi.Initialize(m_engine, part, part.LocalId, null); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); @@ -130,7 +130,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, part.LocalId, part.UUID); + osslApi.Initialize(m_engine, part, part.LocalId, null); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); @@ -161,7 +161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, part.LocalId, part.UUID); + osslApi.Initialize(m_engine, part, part.LocalId, null); string notecardName = "appearanceNc"; @@ -202,7 +202,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, part.LocalId, part.UUID); + osslApi.Initialize(m_engine, part, part.LocalId, null); string notecardName = "appearanceNc"; diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs index 9c36108..80ac52c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs @@ -104,10 +104,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(otherSo); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, part.LocalId, part.UUID); + osslApi.Initialize(m_engine, part, part.LocalId, null); OSSL_Api otherOsslApi = new OSSL_Api(); - otherOsslApi.Initialize(m_engine, otherPart, otherPart.LocalId, otherPart.UUID); + otherOsslApi.Initialize(m_engine, otherPart, otherPart.LocalId, null); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); @@ -151,7 +151,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, part.LocalId, part.UUID); + osslApi.Initialize(m_engine, part, part.LocalId, null); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); -- cgit v1.1 From 6406d5a5b9c1c4ef261254e7d4446603b496d1fd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 8 May 2012 23:20:27 +0100 Subject: refactor: Eliminate local id parameter from api initialize. This is always available from m_host.LocalId --- .../Region/ScriptEngine/Interfaces/IScriptApi.cs | 3 +- .../Shared/Api/Implementation/LSL_Api.cs | 40 ++++++++++------------ .../Shared/Api/Implementation/LS_Api.cs | 4 +-- .../Shared/Api/Implementation/MOD_Api.cs | 4 +-- .../Shared/Api/Implementation/OSSL_Api.cs | 4 +-- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 2 +- .../Shared/Tests/LSL_ApiInventoryTests.cs | 9 +++-- .../ScriptEngine/Shared/Tests/LSL_ApiTest.cs | 2 +- .../Shared/Tests/OSSL_ApiAppearanceTest.cs | 8 ++--- .../ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs | 6 ++-- 10 files changed, 36 insertions(+), 46 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs index cced522..2027ca6 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs @@ -42,8 +42,7 @@ namespace OpenSim.Region.ScriptEngine.Interfaces /// proper runtime assembly at load time. /// /param> /// - /// /// - void Initialize(IScriptEngine engine, SceneObjectPart part, uint localID, TaskInventoryItem item); + void Initialize(IScriptEngine engine, SceneObjectPart part, TaskInventoryItem item); } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index e8e4dab..afd943b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -84,7 +84,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected IScriptEngine m_ScriptEngine; protected SceneObjectPart m_host; - protected uint m_localID; /// /// The item that hosts this script @@ -108,11 +107,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected Dictionary m_userInfoCache = new Dictionary(); - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, TaskInventoryItem item) + public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) { m_ScriptEngine = ScriptEngine; m_host = host; - m_localID = localID; m_item = item; m_ScriptDelayFactor = @@ -843,7 +841,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID.TryParse(ID, out keyID); IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); if (wComm != null) - return wComm.Listen(m_localID, m_item.ItemID, m_host.UUID, channelID, name, keyID, msg); + return wComm.Listen(m_host.LocalId, m_item.ItemID, m_host.UUID, channelID, name, keyID, msg); else return -1; } @@ -870,7 +868,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID keyID = UUID.Zero; UUID.TryParse(id, out keyID); - AsyncCommands.SensorRepeatPlugin.SenseOnce(m_localID, m_item.ItemID, name, keyID, type, range, arc, m_host); + AsyncCommands.SensorRepeatPlugin.SenseOnce(m_host.LocalId, m_item.ItemID, name, keyID, type, range, arc, m_host); } public void llSensorRepeat(string name, string id, int type, double range, double arc, double rate) @@ -879,13 +877,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID keyID = UUID.Zero; UUID.TryParse(id, out keyID); - AsyncCommands.SensorRepeatPlugin.SetSenseRepeatEvent(m_localID, m_item.ItemID, name, keyID, type, range, arc, rate, m_host); + AsyncCommands.SensorRepeatPlugin.SetSenseRepeatEvent(m_host.LocalId, m_item.ItemID, name, keyID, type, range, arc, rate, m_host); } public void llSensorRemove() { m_host.AddScriptLPS(1); - AsyncCommands.SensorRepeatPlugin.UnSetSenseRepeaterEvents(m_localID, m_item.ItemID); + AsyncCommands.SensorRepeatPlugin.UnSetSenseRepeaterEvents(m_host.LocalId, m_item.ItemID); } public string resolveName(UUID objecUUID) @@ -2874,7 +2872,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api sec = m_MinTimerInterval; m_host.AddScriptLPS(1); // Setting timer repeat - AsyncCommands.TimerPlugin.SetTimerEvent(m_localID, m_item.ItemID, sec); + AsyncCommands.TimerPlugin.SetTimerEvent(m_host.LocalId, m_item.ItemID, sec); } public virtual void llSleep(double sec) @@ -2937,7 +2935,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) { - presence.RegisterControlEventsToScript(controls, accept, pass_on, m_localID, m_item.ItemID); + presence.RegisterControlEventsToScript(controls, accept, pass_on, m_host.LocalId, m_item.ItemID); } } } @@ -2958,7 +2956,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) { // Unregister controls from Presence - presence.UnRegisterControlEventsToScript(m_localID, m_item.ItemID); + presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); // Remove Take Control permission. m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS; } @@ -4089,7 +4087,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID rq = UUID.Random(); UUID tid = AsyncCommands. - DataserverPlugin.RegisterRequest(m_localID, + DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString()); AsyncCommands. @@ -4110,7 +4108,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (item.Type == 3 && item.Name == name) { UUID tid = AsyncCommands. - DataserverPlugin.RegisterRequest(m_localID, + DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, item.AssetID.ToString()); Vector3 region = new Vector3( @@ -6564,7 +6562,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); if (xmlrpcMod.IsEnabled()) { - UUID channelID = xmlrpcMod.OpenXMLRPCChannel(m_localID, m_item.ItemID, UUID.Zero); + UUID channelID = xmlrpcMod.OpenXMLRPCChannel(m_host.LocalId, m_item.ItemID, UUID.Zero); IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface(); if (xmlRpcRouter != null) { @@ -6594,7 +6592,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); ScriptSleep(3000); - return (xmlrpcMod.SendRemoteData(m_localID, m_item.ItemID, channel, dest, idata, sdata)).ToString(); + return (xmlrpcMod.SendRemoteData(m_host.LocalId, m_item.ItemID, channel, dest, idata, sdata)).ToString(); } public void llRemoteDataReply(string channel, string message_id, string sdata, int idata) @@ -9083,7 +9081,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID rq = UUID.Random(); UUID tid = AsyncCommands. - DataserverPlugin.RegisterRequest(m_localID, m_item.ItemID, rq.ToString()); + DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString()); AsyncCommands. DataserverPlugin.DataserverReply(rq.ToString(), reply); @@ -9982,8 +9980,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - UUID reqID = httpScriptMod. - StartHttpRequest(m_localID, m_item.ItemID, url, param, httpHeaders, body); + UUID reqID + = httpScriptMod.StartHttpRequest(m_host.LocalId, m_item.ItemID, url, param, httpHeaders, body); if (reqID != UUID.Zero) return reqID.ToString(); @@ -10413,7 +10411,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } // was: UUID tid = tid = AsyncCommands. - UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_item.ItemID, assetID.ToString()); + UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, assetID.ToString()); if (NotecardCache.IsCached(assetID)) { @@ -10475,7 +10473,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } // was: UUID tid = tid = AsyncCommands. - UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_item.ItemID, assetID.ToString()); + UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, assetID.ToString()); if (NotecardCache.IsCached(assetID)) { @@ -10561,7 +10559,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { UUID rq = UUID.Random(); - AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_item.ItemID, rq.ToString()); + AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString()); AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), Name2Username(llKey2Name(id))); @@ -10577,7 +10575,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { UUID rq = UUID.Random(); - AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_item.ItemID, rq.ToString()); + AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString()); AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), llKey2Name(id)); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index cd47d96..795de80 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs @@ -58,15 +58,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { internal IScriptEngine m_ScriptEngine; internal SceneObjectPart m_host; - internal uint m_localID; internal bool m_LSFunctionsEnabled = false; internal IScriptModuleComms m_comms = null; - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, TaskInventoryItem item) + public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) { m_ScriptEngine = ScriptEngine; m_host = host; - m_localID = localID; if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) m_LSFunctionsEnabled = true; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index a578b50..4bd3dff 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs @@ -57,16 +57,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { internal IScriptEngine m_ScriptEngine; internal SceneObjectPart m_host; - internal uint m_localID; internal TaskInventoryItem m_item; internal bool m_MODFunctionsEnabled = false; internal IScriptModuleComms m_comms = null; - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, TaskInventoryItem item) + public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) { m_ScriptEngine = ScriptEngine; m_host = host; - m_localID = localID; m_item = item; if (m_ScriptEngine.Config.GetBoolean("AllowMODFunctions", false)) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 9b2022a..ad1a358 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -133,7 +133,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal IScriptEngine m_ScriptEngine; internal ILSL_Api m_LSL_Api = null; // get a reference to the LSL API so we can call methods housed there internal SceneObjectPart m_host; - internal uint m_localID; internal TaskInventoryItem m_item; internal bool m_OSFunctionsEnabled = false; internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; @@ -141,11 +140,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal float m_ScriptDistanceFactor = 1.0f; internal Dictionary m_FunctionPerms = new Dictionary(); - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, TaskInventoryItem item) + public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) { m_ScriptEngine = ScriptEngine; m_host = host; - m_localID = localID; m_item = item; if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index dd47393..329e361 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -232,7 +232,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance foreach (string api in am.GetApis()) { m_Apis[api] = am.CreateApi(api); - m_Apis[api].Initialize(engine, part, LocalID, ScriptTask); + m_Apis[api].Initialize(engine, part, ScriptTask); } try diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs index f480e1d..c73e22f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs @@ -88,11 +88,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests // Create an object embedded inside the first UUID itemId = TestHelpers.ParseTail(0x20); - TaskInventoryItem item - = TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, userId); + TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, userId); LSL_Api api = new LSL_Api(); - api.Initialize(m_engine, so1.RootPart, so1.RootPart.LocalId, null); + api.Initialize(m_engine, so1.RootPart, null); // Create a second object SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, userId, "so2", 0x100); @@ -125,7 +124,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, user1Id, "so1", 0x10); m_scene.AddSceneObject(so1); LSL_Api api = new LSL_Api(); - api.Initialize(m_engine, so1.RootPart, so1.RootPart.LocalId, null); + api.Initialize(m_engine, so1.RootPart, null); // Create an object embedded inside the first UUID itemId = TestHelpers.ParseTail(0x20); @@ -135,7 +134,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, user2Id, "so2", 0x100); m_scene.AddSceneObject(so2); LSL_Api api2 = new LSL_Api(); - api2.Initialize(m_engine, so2.RootPart, so2.RootPart.LocalId, null); + api2.Initialize(m_engine, so2.RootPart, null); // *** Firstly, we test where llAllowInventoryDrop() has not been called. *** api.llGiveInventory(so2.UUID.ToString(), inventoryItemName); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs index bba6c56..f96a156 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs @@ -66,7 +66,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests engine.AddRegion(scene); m_lslApi = new LSL_Api(); - m_lslApi.Initialize(engine, part, part.LocalId, null); + m_lslApi.Initialize(engine, part, null); } [Test] diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index dff8f6e..3965734 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs @@ -95,7 +95,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, part.LocalId, null); + osslApi.Initialize(m_engine, part, null); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); @@ -130,7 +130,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, part.LocalId, null); + osslApi.Initialize(m_engine, part, null); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); @@ -161,7 +161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, part.LocalId, null); + osslApi.Initialize(m_engine, part, null); string notecardName = "appearanceNc"; @@ -202,7 +202,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, part.LocalId, null); + osslApi.Initialize(m_engine, part, null); string notecardName = "appearanceNc"; diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs index 80ac52c..0ccd889 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs @@ -104,10 +104,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(otherSo); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, part.LocalId, null); + osslApi.Initialize(m_engine, part, null); OSSL_Api otherOsslApi = new OSSL_Api(); - otherOsslApi.Initialize(m_engine, otherPart, otherPart.LocalId, null); + otherOsslApi.Initialize(m_engine, otherPart, null); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); @@ -151,7 +151,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, part.LocalId, null); + osslApi.Initialize(m_engine, part, null); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); -- cgit v1.1 From c0658a102ebbff6ea8ef1ef510d30da890aacded Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 8 May 2012 23:29:51 +0100 Subject: Add automated TestllCreateLink() --- .../Shared/Tests/LSL_ApiLinkingTests.cs | 112 +++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs new file mode 100644 index 0000000..4420915 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs @@ -0,0 +1,112 @@ +/* + * 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 System.Text; +using log4net; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenMetaverse.Assets; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Avatar.AvatarFactory; +using OpenSim.Region.OptionalModules.World.NPC; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.Services.Interfaces; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.ScriptEngine.Shared.Tests +{ + /// + /// Tests for linking functions in LSL + /// + /// + /// This relates to LSL. Actual linking functionality should be tested in the main + /// OpenSim.Region.Framework.Scenes.Tests.SceneObjectLinkingTests. + /// + [TestFixture] + public class LSL_ApiLinkingTests + { + protected Scene m_scene; + protected XEngine.XEngine m_engine; + + [SetUp] + public void SetUp() + { + IConfigSource initConfigSource = new IniConfigSource(); + IConfig config = initConfigSource.AddConfig("XEngine"); + config.Set("Enabled", "true"); + + m_scene = new SceneHelpers().SetupScene(); + SceneHelpers.SetupSceneModules(m_scene, initConfigSource); + + m_engine = new XEngine.XEngine(); + m_engine.Initialise(initConfigSource); + m_engine.AddRegion(m_scene); + } + + [Test] + public void TestllCreateLink() + { + TestHelpers.InMethod(); + + UUID ownerId = TestHelpers.ParseTail(0x1); + + SceneObjectGroup grp1 = SceneHelpers.CreateSceneObject(2, ownerId, "grp1-", 0x10); + grp1.AbsolutePosition = new Vector3(10, 10, 10); + m_scene.AddSceneObject(grp1); + + // FIXME: This should really be a script item (with accompanying script) + TaskInventoryItem grp1Item + = TaskInventoryHelpers.AddNotecard(m_scene, grp1.RootPart); + grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; + + SceneObjectGroup grp2 = SceneHelpers.CreateSceneObject(2, ownerId, "grp2-", 0x20); + grp2.AbsolutePosition = new Vector3(20, 20, 20); + + // <180,0,0> + grp2.UpdateGroupRotationR(Quaternion.CreateFromEulers(180 * Utils.DEG_TO_RAD, 0, 0)); + + m_scene.AddSceneObject(grp2); + + LSL_Api apiGrp1 = new LSL_Api(); + apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item); + + apiGrp1.llCreateLink(grp2.UUID.ToString(), ScriptBaseClass.TRUE); + + Assert.That(grp1.Parts.Length, Is.EqualTo(4)); + Assert.That(grp2.IsDeleted, Is.True); + } + } +} \ No newline at end of file -- cgit v1.1 From ef279c5a62d15d29ca94c95418a13d52f2a68244 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 8 May 2012 23:36:23 +0100 Subject: Add automated TestllBreakLink() --- .../Shared/Tests/LSL_ApiLinkingTests.cs | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs index 4420915..bc3b790 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs @@ -108,5 +108,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests Assert.That(grp1.Parts.Length, Is.EqualTo(4)); Assert.That(grp2.IsDeleted, Is.True); } + + [Test] + public void TestllBreakLink() + { + TestHelpers.InMethod(); + + UUID ownerId = TestHelpers.ParseTail(0x1); + + SceneObjectGroup grp1 = SceneHelpers.CreateSceneObject(2, ownerId, "grp1-", 0x10); + grp1.AbsolutePosition = new Vector3(10, 10, 10); + m_scene.AddSceneObject(grp1); + + // FIXME: This should really be a script item (with accompanying script) + TaskInventoryItem grp1Item + = TaskInventoryHelpers.AddNotecard(m_scene, grp1.RootPart); + grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; + + LSL_Api apiGrp1 = new LSL_Api(); + apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item); + + apiGrp1.llBreakLink(2); + + Assert.That(grp1.Parts.Length, Is.EqualTo(1)); + + SceneObjectGroup grp2 = m_scene.GetSceneObjectGroup("grp1-Part1"); + Assert.That(grp2, Is.Not.Null); + } } } \ No newline at end of file -- cgit v1.1 From c21c9e13ef09607fa6f918f27bf087247a70d5a3 Mon Sep 17 00:00:00 2001 From: Talun Date: Mon, 7 May 2012 21:44:17 +0100 Subject: Mantis 1456 same region teleport of a sitting avatar. Region to region was fixed some time ago in EntityTransferModule. This applies the same fix for same region teleports. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 7e49a5e..769824e 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -996,6 +996,8 @@ namespace OpenSim.Region.Framework.Scenes public void TeleportWithMomentum(Vector3 pos, Vector3? v) { + if (ParentID != (uint)0) + StandUp(); bool isFlying = Flying; Vector3 vel = Velocity; RemoveFromPhysicalScene(); -- cgit v1.1 From 20952c75c526180a0286fb9634b94ac1354a2770 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Tue, 8 May 2012 16:05:34 -0700 Subject: Trigger event when scene presences are updated --- OpenSim/Region/Framework/Scenes/EventManager.cs | 24 ++++++++++++++++++++++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 10 ++++++++++ 2 files changed, 34 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index b3debb0..ace8313 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -480,6 +480,9 @@ namespace OpenSim.Region.Framework.Scenes public delegate void SceneObjectPartUpdated(SceneObjectPart sop); public event SceneObjectPartUpdated OnSceneObjectPartUpdated; + public delegate void ScenePresenceUpdated(ScenePresence sp); + public event ScenePresenceUpdated OnScenePresenceUpdated; + public delegate void RegionUp(GridRegion region); public event RegionUp OnRegionUp; @@ -2343,6 +2346,27 @@ namespace OpenSim.Region.Framework.Scenes } } + public void TriggerScenePresenceUpdated(ScenePresence sp) + { + ScenePresenceUpdated handler = OnScenePresenceUpdated; + if (handler != null) + { + foreach (ScenePresenceUpdated d in handler.GetInvocationList()) + { + try + { + d(sp); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[EVENT MANAGER]: Delegate for TriggerScenePresenceUpdated failed - continuing. {0} {1}", + e.Message, e.StackTrace); + } + } + } + } + public void TriggerOnParcelPropertiesUpdateRequest(LandUpdateArgs args, int local_id, IClientAPI remote_client) { diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 7e49a5e..c552447 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -76,6 +76,11 @@ namespace OpenSim.Region.Framework.Scenes // { // m_log.Debug("[SCENE PRESENCE] Destructor called"); // } + private void TriggerScenePresenceUpdated() + { + if (m_scene != null) + m_scene.EventManager.TriggerScenePresenceUpdated(this); + } private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -489,6 +494,7 @@ namespace OpenSim.Region.Framework.Scenes //m_log.DebugFormat( // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", // Scene.RegionInfo.RegionName, Name, m_pos); + TriggerScenePresenceUpdated(); } } @@ -508,6 +514,7 @@ namespace OpenSim.Region.Framework.Scenes return; m_pos = value; + TriggerScenePresenceUpdated(); } } @@ -1523,6 +1530,7 @@ namespace OpenSim.Region.Framework.Scenes } m_scene.EventManager.TriggerOnClientMovement(this); + TriggerScenePresenceUpdated(); } /// @@ -2419,6 +2427,7 @@ namespace OpenSim.Region.Framework.Scenes m_scene.ForEachClient(SendTerseUpdateToClient); } + TriggerScenePresenceUpdated(); } public void SendCoarseLocations(List coarseLocations, List avatarUUIDs) @@ -3195,6 +3204,7 @@ namespace OpenSim.Region.Framework.Scenes Velocity = force; m_forceToApply = null; + TriggerScenePresenceUpdated(); } } -- cgit v1.1 From e5dbb652d5118d193de794fb948252195594b344 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 9 May 2012 00:11:10 +0100 Subject: Remove physics actor related race conditions in SetVehicleFlags() and SetPhysicsAxisRotation() sop.PhysActor can currently become null at any time. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 4bec2d4..f911ef8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3321,10 +3321,10 @@ namespace OpenSim.Region.Framework.Scenes public void SetVehicleFlags(int param, bool remove) { - if (PhysActor != null) - { - PhysActor.VehicleFlags(param, remove); - } + PhysicsActor pa = PhysActor; + + if (pa != null) + pa.VehicleFlags(param, remove); } public void SetGroup(UUID groupID, IClientAPI client) @@ -3356,10 +3356,12 @@ namespace OpenSim.Region.Framework.Scenes public void SetPhysicsAxisRotation() { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + + if (pa != null) { - PhysActor.LockAngularMotion(RotationAxis); - ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + pa.LockAngularMotion(RotationAxis); + ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); } } -- cgit v1.1 From 61e99bcdcba5480aa8a2a8b8e2f2b0a66c08e6b4 Mon Sep 17 00:00:00 2001 From: Talun Date: Tue, 8 May 2012 15:52:25 +0100 Subject: Mantis 6015 new LSL function llGetAgentList. Details in the lsl wiki --- .../Shared/Api/Implementation/LSL_Api.cs | 85 ++++++++++++++++++++++ .../ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | 1 + .../Shared/Api/Runtime/LSL_Constants.cs | 5 ++ .../ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs | 5 ++ 4 files changed, 96 insertions(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index afd943b..5b5cab8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5529,6 +5529,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); return "en-us"; } + /// + /// http://wiki.secondlife.com/wiki/LlGetAgentList + /// The list of options is currently not used in SL + /// scope is one of:- + /// AGENT_LIST_REGION - all in the region + /// AGENT_LIST_PARCEL - all in the same parcel as the scripted object + /// AGENT_LIST_PARCEL_OWNER - all in any parcel owned by the owner of the + /// current parcel. + /// + public LSL_List llGetAgentList(LSL_Integer scope, LSL_List options) + { + m_host.AddScriptLPS(1); + + // the constants are 1, 2 and 4 so bits are being set, but you + // get an error "INVALID_SCOPE" if it is anything but 1, 2 and 4 + bool regionWide = scope == ScriptBaseClass.AGENT_LIST_REGION; + bool parcelOwned = scope == ScriptBaseClass.AGENT_LIST_PARCEL_OWNER; + bool parcel = scope == ScriptBaseClass.AGENT_LIST_PARCEL; + + LSL_List result = new LSL_List(); + + if (!regionWide && !parcelOwned && !parcel) + { + result.Add("INVALID_SCOPE"); + return result; + } + + ILandObject land; + Vector3 pos; + UUID id = UUID.Zero; + if (parcel || parcelOwned) + { + pos = m_host.ParentGroup.RootPart.GetWorldPosition(); + land = World.LandChannel.GetLandObject(pos.X, pos.Y); + if (land == null) + { + id = UUID.Zero; + } + else + { + if (parcelOwned) + { + id = land.LandData.OwnerID; + } + else + { + id = land.LandData.GlobalID; + } + } + } + List presenceIds = new List(); + + World.ForEachRootScenePresence( + delegate (ScenePresence ssp) + { + // Gods are not listed in SL + if (!ssp.IsDeleted && ssp.GodLevel == 0.0 && !ssp.IsChildAgent) + { + if (!regionWide) + { + pos = ssp.AbsolutePosition; + land = World.LandChannel.GetLandObject(pos.X, pos.Y); + if (land != null) + { + if (parcelOwned && land.LandData.OwnerID == id || + parcel && land.LandData.GlobalID == id) + { + result.Add(ssp.UUID.ToString()); + } + } + } + else + { + result.Add(ssp.UUID.ToString()); + } + } + // Maximum of 100 results + if (result.Length > 99) + { + return; + } + } + ); + return result; + } public void llAdjustSoundVolume(double volume) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 7a797ac..7f5d1fe 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -109,6 +109,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Vector llGetAccel(); LSL_Integer llGetAgentInfo(string id); LSL_String llGetAgentLanguage(string id); + LSL_List llGetAgentList(LSL_Integer scope, LSL_List options); LSL_Vector llGetAgentSize(string id); LSL_Float llGetAlpha(int face); LSL_Float llGetAndResetTime(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 2a28542..b6c21e6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -501,6 +501,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int OBJECT_STREAMING_COST = 15; public const int OBJECT_PHYSICS_COST = 16; + // for llGetAgentList + public const int AGENT_LIST_PARCEL = 1; + public const int AGENT_LIST_PARCEL_OWNER = 2; + public const int AGENT_LIST_REGION = 4; + // Can not be public const? public static readonly vector ZERO_VECTOR = new vector(0.0, 0.0, 0.0); public static readonly rotation ZERO_ROTATION = new rotation(0.0, 0.0, 0.0, 1.0); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index 80fa530..c0bf29c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -389,6 +389,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_LSL_Functions.llGetAgentLanguage(id); } + public LSL_List llGetAgentList(LSL_Integer scope, LSL_List options) + { + return m_LSL_Functions.llGetAgentList(scope, options); + } + public LSL_Vector llGetAgentSize(string id) { return m_LSL_Functions.llGetAgentSize(id); -- cgit v1.1 From e813f41478eefb50748e9bdc2b825fa8bc25c971 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 9 May 2012 20:52:54 +0100 Subject: Escape and unescape xml element names if necessary in ServerUtils.BuildXmlData() and ParseElement() If AvatarService appearance data is retrieved over the network, then ServerUtils was attempting to transfer names such as "Wearable 0:0" directly to xml element names, resulting in an exception. Space is not valid in xml element names. Neither is : in this case since the intention is not to namespace. Using names directly as keys is not a good idea. To get around this problem this patch escapes and unescapes the element names as appropriate. This has no impact on existing xml (since it had to be valid in the first place) but allows AvatarService data to be used over the network. Setting appearance (from simulator to AvatarService) did not suffer this problem since the values are passed in the query string which is already properly escaped. --- OpenSim/Server/Base/ServerUtils.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs index 0cc2a4b..42c82cf 100644 --- a/OpenSim/Server/Base/ServerUtils.cs +++ b/OpenSim/Server/Base/ServerUtils.cs @@ -268,7 +268,7 @@ namespace OpenSim.Server.Base continue; XmlElement elem = parent.OwnerDocument.CreateElement("", - kvp.Key, ""); + XmlConvert.EncodeLocalName(kvp.Key), ""); if (kvp.Value is Dictionary) { @@ -323,11 +323,11 @@ namespace OpenSim.Server.Base XmlNode type = part.Attributes.GetNamedItem("type"); if (type == null || type.Value != "List") { - ret[part.Name] = part.InnerText; + ret[XmlConvert.DecodeName(part.Name)] = part.InnerText; } else { - ret[part.Name] = ParseElement(part); + ret[XmlConvert.DecodeName(part.Name)] = ParseElement(part); } } -- cgit v1.1 From 6987aef38dbc4f5c24b6e2cc73601f9a7c5f4431 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 9 May 2012 23:12:30 +0100 Subject: Improve logging on the prim inventory script asset request path for future use. This adds name and description of the request handler to http request logging when DebugLevel >= 1 --- OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 4 ++-- .../ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 2 +- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 13 ++++++++----- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 4 ++++ 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index d0463c8..401dfd3 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -447,8 +447,8 @@ namespace OpenSim.Framework.Servers.HttpServer { if (DebugLevel >= 1) m_log.DebugFormat( - "[BASE HTTP SERVER]: Found stream handler for {0} {1}", - request.HttpMethod, request.Url.PathAndQuery); + "[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}", + request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description); // Okay, so this is bad, but should be considered temporary until everything is IStreamHandler. byte[] buffer = null; diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 9791885..6c28e78 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -309,7 +309,7 @@ namespace OpenSim.Region.ClientStack.Linden m_HostCapsObj.HttpListener.AddStreamHandler( new BinaryStreamHandler( - "POST", capsBase + uploaderPath, uploader.uploaderCaps, "BunchOfCaps", null)); + "POST", capsBase + uploaderPath, uploader.uploaderCaps, "TaskInventoryScriptUpdater", null)); string protocol = "http://"; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index ae5cbff..4d6081c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -11955,21 +11955,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected void MakeAssetRequest(TransferRequestPacket transferRequest, UUID taskID) { UUID requestID = UUID.Zero; - if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset) + int sourceType = transferRequest.TransferInfo.SourceType; + + if (sourceType == (int)SourceType.Asset) { requestID = new UUID(transferRequest.TransferInfo.Params, 0); } - else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimInventoryItem) + else if (sourceType == (int)SourceType.SimInventoryItem) { requestID = new UUID(transferRequest.TransferInfo.Params, 80); } - else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimEstate) + else if (sourceType == (int)SourceType.SimEstate) { requestID = taskID; } - -// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); +// m_log.DebugFormat( +// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", +// requestID, taskID, (SourceType)sourceType, Name); m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 816d3b6..8a26df1 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -300,6 +300,10 @@ namespace OpenSim.Region.Framework.Scenes AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)AssetType.LSLText, data, remoteClient.AgentId); AssetService.Store(asset); +// m_log.DebugFormat( +// "[PRIM INVENTORY]: Stored asset {0} when updating item {1} in prim {2} for {3}", +// asset.ID, item.Name, part.Name, remoteClient.Name); + if (isScriptRunning) { part.Inventory.RemoveScriptInstance(item.ItemID, false); -- cgit v1.1 From d8a78374aa11c5460d6e58a6f4110fca61dfded4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 9 May 2012 23:25:01 +0100 Subject: Where necessary, rename OpenSim/Services/Connectors/*.cs files to reflect the actual class names. This is usually because the file name was singular (*Service*) but the class name was plural (*Services*). This is to make configuration easier rather than having to look in the c# code itself to find the slightly different name of the connector. This does not affect existing configuration since the files are being renamed rather than the classes. --- .../Connectors/Asset/AssetServiceConnector.cs | 329 ---------- .../Connectors/Asset/AssetServicesConnector.cs | 329 ++++++++++ .../AuthenticationServiceConnector.cs | 167 ----- .../AuthenticationServicesConnector.cs | 167 +++++ .../Authorization/AuthorizationServiceConnector.cs | 123 ---- .../AuthorizationServicesConnector.cs | 123 ++++ .../Connectors/Avatar/AvatarServiceConnector.cs | 326 ---------- .../Connectors/Avatar/AvatarServicesConnector.cs | 326 ++++++++++ .../Connectors/Friends/FriendsServiceConnector.cs | 267 -------- .../Connectors/Friends/FriendsServicesConnector.cs | 267 ++++++++ .../Connectors/Grid/GridServiceConnector.cs | 671 --------------------- .../Connectors/Grid/GridServicesConnector.cs | 671 +++++++++++++++++++++ .../GridUser/GridUserServiceConnector.cs | 290 --------- .../GridUser/GridUserServicesConnector.cs | 290 +++++++++ .../Hypergrid/HGFriendsServiceConnector.cs | 312 ---------- .../Hypergrid/HGFriendsServicesConnector.cs | 312 ++++++++++ .../Connectors/Hypergrid/HeloServiceConnector.cs | 100 --- .../Connectors/Hypergrid/HeloServicesConnector.cs | 100 +++ .../Connectors/Inventory/XInventoryConnector.cs | 623 ------------------- .../Inventory/XInventoryServicesConnector.cs | 623 +++++++++++++++++++ .../Connectors/Land/LandServiceConnector.cs | 133 ---- .../Connectors/Land/LandServicesConnector.cs | 133 ++++ .../MapImage/MapImageServiceConnector.cs | 159 ----- .../MapImage/MapImageServicesConnector.cs | 159 +++++ .../Neighbour/NeighbourServiceConnector.cs | 206 ------- .../Neighbour/NeighbourServicesConnector.cs | 206 +++++++ .../Presence/PresenceServiceConnector.cs | 378 ------------ .../Presence/PresenceServicesConnector.cs | 378 ++++++++++++ .../UserAccounts/UserAccountServiceConnector.cs | 287 --------- .../UserAccounts/UserAccountServicesConnector.cs | 287 +++++++++ 30 files changed, 4371 insertions(+), 4371 deletions(-) delete mode 100644 OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs delete mode 100644 OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/Authentication/AuthenticationServicesConnector.cs delete mode 100644 OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/Authorization/AuthorizationServicesConnector.cs delete mode 100644 OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/Avatar/AvatarServicesConnector.cs delete mode 100644 OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/Friends/FriendsServicesConnector.cs delete mode 100644 OpenSim/Services/Connectors/Grid/GridServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/Grid/GridServicesConnector.cs delete mode 100644 OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs delete mode 100644 OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/Hypergrid/HGFriendsServicesConnector.cs delete mode 100644 OpenSim/Services/Connectors/Hypergrid/HeloServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/Hypergrid/HeloServicesConnector.cs delete mode 100644 OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs create mode 100644 OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs delete mode 100644 OpenSim/Services/Connectors/Land/LandServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/Land/LandServicesConnector.cs delete mode 100644 OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/MapImage/MapImageServicesConnector.cs delete mode 100644 OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs delete mode 100644 OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/Presence/PresenceServicesConnector.cs delete mode 100644 OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs deleted file mode 100644 index e4c3eaf..0000000 --- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs +++ /dev/null @@ -1,329 +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 log4net; -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Console; -using OpenSim.Framework.Communications; -using OpenSim.Services.Interfaces; -using OpenMetaverse; - -namespace OpenSim.Services.Connectors -{ - public class AssetServicesConnector : IAssetService - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - private string m_ServerURI = String.Empty; - private IImprovedAssetCache m_Cache = null; - - private delegate void AssetRetrievedEx(AssetBase asset); - - // Keeps track of concurrent requests for the same asset, so that it's only loaded once. - // Maps: Asset ID -> Handlers which will be called when the asset has been loaded - private Dictionary m_AssetHandlers = new Dictionary(); - - - public AssetServicesConnector() - { - } - - public AssetServicesConnector(string serverURI) - { - m_ServerURI = serverURI.TrimEnd('/'); - } - - public AssetServicesConnector(IConfigSource source) - { - Initialise(source); - } - - public virtual void Initialise(IConfigSource source) - { - IConfig assetConfig = source.Configs["AssetService"]; - if (assetConfig == null) - { - m_log.Error("[ASSET CONNECTOR]: AssetService missing from OpenSim.ini"); - throw new Exception("Asset connector init error"); - } - - string serviceURI = assetConfig.GetString("AssetServerURI", - String.Empty); - - if (serviceURI == String.Empty) - { - m_log.Error("[ASSET CONNECTOR]: No Server URI named in section AssetService"); - throw new Exception("Asset connector init error"); - } - - m_ServerURI = serviceURI; - } - - protected void SetCache(IImprovedAssetCache cache) - { - m_Cache = cache; - } - - public AssetBase Get(string id) - { -// m_log.DebugFormat("[ASSET SERVICE CONNECTOR]: Synchronous get request for {0}", id); - - string uri = m_ServerURI + "/assets/" + id; - - AssetBase asset = null; - if (m_Cache != null) - asset = m_Cache.Get(id); - - if (asset == null) - { - asset = SynchronousRestObjectRequester. - MakeRequest("GET", uri, 0); - - if (m_Cache != null) - m_Cache.Cache(asset); - } - return asset; - } - - public AssetBase GetCached(string id) - { -// m_log.DebugFormat("[ASSET SERVICE CONNECTOR]: Cache request for {0}", id); - - if (m_Cache != null) - return m_Cache.Get(id); - - return null; - } - - public AssetMetadata GetMetadata(string id) - { - if (m_Cache != null) - { - AssetBase fullAsset = m_Cache.Get(id); - - if (fullAsset != null) - return fullAsset.Metadata; - } - - string uri = m_ServerURI + "/assets/" + id + "/metadata"; - - AssetMetadata asset = SynchronousRestObjectRequester. - MakeRequest("GET", uri, 0); - return asset; - } - - public byte[] GetData(string id) - { - if (m_Cache != null) - { - AssetBase fullAsset = m_Cache.Get(id); - - if (fullAsset != null) - return fullAsset.Data; - } - - RestClient rc = new RestClient(m_ServerURI); - rc.AddResourcePath("assets"); - rc.AddResourcePath(id); - rc.AddResourcePath("data"); - - rc.RequestMethod = "GET"; - - Stream s = rc.Request(); - - if (s == null) - return null; - - if (s.Length > 0) - { - byte[] ret = new byte[s.Length]; - s.Read(ret, 0, (int)s.Length); - - return ret; - } - - return null; - } - - public bool Get(string id, Object sender, AssetRetrieved handler) - { -// m_log.DebugFormat("[ASSET SERVICE CONNECTOR]: Potentially asynchronous get request for {0}", id); - - string uri = m_ServerURI + "/assets/" + id; - - AssetBase asset = null; - if (m_Cache != null) - asset = m_Cache.Get(id); - - if (asset == null) - { - lock (m_AssetHandlers) - { - AssetRetrievedEx handlerEx = new AssetRetrievedEx(delegate(AssetBase _asset) { handler(id, sender, _asset); }); - - AssetRetrievedEx handlers; - if (m_AssetHandlers.TryGetValue(id, out handlers)) - { - // Someone else is already loading this asset. It will notify our handler when done. - handlers += handlerEx; - return true; - } - - // Load the asset ourselves - handlers += handlerEx; - m_AssetHandlers.Add(id, handlers); - } - - bool success = false; - try - { - AsynchronousRestObjectRequester.MakeRequest("GET", uri, 0, - delegate(AssetBase a) - { - if (m_Cache != null) - m_Cache.Cache(a); - - AssetRetrievedEx handlers; - lock (m_AssetHandlers) - { - handlers = m_AssetHandlers[id]; - m_AssetHandlers.Remove(id); - } - handlers.Invoke(a); - }); - - success = true; - } - finally - { - if (!success) - { - lock (m_AssetHandlers) - { - m_AssetHandlers.Remove(id); - } - } - } - } - else - { - handler(id, sender, asset); - } - - return true; - } - - public string Store(AssetBase asset) - { - if (asset.Temporary || asset.Local) - { - if (m_Cache != null) - m_Cache.Cache(asset); - - return asset.ID; - } - - string uri = m_ServerURI + "/assets/"; - - string newID = string.Empty; - try - { - newID = SynchronousRestObjectRequester. - MakeRequest("POST", uri, asset); - } - catch (Exception e) - { - m_log.WarnFormat("[ASSET CONNECTOR]: Unable to send asset {0} to asset server. Reason: {1}", asset.ID, e.Message); - } - - if (newID != String.Empty) - { - // Placing this here, so that this work with old asset servers that don't send any reply back - // SynchronousRestObjectRequester returns somethins that is not an empty string - if (newID != null) - asset.ID = newID; - - if (m_Cache != null) - m_Cache.Cache(asset); - } - return newID; - } - - public bool UpdateContent(string id, byte[] data) - { - AssetBase asset = null; - - if (m_Cache != null) - asset = m_Cache.Get(id); - - if (asset == null) - { - AssetMetadata metadata = GetMetadata(id); - if (metadata == null) - return false; - - asset = new AssetBase(metadata.FullID, metadata.Name, metadata.Type, UUID.Zero.ToString()); - asset.Metadata = metadata; - } - asset.Data = data; - - string uri = m_ServerURI + "/assets/" + id; - - if (SynchronousRestObjectRequester. - MakeRequest("POST", uri, asset)) - { - if (m_Cache != null) - m_Cache.Cache(asset); - - return true; - } - return false; - } - - public bool Delete(string id) - { - string uri = m_ServerURI + "/assets/" + id; - - if (SynchronousRestObjectRequester. - MakeRequest("DELETE", uri, 0)) - { - if (m_Cache != null) - m_Cache.Expire(id); - - return true; - } - return false; - } - } -} \ No newline at end of file diff --git a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs new file mode 100644 index 0000000..e4c3eaf --- /dev/null +++ b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs @@ -0,0 +1,329 @@ +/* + * 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 log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Communications; +using OpenSim.Services.Interfaces; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors +{ + public class AssetServicesConnector : IAssetService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + private IImprovedAssetCache m_Cache = null; + + private delegate void AssetRetrievedEx(AssetBase asset); + + // Keeps track of concurrent requests for the same asset, so that it's only loaded once. + // Maps: Asset ID -> Handlers which will be called when the asset has been loaded + private Dictionary m_AssetHandlers = new Dictionary(); + + + public AssetServicesConnector() + { + } + + public AssetServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + + public AssetServicesConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig assetConfig = source.Configs["AssetService"]; + if (assetConfig == null) + { + m_log.Error("[ASSET CONNECTOR]: AssetService missing from OpenSim.ini"); + throw new Exception("Asset connector init error"); + } + + string serviceURI = assetConfig.GetString("AssetServerURI", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[ASSET CONNECTOR]: No Server URI named in section AssetService"); + throw new Exception("Asset connector init error"); + } + + m_ServerURI = serviceURI; + } + + protected void SetCache(IImprovedAssetCache cache) + { + m_Cache = cache; + } + + public AssetBase Get(string id) + { +// m_log.DebugFormat("[ASSET SERVICE CONNECTOR]: Synchronous get request for {0}", id); + + string uri = m_ServerURI + "/assets/" + id; + + AssetBase asset = null; + if (m_Cache != null) + asset = m_Cache.Get(id); + + if (asset == null) + { + asset = SynchronousRestObjectRequester. + MakeRequest("GET", uri, 0); + + if (m_Cache != null) + m_Cache.Cache(asset); + } + return asset; + } + + public AssetBase GetCached(string id) + { +// m_log.DebugFormat("[ASSET SERVICE CONNECTOR]: Cache request for {0}", id); + + if (m_Cache != null) + return m_Cache.Get(id); + + return null; + } + + public AssetMetadata GetMetadata(string id) + { + if (m_Cache != null) + { + AssetBase fullAsset = m_Cache.Get(id); + + if (fullAsset != null) + return fullAsset.Metadata; + } + + string uri = m_ServerURI + "/assets/" + id + "/metadata"; + + AssetMetadata asset = SynchronousRestObjectRequester. + MakeRequest("GET", uri, 0); + return asset; + } + + public byte[] GetData(string id) + { + if (m_Cache != null) + { + AssetBase fullAsset = m_Cache.Get(id); + + if (fullAsset != null) + return fullAsset.Data; + } + + RestClient rc = new RestClient(m_ServerURI); + rc.AddResourcePath("assets"); + rc.AddResourcePath(id); + rc.AddResourcePath("data"); + + rc.RequestMethod = "GET"; + + Stream s = rc.Request(); + + if (s == null) + return null; + + if (s.Length > 0) + { + byte[] ret = new byte[s.Length]; + s.Read(ret, 0, (int)s.Length); + + return ret; + } + + return null; + } + + public bool Get(string id, Object sender, AssetRetrieved handler) + { +// m_log.DebugFormat("[ASSET SERVICE CONNECTOR]: Potentially asynchronous get request for {0}", id); + + string uri = m_ServerURI + "/assets/" + id; + + AssetBase asset = null; + if (m_Cache != null) + asset = m_Cache.Get(id); + + if (asset == null) + { + lock (m_AssetHandlers) + { + AssetRetrievedEx handlerEx = new AssetRetrievedEx(delegate(AssetBase _asset) { handler(id, sender, _asset); }); + + AssetRetrievedEx handlers; + if (m_AssetHandlers.TryGetValue(id, out handlers)) + { + // Someone else is already loading this asset. It will notify our handler when done. + handlers += handlerEx; + return true; + } + + // Load the asset ourselves + handlers += handlerEx; + m_AssetHandlers.Add(id, handlers); + } + + bool success = false; + try + { + AsynchronousRestObjectRequester.MakeRequest("GET", uri, 0, + delegate(AssetBase a) + { + if (m_Cache != null) + m_Cache.Cache(a); + + AssetRetrievedEx handlers; + lock (m_AssetHandlers) + { + handlers = m_AssetHandlers[id]; + m_AssetHandlers.Remove(id); + } + handlers.Invoke(a); + }); + + success = true; + } + finally + { + if (!success) + { + lock (m_AssetHandlers) + { + m_AssetHandlers.Remove(id); + } + } + } + } + else + { + handler(id, sender, asset); + } + + return true; + } + + public string Store(AssetBase asset) + { + if (asset.Temporary || asset.Local) + { + if (m_Cache != null) + m_Cache.Cache(asset); + + return asset.ID; + } + + string uri = m_ServerURI + "/assets/"; + + string newID = string.Empty; + try + { + newID = SynchronousRestObjectRequester. + MakeRequest("POST", uri, asset); + } + catch (Exception e) + { + m_log.WarnFormat("[ASSET CONNECTOR]: Unable to send asset {0} to asset server. Reason: {1}", asset.ID, e.Message); + } + + if (newID != String.Empty) + { + // Placing this here, so that this work with old asset servers that don't send any reply back + // SynchronousRestObjectRequester returns somethins that is not an empty string + if (newID != null) + asset.ID = newID; + + if (m_Cache != null) + m_Cache.Cache(asset); + } + return newID; + } + + public bool UpdateContent(string id, byte[] data) + { + AssetBase asset = null; + + if (m_Cache != null) + asset = m_Cache.Get(id); + + if (asset == null) + { + AssetMetadata metadata = GetMetadata(id); + if (metadata == null) + return false; + + asset = new AssetBase(metadata.FullID, metadata.Name, metadata.Type, UUID.Zero.ToString()); + asset.Metadata = metadata; + } + asset.Data = data; + + string uri = m_ServerURI + "/assets/" + id; + + if (SynchronousRestObjectRequester. + MakeRequest("POST", uri, asset)) + { + if (m_Cache != null) + m_Cache.Cache(asset); + + return true; + } + return false; + } + + public bool Delete(string id) + { + string uri = m_ServerURI + "/assets/" + id; + + if (SynchronousRestObjectRequester. + MakeRequest("DELETE", uri, 0)) + { + if (m_Cache != null) + m_Cache.Expire(id); + + return true; + } + return false; + } + } +} \ No newline at end of file diff --git a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs deleted file mode 100644 index 2b77154..0000000 --- a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs +++ /dev/null @@ -1,167 +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 log4net; -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Services.Interfaces; -using OpenSim.Server.Base; -using OpenMetaverse; - -namespace OpenSim.Services.Connectors -{ - public class AuthenticationServicesConnector : IAuthenticationService - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - private string m_ServerURI = String.Empty; - - public AuthenticationServicesConnector() - { - } - - public AuthenticationServicesConnector(string serverURI) - { - m_ServerURI = serverURI.TrimEnd('/'); - } - - public AuthenticationServicesConnector(IConfigSource source) - { - Initialise(source); - } - - public virtual void Initialise(IConfigSource source) - { - IConfig assetConfig = source.Configs["AuthenticationService"]; - if (assetConfig == null) - { - m_log.Error("[AUTH CONNECTOR]: AuthenticationService missing from OpenSim.ini"); - throw new Exception("Authentication connector init error"); - } - - string serviceURI = assetConfig.GetString("AuthenticationServerURI", - String.Empty); - - if (serviceURI == String.Empty) - { - m_log.Error("[AUTH CONNECTOR]: No Server URI named in section AuthenticationService"); - throw new Exception("Authentication connector init error"); - } - m_ServerURI = serviceURI; - } - - public string Authenticate(UUID principalID, string password, int lifetime) - { - Dictionary sendData = new Dictionary(); - sendData["LIFETIME"] = lifetime.ToString(); - sendData["PRINCIPAL"] = principalID.ToString(); - sendData["PASSWORD"] = password; - - sendData["METHOD"] = "authenticate"; - - string reply = SynchronousRestFormsRequester.MakeRequest("POST", - m_ServerURI + "/auth/plain", - ServerUtils.BuildQueryString(sendData)); - - Dictionary replyData = ServerUtils.ParseXmlResponse( - reply); - - if (replyData["Result"].ToString() != "Success") - return String.Empty; - - return replyData["Token"].ToString(); - } - - public bool Verify(UUID principalID, string token, int lifetime) - { - Dictionary sendData = new Dictionary(); - sendData["LIFETIME"] = lifetime.ToString(); - sendData["PRINCIPAL"] = principalID.ToString(); - sendData["TOKEN"] = token; - - sendData["METHOD"] = "verify"; - - string reply = SynchronousRestFormsRequester.MakeRequest("POST", - m_ServerURI + "/auth/plain", - ServerUtils.BuildQueryString(sendData)); - - Dictionary replyData = ServerUtils.ParseXmlResponse( - reply); - - if (replyData["Result"].ToString() != "Success") - return false; - - return true; - } - - public bool Release(UUID principalID, string token) - { - Dictionary sendData = new Dictionary(); - sendData["PRINCIPAL"] = principalID.ToString(); - sendData["TOKEN"] = token; - - sendData["METHOD"] = "release"; - - string reply = SynchronousRestFormsRequester.MakeRequest("POST", - m_ServerURI + "/auth/plain", - ServerUtils.BuildQueryString(sendData)); - - Dictionary replyData = ServerUtils.ParseXmlResponse( - reply); - - if (replyData["Result"].ToString() != "Success") - return false; - - return true; - } - - public bool SetPassword(UUID principalID, string passwd) - { - // nope, we don't do this - return false; - } - - public AuthInfo GetAuthInfo(UUID principalID) - { - // not done from remote simulators - return null; - } - - public bool SetAuthInfo(AuthInfo info) - { - // not done from remote simulators - return false; - } - } -} diff --git a/OpenSim/Services/Connectors/Authentication/AuthenticationServicesConnector.cs b/OpenSim/Services/Connectors/Authentication/AuthenticationServicesConnector.cs new file mode 100644 index 0000000..2b77154 --- /dev/null +++ b/OpenSim/Services/Connectors/Authentication/AuthenticationServicesConnector.cs @@ -0,0 +1,167 @@ +/* + * 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 log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Services.Interfaces; +using OpenSim.Server.Base; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors +{ + public class AuthenticationServicesConnector : IAuthenticationService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + + public AuthenticationServicesConnector() + { + } + + public AuthenticationServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + + public AuthenticationServicesConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig assetConfig = source.Configs["AuthenticationService"]; + if (assetConfig == null) + { + m_log.Error("[AUTH CONNECTOR]: AuthenticationService missing from OpenSim.ini"); + throw new Exception("Authentication connector init error"); + } + + string serviceURI = assetConfig.GetString("AuthenticationServerURI", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[AUTH CONNECTOR]: No Server URI named in section AuthenticationService"); + throw new Exception("Authentication connector init error"); + } + m_ServerURI = serviceURI; + } + + public string Authenticate(UUID principalID, string password, int lifetime) + { + Dictionary sendData = new Dictionary(); + sendData["LIFETIME"] = lifetime.ToString(); + sendData["PRINCIPAL"] = principalID.ToString(); + sendData["PASSWORD"] = password; + + sendData["METHOD"] = "authenticate"; + + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + m_ServerURI + "/auth/plain", + ServerUtils.BuildQueryString(sendData)); + + Dictionary replyData = ServerUtils.ParseXmlResponse( + reply); + + if (replyData["Result"].ToString() != "Success") + return String.Empty; + + return replyData["Token"].ToString(); + } + + public bool Verify(UUID principalID, string token, int lifetime) + { + Dictionary sendData = new Dictionary(); + sendData["LIFETIME"] = lifetime.ToString(); + sendData["PRINCIPAL"] = principalID.ToString(); + sendData["TOKEN"] = token; + + sendData["METHOD"] = "verify"; + + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + m_ServerURI + "/auth/plain", + ServerUtils.BuildQueryString(sendData)); + + Dictionary replyData = ServerUtils.ParseXmlResponse( + reply); + + if (replyData["Result"].ToString() != "Success") + return false; + + return true; + } + + public bool Release(UUID principalID, string token) + { + Dictionary sendData = new Dictionary(); + sendData["PRINCIPAL"] = principalID.ToString(); + sendData["TOKEN"] = token; + + sendData["METHOD"] = "release"; + + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + m_ServerURI + "/auth/plain", + ServerUtils.BuildQueryString(sendData)); + + Dictionary replyData = ServerUtils.ParseXmlResponse( + reply); + + if (replyData["Result"].ToString() != "Success") + return false; + + return true; + } + + public bool SetPassword(UUID principalID, string passwd) + { + // nope, we don't do this + return false; + } + + public AuthInfo GetAuthInfo(UUID principalID) + { + // not done from remote simulators + return null; + } + + public bool SetAuthInfo(AuthInfo info) + { + // not done from remote simulators + return false; + } + } +} diff --git a/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs b/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs deleted file mode 100644 index 35b7109..0000000 --- a/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs +++ /dev/null @@ -1,123 +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 log4net; -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Services.Interfaces; -using OpenMetaverse; - -namespace OpenSim.Services.Connectors -{ - public class AuthorizationServicesConnector - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - private string m_ServerURI = String.Empty; - private bool m_ResponseOnFailure = true; - - public AuthorizationServicesConnector() - { - } - - public AuthorizationServicesConnector(string serverURI) - { - m_ServerURI = serverURI.TrimEnd('/'); - } - - public AuthorizationServicesConnector(IConfigSource source) - { - Initialise(source); - } - - public virtual void Initialise(IConfigSource source) - { - IConfig authorizationConfig = source.Configs["AuthorizationService"]; - if (authorizationConfig == null) - { - //m_log.Info("[AUTHORIZATION CONNECTOR]: AuthorizationService missing from OpenSim.ini"); - throw new Exception("Authorization connector init error"); - } - - string serviceURI = authorizationConfig.GetString("AuthorizationServerURI", - String.Empty); - - if (serviceURI == String.Empty) - { - m_log.Error("[AUTHORIZATION CONNECTOR]: No Server URI named in section AuthorizationService"); - throw new Exception("Authorization connector init error"); - } - m_ServerURI = serviceURI; - - // this dictates what happens if the remote service fails, if the service fails and the value is true - // the user is authorized for the region. - bool responseOnFailure = authorizationConfig.GetBoolean("ResponseOnFailure",true); - - m_ResponseOnFailure = responseOnFailure; - m_log.Info("[AUTHORIZATION CONNECTOR]: AuthorizationService initialized"); - } - - public bool IsAuthorizedForRegion(string userID, string firstname, string surname, string email, string regionName, string regionID, out string message) - { - // do a remote call to the authorization server specified in the AuthorizationServerURI - m_log.InfoFormat("[AUTHORIZATION CONNECTOR]: IsAuthorizedForRegion checking {0} at remote server {1}", userID, m_ServerURI); - - string uri = m_ServerURI; - - AuthorizationRequest req = new AuthorizationRequest(userID, firstname, surname, email, regionName, regionID); - - AuthorizationResponse response; - try - { - response = SynchronousRestObjectRequester.MakeRequest("POST", uri, req); - } - catch (Exception e) - { - m_log.WarnFormat("[AUTHORIZATION CONNECTOR]: Unable to send authorize {0} for region {1} error thrown during comms with remote server. Reason: {2}", userID, regionID, e.Message); - message = ""; - return m_ResponseOnFailure; - } - if (response == null) - { - message = "Null response"; - return m_ResponseOnFailure; - } - m_log.DebugFormat("[AUTHORIZATION CONNECTOR] response from remote service was {0}", response.Message); - message = response.Message; - - return response.IsAuthorized; - } - - } -} diff --git a/OpenSim/Services/Connectors/Authorization/AuthorizationServicesConnector.cs b/OpenSim/Services/Connectors/Authorization/AuthorizationServicesConnector.cs new file mode 100644 index 0000000..35b7109 --- /dev/null +++ b/OpenSim/Services/Connectors/Authorization/AuthorizationServicesConnector.cs @@ -0,0 +1,123 @@ +/* + * 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 log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Services.Interfaces; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors +{ + public class AuthorizationServicesConnector + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + private bool m_ResponseOnFailure = true; + + public AuthorizationServicesConnector() + { + } + + public AuthorizationServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + + public AuthorizationServicesConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig authorizationConfig = source.Configs["AuthorizationService"]; + if (authorizationConfig == null) + { + //m_log.Info("[AUTHORIZATION CONNECTOR]: AuthorizationService missing from OpenSim.ini"); + throw new Exception("Authorization connector init error"); + } + + string serviceURI = authorizationConfig.GetString("AuthorizationServerURI", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[AUTHORIZATION CONNECTOR]: No Server URI named in section AuthorizationService"); + throw new Exception("Authorization connector init error"); + } + m_ServerURI = serviceURI; + + // this dictates what happens if the remote service fails, if the service fails and the value is true + // the user is authorized for the region. + bool responseOnFailure = authorizationConfig.GetBoolean("ResponseOnFailure",true); + + m_ResponseOnFailure = responseOnFailure; + m_log.Info("[AUTHORIZATION CONNECTOR]: AuthorizationService initialized"); + } + + public bool IsAuthorizedForRegion(string userID, string firstname, string surname, string email, string regionName, string regionID, out string message) + { + // do a remote call to the authorization server specified in the AuthorizationServerURI + m_log.InfoFormat("[AUTHORIZATION CONNECTOR]: IsAuthorizedForRegion checking {0} at remote server {1}", userID, m_ServerURI); + + string uri = m_ServerURI; + + AuthorizationRequest req = new AuthorizationRequest(userID, firstname, surname, email, regionName, regionID); + + AuthorizationResponse response; + try + { + response = SynchronousRestObjectRequester.MakeRequest("POST", uri, req); + } + catch (Exception e) + { + m_log.WarnFormat("[AUTHORIZATION CONNECTOR]: Unable to send authorize {0} for region {1} error thrown during comms with remote server. Reason: {2}", userID, regionID, e.Message); + message = ""; + return m_ResponseOnFailure; + } + if (response == null) + { + message = "Null response"; + return m_ResponseOnFailure; + } + m_log.DebugFormat("[AUTHORIZATION CONNECTOR] response from remote service was {0}", response.Message); + message = response.Message; + + return response.IsAuthorized; + } + + } +} diff --git a/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs b/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs deleted file mode 100644 index ddfca57..0000000 --- a/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs +++ /dev/null @@ -1,326 +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 log4net; -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Services.Interfaces; -using GridRegion = OpenSim.Services.Interfaces.GridRegion; -using IAvatarService = OpenSim.Services.Interfaces.IAvatarService; -using OpenSim.Server.Base; -using OpenMetaverse; - -namespace OpenSim.Services.Connectors -{ - public class AvatarServicesConnector : IAvatarService - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - private string m_ServerURI = String.Empty; - - public AvatarServicesConnector() - { - } - - public AvatarServicesConnector(string serverURI) - { - m_ServerURI = serverURI.TrimEnd('/'); - } - - public AvatarServicesConnector(IConfigSource source) - { - Initialise(source); - } - - public virtual void Initialise(IConfigSource source) - { - IConfig gridConfig = source.Configs["AvatarService"]; - if (gridConfig == null) - { - m_log.Error("[AVATAR CONNECTOR]: AvatarService missing from OpenSim.ini"); - throw new Exception("Avatar connector init error"); - } - - string serviceURI = gridConfig.GetString("AvatarServerURI", - String.Empty); - - if (serviceURI == String.Empty) - { - m_log.Error("[AVATAR CONNECTOR]: No Server URI named in section AvatarService"); - throw new Exception("Avatar connector init error"); - } - m_ServerURI = serviceURI; - } - - - #region IAvatarService - - public AvatarAppearance GetAppearance(UUID userID) - { - AvatarData avatar = GetAvatar(userID); - return avatar.ToAvatarAppearance(); - } - - public bool SetAppearance(UUID userID, AvatarAppearance appearance) - { - AvatarData avatar = new AvatarData(appearance); - return SetAvatar(userID,avatar); - } - - public AvatarData GetAvatar(UUID userID) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "getavatar"; - - sendData["UserID"] = userID; - - string reply = string.Empty; - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/avatar"; - // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString); - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); - if (reply == null || (reply != null && reply == string.Empty)) - { - m_log.DebugFormat("[AVATAR CONNECTOR]: GetAgent received null or empty reply"); - return null; - } - } - catch (Exception e) - { - m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); - } - - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - AvatarData avatar = null; - - if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null)) - { - if (replyData["result"] is Dictionary) - { - avatar = new AvatarData((Dictionary)replyData["result"]); - } - } - - return avatar; - - } - - public bool SetAvatar(UUID userID, AvatarData avatar) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "setavatar"; - - sendData["UserID"] = userID.ToString(); - - Dictionary structData = avatar.ToKeyValuePairs(); - - foreach (KeyValuePair kvp in structData) - sendData[kvp.Key] = kvp.Value.ToString(); - - - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/avatar"; - //m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString); - try - { - string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData.ContainsKey("result")) - { - if (replyData["result"].ToString().ToLower() == "success") - return true; - else - return false; - } - else - { - m_log.DebugFormat("[AVATAR CONNECTOR]: SetAvatar reply data does not contain result field"); - } - } - else - { - m_log.DebugFormat("[AVATAR CONNECTOR]: SetAvatar received empty reply"); - } - } - catch (Exception e) - { - m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); - } - - return false; - } - - public bool ResetAvatar(UUID userID) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "resetavatar"; - - sendData["UserID"] = userID.ToString(); - - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/avatar"; - // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString); - try - { - string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData.ContainsKey("result")) - { - if (replyData["result"].ToString().ToLower() == "success") - return true; - else - return false; - } - else - m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems reply data does not contain result field"); - - } - else - m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems received empty reply"); - } - catch (Exception e) - { - m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); - } - - return false; - } - - public bool SetItems(UUID userID, string[] names, string[] values) - { - Dictionary sendData = new Dictionary(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "setitems"; - - sendData["UserID"] = userID.ToString(); - sendData["Names"] = new List(names); - sendData["Values"] = new List(values); - - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/avatar"; - // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString); - try - { - string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData.ContainsKey("result")) - { - if (replyData["result"].ToString().ToLower() == "success") - return true; - else - return false; - } - else - m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems reply data does not contain result field"); - - } - else - m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems received empty reply"); - } - catch (Exception e) - { - m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); - } - - return false; - } - - public bool RemoveItems(UUID userID, string[] names) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "removeitems"; - - sendData["UserID"] = userID.ToString(); - sendData["Names"] = new List(names); - - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/avatar"; - // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString); - try - { - string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData.ContainsKey("result")) - { - if (replyData["result"].ToString().ToLower() == "success") - return true; - else - return false; - } - else - m_log.DebugFormat("[AVATAR CONNECTOR]: RemoveItems reply data does not contain result field"); - - } - else - m_log.DebugFormat("[AVATAR CONNECTOR]: RemoveItems received empty reply"); - } - catch (Exception e) - { - m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); - } - - return false; - } - - #endregion - - } -} diff --git a/OpenSim/Services/Connectors/Avatar/AvatarServicesConnector.cs b/OpenSim/Services/Connectors/Avatar/AvatarServicesConnector.cs new file mode 100644 index 0000000..ddfca57 --- /dev/null +++ b/OpenSim/Services/Connectors/Avatar/AvatarServicesConnector.cs @@ -0,0 +1,326 @@ +/* + * 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 log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Services.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using IAvatarService = OpenSim.Services.Interfaces.IAvatarService; +using OpenSim.Server.Base; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors +{ + public class AvatarServicesConnector : IAvatarService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + + public AvatarServicesConnector() + { + } + + public AvatarServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + + public AvatarServicesConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig gridConfig = source.Configs["AvatarService"]; + if (gridConfig == null) + { + m_log.Error("[AVATAR CONNECTOR]: AvatarService missing from OpenSim.ini"); + throw new Exception("Avatar connector init error"); + } + + string serviceURI = gridConfig.GetString("AvatarServerURI", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[AVATAR CONNECTOR]: No Server URI named in section AvatarService"); + throw new Exception("Avatar connector init error"); + } + m_ServerURI = serviceURI; + } + + + #region IAvatarService + + public AvatarAppearance GetAppearance(UUID userID) + { + AvatarData avatar = GetAvatar(userID); + return avatar.ToAvatarAppearance(); + } + + public bool SetAppearance(UUID userID, AvatarAppearance appearance) + { + AvatarData avatar = new AvatarData(appearance); + return SetAvatar(userID,avatar); + } + + public AvatarData GetAvatar(UUID userID) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "getavatar"; + + sendData["UserID"] = userID; + + string reply = string.Empty; + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/avatar"; + // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString); + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); + if (reply == null || (reply != null && reply == string.Empty)) + { + m_log.DebugFormat("[AVATAR CONNECTOR]: GetAgent received null or empty reply"); + return null; + } + } + catch (Exception e) + { + m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); + } + + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + AvatarData avatar = null; + + if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null)) + { + if (replyData["result"] is Dictionary) + { + avatar = new AvatarData((Dictionary)replyData["result"]); + } + } + + return avatar; + + } + + public bool SetAvatar(UUID userID, AvatarData avatar) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "setavatar"; + + sendData["UserID"] = userID.ToString(); + + Dictionary structData = avatar.ToKeyValuePairs(); + + foreach (KeyValuePair kvp in structData) + sendData[kvp.Key] = kvp.Value.ToString(); + + + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/avatar"; + //m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString); + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("result")) + { + if (replyData["result"].ToString().ToLower() == "success") + return true; + else + return false; + } + else + { + m_log.DebugFormat("[AVATAR CONNECTOR]: SetAvatar reply data does not contain result field"); + } + } + else + { + m_log.DebugFormat("[AVATAR CONNECTOR]: SetAvatar received empty reply"); + } + } + catch (Exception e) + { + m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); + } + + return false; + } + + public bool ResetAvatar(UUID userID) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "resetavatar"; + + sendData["UserID"] = userID.ToString(); + + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/avatar"; + // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString); + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("result")) + { + if (replyData["result"].ToString().ToLower() == "success") + return true; + else + return false; + } + else + m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems reply data does not contain result field"); + + } + else + m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems received empty reply"); + } + catch (Exception e) + { + m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); + } + + return false; + } + + public bool SetItems(UUID userID, string[] names, string[] values) + { + Dictionary sendData = new Dictionary(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "setitems"; + + sendData["UserID"] = userID.ToString(); + sendData["Names"] = new List(names); + sendData["Values"] = new List(values); + + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/avatar"; + // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString); + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("result")) + { + if (replyData["result"].ToString().ToLower() == "success") + return true; + else + return false; + } + else + m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems reply data does not contain result field"); + + } + else + m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems received empty reply"); + } + catch (Exception e) + { + m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); + } + + return false; + } + + public bool RemoveItems(UUID userID, string[] names) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "removeitems"; + + sendData["UserID"] = userID.ToString(); + sendData["Names"] = new List(names); + + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/avatar"; + // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString); + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("result")) + { + if (replyData["result"].ToString().ToLower() == "success") + return true; + else + return false; + } + else + m_log.DebugFormat("[AVATAR CONNECTOR]: RemoveItems reply data does not contain result field"); + + } + else + m_log.DebugFormat("[AVATAR CONNECTOR]: RemoveItems received empty reply"); + } + catch (Exception e) + { + m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); + } + + return false; + } + + #endregion + + } +} diff --git a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs deleted file mode 100644 index b1dd84e..0000000 --- a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs +++ /dev/null @@ -1,267 +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 log4net; -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Services.Interfaces; -using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; -using OpenSim.Server.Base; -using OpenMetaverse; - -namespace OpenSim.Services.Connectors.Friends -{ - public class FriendsServicesConnector : IFriendsService - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - private string m_ServerURI = String.Empty; - - public FriendsServicesConnector() - { - } - - public FriendsServicesConnector(string serverURI) - { - m_ServerURI = serverURI.TrimEnd('/'); - } - - public FriendsServicesConnector(IConfigSource source) - { - Initialise(source); - } - - public virtual void Initialise(IConfigSource source) - { - IConfig gridConfig = source.Configs["FriendsService"]; - if (gridConfig == null) - { - m_log.Error("[FRIENDS SERVICE CONNECTOR]: FriendsService missing from OpenSim.ini"); - throw new Exception("Friends connector init error"); - } - - string serviceURI = gridConfig.GetString("FriendsServerURI", - String.Empty); - - if (serviceURI == String.Empty) - { - m_log.Error("[FRIENDS SERVICE CONNECTOR]: No Server URI named in section FriendsService"); - throw new Exception("Friends connector init error"); - } - m_ServerURI = serviceURI; - } - - - #region IFriendsService - - public FriendInfo[] GetFriends(UUID PrincipalID) - { - Dictionary sendData = new Dictionary(); - - sendData["PRINCIPALID"] = PrincipalID.ToString(); - sendData["METHOD"] = "getfriends"; - - return GetFriends(sendData, PrincipalID.ToString()); - } - - public FriendInfo[] GetFriends(string PrincipalID) - { - Dictionary sendData = new Dictionary(); - - sendData["PRINCIPALID"] = PrincipalID; - sendData["METHOD"] = "getfriends_string"; - - return GetFriends(sendData, PrincipalID); - } - - protected FriendInfo[] GetFriends(Dictionary sendData, string PrincipalID) - { - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/friends"; - - try - { - string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData != null) - { - if (replyData.ContainsKey("result") && (replyData["result"].ToString().ToLower() == "null")) - { - return new FriendInfo[0]; - } - - List finfos = new List(); - Dictionary.ValueCollection finfosList = replyData.Values; - //m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: get neighbours returned {0} elements", rinfosList.Count); - foreach (object f in finfosList) - { - if (f is Dictionary) - { - FriendInfo finfo = new FriendInfo((Dictionary)f); - finfos.Add(finfo); - } - else - m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: GetFriends {0} received invalid response type {1}", - PrincipalID, f.GetType()); - } - - // Success - return finfos.ToArray(); - } - else - m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: GetFriends {0} received null response", - PrincipalID); - - } - } - catch (Exception e) - { - m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message); - } - - return new FriendInfo[0]; - - } - - public bool StoreFriend(string PrincipalID, string Friend, int flags) - { - - Dictionary sendData = ToKeyValuePairs(PrincipalID, Friend, flags); - - sendData["METHOD"] = "storefriend"; - - string reply = string.Empty; - string uri = m_ServerURI + "/friends"; - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData)); - } - catch (Exception e) - { - m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message); - return false; - } - - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null)) - { - bool success = false; - Boolean.TryParse(replyData["Result"].ToString(), out success); - return success; - } - else - m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: StoreFriend {0} {1} received null response", - PrincipalID, Friend); - } - else - m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: StoreFriend received null reply"); - - return false; - - } - - public bool Delete(string PrincipalID, string Friend) - { - Dictionary sendData = new Dictionary(); - sendData["PRINCIPALID"] = PrincipalID.ToString(); - sendData["FRIEND"] = Friend; - sendData["METHOD"] = "deletefriend_string"; - - return Delete(sendData, PrincipalID, Friend); - } - - public bool Delete(UUID PrincipalID, string Friend) - { - Dictionary sendData = new Dictionary(); - sendData["PRINCIPALID"] = PrincipalID.ToString(); - sendData["FRIEND"] = Friend; - sendData["METHOD"] = "deletefriend"; - - return Delete(sendData, PrincipalID.ToString(), Friend); - } - - public bool Delete(Dictionary sendData, string PrincipalID, string Friend) - { - string reply = string.Empty; - string uri = m_ServerURI + "/friends"; - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData)); - } - catch (Exception e) - { - m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message); - return false; - } - - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null)) - { - bool success = false; - Boolean.TryParse(replyData["Result"].ToString(), out success); - return success; - } - else - m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: DeleteFriend {0} {1} received null response", - PrincipalID, Friend); - } - else - m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: DeleteFriend received null reply"); - - return false; - } - - #endregion - - public Dictionary ToKeyValuePairs(string principalID, string friend, int flags) - { - Dictionary result = new Dictionary(); - result["PrincipalID"] = principalID; - result["Friend"] = friend; - result["MyFlags"] = flags; - - return result; - } - - } -} \ No newline at end of file diff --git a/OpenSim/Services/Connectors/Friends/FriendsServicesConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsServicesConnector.cs new file mode 100644 index 0000000..b1dd84e --- /dev/null +++ b/OpenSim/Services/Connectors/Friends/FriendsServicesConnector.cs @@ -0,0 +1,267 @@ +/* + * 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 log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Services.Interfaces; +using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; +using OpenSim.Server.Base; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors.Friends +{ + public class FriendsServicesConnector : IFriendsService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + + public FriendsServicesConnector() + { + } + + public FriendsServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + + public FriendsServicesConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig gridConfig = source.Configs["FriendsService"]; + if (gridConfig == null) + { + m_log.Error("[FRIENDS SERVICE CONNECTOR]: FriendsService missing from OpenSim.ini"); + throw new Exception("Friends connector init error"); + } + + string serviceURI = gridConfig.GetString("FriendsServerURI", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[FRIENDS SERVICE CONNECTOR]: No Server URI named in section FriendsService"); + throw new Exception("Friends connector init error"); + } + m_ServerURI = serviceURI; + } + + + #region IFriendsService + + public FriendInfo[] GetFriends(UUID PrincipalID) + { + Dictionary sendData = new Dictionary(); + + sendData["PRINCIPALID"] = PrincipalID.ToString(); + sendData["METHOD"] = "getfriends"; + + return GetFriends(sendData, PrincipalID.ToString()); + } + + public FriendInfo[] GetFriends(string PrincipalID) + { + Dictionary sendData = new Dictionary(); + + sendData["PRINCIPALID"] = PrincipalID; + sendData["METHOD"] = "getfriends_string"; + + return GetFriends(sendData, PrincipalID); + } + + protected FriendInfo[] GetFriends(Dictionary sendData, string PrincipalID) + { + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/friends"; + + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData != null) + { + if (replyData.ContainsKey("result") && (replyData["result"].ToString().ToLower() == "null")) + { + return new FriendInfo[0]; + } + + List finfos = new List(); + Dictionary.ValueCollection finfosList = replyData.Values; + //m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: get neighbours returned {0} elements", rinfosList.Count); + foreach (object f in finfosList) + { + if (f is Dictionary) + { + FriendInfo finfo = new FriendInfo((Dictionary)f); + finfos.Add(finfo); + } + else + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: GetFriends {0} received invalid response type {1}", + PrincipalID, f.GetType()); + } + + // Success + return finfos.ToArray(); + } + else + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: GetFriends {0} received null response", + PrincipalID); + + } + } + catch (Exception e) + { + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message); + } + + return new FriendInfo[0]; + + } + + public bool StoreFriend(string PrincipalID, string Friend, int flags) + { + + Dictionary sendData = ToKeyValuePairs(PrincipalID, Friend, flags); + + sendData["METHOD"] = "storefriend"; + + string reply = string.Empty; + string uri = m_ServerURI + "/friends"; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData)); + } + catch (Exception e) + { + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message); + return false; + } + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null)) + { + bool success = false; + Boolean.TryParse(replyData["Result"].ToString(), out success); + return success; + } + else + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: StoreFriend {0} {1} received null response", + PrincipalID, Friend); + } + else + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: StoreFriend received null reply"); + + return false; + + } + + public bool Delete(string PrincipalID, string Friend) + { + Dictionary sendData = new Dictionary(); + sendData["PRINCIPALID"] = PrincipalID.ToString(); + sendData["FRIEND"] = Friend; + sendData["METHOD"] = "deletefriend_string"; + + return Delete(sendData, PrincipalID, Friend); + } + + public bool Delete(UUID PrincipalID, string Friend) + { + Dictionary sendData = new Dictionary(); + sendData["PRINCIPALID"] = PrincipalID.ToString(); + sendData["FRIEND"] = Friend; + sendData["METHOD"] = "deletefriend"; + + return Delete(sendData, PrincipalID.ToString(), Friend); + } + + public bool Delete(Dictionary sendData, string PrincipalID, string Friend) + { + string reply = string.Empty; + string uri = m_ServerURI + "/friends"; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData)); + } + catch (Exception e) + { + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message); + return false; + } + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null)) + { + bool success = false; + Boolean.TryParse(replyData["Result"].ToString(), out success); + return success; + } + else + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: DeleteFriend {0} {1} received null response", + PrincipalID, Friend); + } + else + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: DeleteFriend received null reply"); + + return false; + } + + #endregion + + public Dictionary ToKeyValuePairs(string principalID, string friend, int flags) + { + Dictionary result = new Dictionary(); + result["PrincipalID"] = principalID; + result["Friend"] = friend; + result["MyFlags"] = flags; + + return result; + } + + } +} \ No newline at end of file diff --git a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs deleted file mode 100644 index 34ed0d7..0000000 --- a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs +++ /dev/null @@ -1,671 +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 log4net; -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Services.Interfaces; -using GridRegion = OpenSim.Services.Interfaces.GridRegion; -using OpenSim.Server.Base; -using OpenMetaverse; - -namespace OpenSim.Services.Connectors -{ - public class GridServicesConnector : IGridService - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - private string m_ServerURI = String.Empty; - - public GridServicesConnector() - { - } - - public GridServicesConnector(string serverURI) - { - m_ServerURI = serverURI.TrimEnd('/'); - } - - public GridServicesConnector(IConfigSource source) - { - Initialise(source); - } - - public virtual void Initialise(IConfigSource source) - { - IConfig gridConfig = source.Configs["GridService"]; - if (gridConfig == null) - { - m_log.Error("[GRID CONNECTOR]: GridService missing from OpenSim.ini"); - throw new Exception("Grid connector init error"); - } - - string serviceURI = gridConfig.GetString("GridServerURI", - String.Empty); - - if (serviceURI == String.Empty) - { - m_log.Error("[GRID CONNECTOR]: No Server URI named in section GridService"); - throw new Exception("Grid connector init error"); - } - m_ServerURI = serviceURI; - } - - - #region IGridService - - public string RegisterRegion(UUID scopeID, GridRegion regionInfo) - { - Dictionary rinfo = regionInfo.ToKeyValuePairs(); - Dictionary sendData = new Dictionary(); - foreach (KeyValuePair kvp in rinfo) - sendData[kvp.Key] = (string)kvp.Value; - - sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "register"; - - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/grid"; - // m_log.DebugFormat("[GRID CONNECTOR]: queryString = {0}", reqString); - try - { - string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData.ContainsKey("Result")&& (replyData["Result"].ToString().ToLower() == "success")) - { - return String.Empty; - } - else if (replyData.ContainsKey("Result")&& (replyData["Result"].ToString().ToLower() == "failure")) - { - m_log.ErrorFormat( - "[GRID CONNECTOR]: Registration failed: {0} when contacting {1}", replyData["Message"], uri); - - return replyData["Message"].ToString(); - } - else if (!replyData.ContainsKey("Result")) - { - m_log.ErrorFormat( - "[GRID CONNECTOR]: reply data does not contain result field when contacting {0}", uri); - } - else - { - m_log.ErrorFormat( - "[GRID CONNECTOR]: unexpected result {0} when contacting {1}", replyData["Result"], uri); - - return "Unexpected result " + replyData["Result"].ToString(); - } - } - else - { - m_log.ErrorFormat( - "[GRID CONNECTOR]: RegisterRegion received null reply when contacting grid server at {0}", uri); - } - } - catch (Exception e) - { - m_log.ErrorFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); - } - - return string.Format("Error communicating with the grid service at {0}", uri); - } - - public bool DeregisterRegion(UUID regionID) - { - Dictionary sendData = new Dictionary(); - - sendData["REGIONID"] = regionID.ToString(); - - sendData["METHOD"] = "deregister"; - - string uri = m_ServerURI + "/grid"; - - try - { - string reply - = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData)); - - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if ((replyData["Result"] != null) && (replyData["Result"].ToString().ToLower() == "success")) - return true; - } - else - m_log.DebugFormat("[GRID CONNECTOR]: DeregisterRegion received null reply"); - } - catch (Exception e) - { - m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); - } - - return false; - } - - public List GetNeighbours(UUID scopeID, UUID regionID) - { - Dictionary sendData = new Dictionary(); - - sendData["SCOPEID"] = scopeID.ToString(); - sendData["REGIONID"] = regionID.ToString(); - - sendData["METHOD"] = "get_neighbours"; - - List rinfos = new List(); - - string reqString = ServerUtils.BuildQueryString(sendData); - string reply = string.Empty; - string uri = m_ServerURI + "/grid"; - - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); - } - catch (Exception e) - { - m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); - return rinfos; - } - - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData != null) - { - Dictionary.ValueCollection rinfosList = replyData.Values; - //m_log.DebugFormat("[GRID CONNECTOR]: get neighbours returned {0} elements", rinfosList.Count); - foreach (object r in rinfosList) - { - if (r is Dictionary) - { - GridRegion rinfo = new GridRegion((Dictionary)r); - rinfos.Add(rinfo); - } - } - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetNeighbours {0}, {1} received null response", - scopeID, regionID); - - return rinfos; - } - - public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID) - { - Dictionary sendData = new Dictionary(); - - sendData["SCOPEID"] = scopeID.ToString(); - sendData["REGIONID"] = regionID.ToString(); - - sendData["METHOD"] = "get_region_by_uuid"; - - string reply = string.Empty; - string uri = m_ServerURI + "/grid"; - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData)); - } - catch (Exception e) - { - m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); - return null; - } - - GridRegion rinfo = null; - - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if ((replyData != null) && (replyData["result"] != null)) - { - if (replyData["result"] is Dictionary) - rinfo = new GridRegion((Dictionary)replyData["result"]); - //else - // m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByUUID {0}, {1} received null response", - // scopeID, regionID); - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByUUID {0}, {1} received null response", - scopeID, regionID); - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByUUID received null reply"); - - return rinfo; - } - - public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) - { - Dictionary sendData = new Dictionary(); - - sendData["SCOPEID"] = scopeID.ToString(); - sendData["X"] = x.ToString(); - sendData["Y"] = y.ToString(); - - sendData["METHOD"] = "get_region_by_position"; - string reply = string.Empty; - string uri = m_ServerURI + "/grid"; - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - ServerUtils.BuildQueryString(sendData)); - } - catch (Exception e) - { - m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); - return null; - } - - GridRegion rinfo = null; - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if ((replyData != null) && (replyData["result"] != null)) - { - if (replyData["result"] is Dictionary) - rinfo = new GridRegion((Dictionary)replyData["result"]); - //else - // m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition {0}, {1}-{2} received no region", - // scopeID, x, y); - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition {0}, {1}-{2} received null response", - scopeID, x, y); - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition received null reply"); - - return rinfo; - } - - public GridRegion GetRegionByName(UUID scopeID, string regionName) - { - Dictionary sendData = new Dictionary(); - - sendData["SCOPEID"] = scopeID.ToString(); - sendData["NAME"] = regionName; - - sendData["METHOD"] = "get_region_by_name"; - string reply = string.Empty; - string uri = m_ServerURI + "/grid"; - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - ServerUtils.BuildQueryString(sendData)); - } - catch (Exception e) - { - m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); - return null; - } - - GridRegion rinfo = null; - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if ((replyData != null) && (replyData["result"] != null)) - { - if (replyData["result"] is Dictionary) - rinfo = new GridRegion((Dictionary)replyData["result"]); - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition {0}, {1} received null response", - scopeID, regionName); - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByName received null reply"); - - return rinfo; - } - - public List GetRegionsByName(UUID scopeID, string name, int maxNumber) - { - Dictionary sendData = new Dictionary(); - - sendData["SCOPEID"] = scopeID.ToString(); - sendData["NAME"] = name; - sendData["MAX"] = maxNumber.ToString(); - - sendData["METHOD"] = "get_regions_by_name"; - List rinfos = new List(); - string reply = string.Empty; - string uri = m_ServerURI + "/grid"; - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - ServerUtils.BuildQueryString(sendData)); - } - catch (Exception e) - { - m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); - return rinfos; - } - - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData != null) - { - Dictionary.ValueCollection rinfosList = replyData.Values; - foreach (object r in rinfosList) - { - if (r is Dictionary) - { - GridRegion rinfo = new GridRegion((Dictionary)r); - rinfos.Add(rinfo); - } - } - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetRegionsByName {0}, {1}, {2} received null response", - scopeID, name, maxNumber); - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetRegionsByName received null reply"); - - return rinfos; - } - - public List GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax) - { - Dictionary sendData = new Dictionary(); - - sendData["SCOPEID"] = scopeID.ToString(); - sendData["XMIN"] = xmin.ToString(); - sendData["XMAX"] = xmax.ToString(); - sendData["YMIN"] = ymin.ToString(); - sendData["YMAX"] = ymax.ToString(); - - sendData["METHOD"] = "get_region_range"; - - List rinfos = new List(); - string reply = string.Empty; - string uri = m_ServerURI + "/grid"; - - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - ServerUtils.BuildQueryString(sendData)); - - //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply); - } - catch (Exception e) - { - m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); - return rinfos; - } - - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData != null) - { - Dictionary.ValueCollection rinfosList = replyData.Values; - foreach (object r in rinfosList) - { - if (r is Dictionary) - { - GridRegion rinfo = new GridRegion((Dictionary)r); - rinfos.Add(rinfo); - } - } - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetRegionRange {0}, {1}-{2} {3}-{4} received null response", - scopeID, xmin, xmax, ymin, ymax); - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetRegionRange received null reply"); - - return rinfos; - } - - public List GetDefaultRegions(UUID scopeID) - { - Dictionary sendData = new Dictionary(); - - sendData["SCOPEID"] = scopeID.ToString(); - - sendData["METHOD"] = "get_default_regions"; - - List rinfos = new List(); - string reply = string.Empty; - string uri = m_ServerURI + "/grid"; - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - ServerUtils.BuildQueryString(sendData)); - - //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply); - } - catch (Exception e) - { - m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); - return rinfos; - } - - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData != null) - { - Dictionary.ValueCollection rinfosList = replyData.Values; - foreach (object r in rinfosList) - { - if (r is Dictionary) - { - GridRegion rinfo = new GridRegion((Dictionary)r); - rinfos.Add(rinfo); - } - } - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultRegions {0} received null response", - scopeID); - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultRegions received null reply"); - - return rinfos; - } - - public List GetFallbackRegions(UUID scopeID, int x, int y) - { - Dictionary sendData = new Dictionary(); - - sendData["SCOPEID"] = scopeID.ToString(); - sendData["X"] = x.ToString(); - sendData["Y"] = y.ToString(); - - sendData["METHOD"] = "get_fallback_regions"; - - List rinfos = new List(); - string reply = string.Empty; - string uri = m_ServerURI + "/grid"; - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - ServerUtils.BuildQueryString(sendData)); - - //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply); - } - catch (Exception e) - { - m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); - return rinfos; - } - - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData != null) - { - Dictionary.ValueCollection rinfosList = replyData.Values; - foreach (object r in rinfosList) - { - if (r is Dictionary) - { - GridRegion rinfo = new GridRegion((Dictionary)r); - rinfos.Add(rinfo); - } - } - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetFallbackRegions {0}, {1}-{2} received null response", - scopeID, x, y); - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetFallbackRegions received null reply"); - - return rinfos; - } - - public List GetHyperlinks(UUID scopeID) - { - Dictionary sendData = new Dictionary(); - - sendData["SCOPEID"] = scopeID.ToString(); - - sendData["METHOD"] = "get_hyperlinks"; - - List rinfos = new List(); - string reply = string.Empty; - string uri = m_ServerURI + "/grid"; - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - ServerUtils.BuildQueryString(sendData)); - - //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply); - } - catch (Exception e) - { - m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); - return rinfos; - } - - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData != null) - { - Dictionary.ValueCollection rinfosList = replyData.Values; - foreach (object r in rinfosList) - { - if (r is Dictionary) - { - GridRegion rinfo = new GridRegion((Dictionary)r); - rinfos.Add(rinfo); - } - } - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetHyperlinks {0} received null response", - scopeID); - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetHyperlinks received null reply"); - - return rinfos; - } - - public int GetRegionFlags(UUID scopeID, UUID regionID) - { - Dictionary sendData = new Dictionary(); - - sendData["SCOPEID"] = scopeID.ToString(); - sendData["REGIONID"] = regionID.ToString(); - - sendData["METHOD"] = "get_region_flags"; - - string reply = string.Empty; - string uri = m_ServerURI + "/grid"; - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - ServerUtils.BuildQueryString(sendData)); - } - catch (Exception e) - { - m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); - return -1; - } - - int flags = -1; - - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null)) - { - Int32.TryParse((string)replyData["result"], out flags); - //else - // m_log.DebugFormat("[GRID CONNECTOR]: GetRegionFlags {0}, {1} received wrong type {2}", - // scopeID, regionID, replyData["result"].GetType()); - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetRegionFlags {0}, {1} received null response", - scopeID, regionID); - } - else - m_log.DebugFormat("[GRID CONNECTOR]: GetRegionFlags received null reply"); - - return flags; - } - - #endregion - - } -} diff --git a/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs b/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs new file mode 100644 index 0000000..34ed0d7 --- /dev/null +++ b/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs @@ -0,0 +1,671 @@ +/* + * 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 log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Services.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using OpenSim.Server.Base; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors +{ + public class GridServicesConnector : IGridService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + + public GridServicesConnector() + { + } + + public GridServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + + public GridServicesConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig gridConfig = source.Configs["GridService"]; + if (gridConfig == null) + { + m_log.Error("[GRID CONNECTOR]: GridService missing from OpenSim.ini"); + throw new Exception("Grid connector init error"); + } + + string serviceURI = gridConfig.GetString("GridServerURI", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[GRID CONNECTOR]: No Server URI named in section GridService"); + throw new Exception("Grid connector init error"); + } + m_ServerURI = serviceURI; + } + + + #region IGridService + + public string RegisterRegion(UUID scopeID, GridRegion regionInfo) + { + Dictionary rinfo = regionInfo.ToKeyValuePairs(); + Dictionary sendData = new Dictionary(); + foreach (KeyValuePair kvp in rinfo) + sendData[kvp.Key] = (string)kvp.Value; + + sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "register"; + + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/grid"; + // m_log.DebugFormat("[GRID CONNECTOR]: queryString = {0}", reqString); + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("Result")&& (replyData["Result"].ToString().ToLower() == "success")) + { + return String.Empty; + } + else if (replyData.ContainsKey("Result")&& (replyData["Result"].ToString().ToLower() == "failure")) + { + m_log.ErrorFormat( + "[GRID CONNECTOR]: Registration failed: {0} when contacting {1}", replyData["Message"], uri); + + return replyData["Message"].ToString(); + } + else if (!replyData.ContainsKey("Result")) + { + m_log.ErrorFormat( + "[GRID CONNECTOR]: reply data does not contain result field when contacting {0}", uri); + } + else + { + m_log.ErrorFormat( + "[GRID CONNECTOR]: unexpected result {0} when contacting {1}", replyData["Result"], uri); + + return "Unexpected result " + replyData["Result"].ToString(); + } + } + else + { + m_log.ErrorFormat( + "[GRID CONNECTOR]: RegisterRegion received null reply when contacting grid server at {0}", uri); + } + } + catch (Exception e) + { + m_log.ErrorFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); + } + + return string.Format("Error communicating with the grid service at {0}", uri); + } + + public bool DeregisterRegion(UUID regionID) + { + Dictionary sendData = new Dictionary(); + + sendData["REGIONID"] = regionID.ToString(); + + sendData["METHOD"] = "deregister"; + + string uri = m_ServerURI + "/grid"; + + try + { + string reply + = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData)); + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if ((replyData["Result"] != null) && (replyData["Result"].ToString().ToLower() == "success")) + return true; + } + else + m_log.DebugFormat("[GRID CONNECTOR]: DeregisterRegion received null reply"); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); + } + + return false; + } + + public List GetNeighbours(UUID scopeID, UUID regionID) + { + Dictionary sendData = new Dictionary(); + + sendData["SCOPEID"] = scopeID.ToString(); + sendData["REGIONID"] = regionID.ToString(); + + sendData["METHOD"] = "get_neighbours"; + + List rinfos = new List(); + + string reqString = ServerUtils.BuildQueryString(sendData); + string reply = string.Empty; + string uri = m_ServerURI + "/grid"; + + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); + return rinfos; + } + + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData != null) + { + Dictionary.ValueCollection rinfosList = replyData.Values; + //m_log.DebugFormat("[GRID CONNECTOR]: get neighbours returned {0} elements", rinfosList.Count); + foreach (object r in rinfosList) + { + if (r is Dictionary) + { + GridRegion rinfo = new GridRegion((Dictionary)r); + rinfos.Add(rinfo); + } + } + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetNeighbours {0}, {1} received null response", + scopeID, regionID); + + return rinfos; + } + + public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID) + { + Dictionary sendData = new Dictionary(); + + sendData["SCOPEID"] = scopeID.ToString(); + sendData["REGIONID"] = regionID.ToString(); + + sendData["METHOD"] = "get_region_by_uuid"; + + string reply = string.Empty; + string uri = m_ServerURI + "/grid"; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData)); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); + return null; + } + + GridRegion rinfo = null; + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if ((replyData != null) && (replyData["result"] != null)) + { + if (replyData["result"] is Dictionary) + rinfo = new GridRegion((Dictionary)replyData["result"]); + //else + // m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByUUID {0}, {1} received null response", + // scopeID, regionID); + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByUUID {0}, {1} received null response", + scopeID, regionID); + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByUUID received null reply"); + + return rinfo; + } + + public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) + { + Dictionary sendData = new Dictionary(); + + sendData["SCOPEID"] = scopeID.ToString(); + sendData["X"] = x.ToString(); + sendData["Y"] = y.ToString(); + + sendData["METHOD"] = "get_region_by_position"; + string reply = string.Empty; + string uri = m_ServerURI + "/grid"; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + ServerUtils.BuildQueryString(sendData)); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); + return null; + } + + GridRegion rinfo = null; + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if ((replyData != null) && (replyData["result"] != null)) + { + if (replyData["result"] is Dictionary) + rinfo = new GridRegion((Dictionary)replyData["result"]); + //else + // m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition {0}, {1}-{2} received no region", + // scopeID, x, y); + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition {0}, {1}-{2} received null response", + scopeID, x, y); + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition received null reply"); + + return rinfo; + } + + public GridRegion GetRegionByName(UUID scopeID, string regionName) + { + Dictionary sendData = new Dictionary(); + + sendData["SCOPEID"] = scopeID.ToString(); + sendData["NAME"] = regionName; + + sendData["METHOD"] = "get_region_by_name"; + string reply = string.Empty; + string uri = m_ServerURI + "/grid"; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + ServerUtils.BuildQueryString(sendData)); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); + return null; + } + + GridRegion rinfo = null; + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if ((replyData != null) && (replyData["result"] != null)) + { + if (replyData["result"] is Dictionary) + rinfo = new GridRegion((Dictionary)replyData["result"]); + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition {0}, {1} received null response", + scopeID, regionName); + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByName received null reply"); + + return rinfo; + } + + public List GetRegionsByName(UUID scopeID, string name, int maxNumber) + { + Dictionary sendData = new Dictionary(); + + sendData["SCOPEID"] = scopeID.ToString(); + sendData["NAME"] = name; + sendData["MAX"] = maxNumber.ToString(); + + sendData["METHOD"] = "get_regions_by_name"; + List rinfos = new List(); + string reply = string.Empty; + string uri = m_ServerURI + "/grid"; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + ServerUtils.BuildQueryString(sendData)); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); + return rinfos; + } + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData != null) + { + Dictionary.ValueCollection rinfosList = replyData.Values; + foreach (object r in rinfosList) + { + if (r is Dictionary) + { + GridRegion rinfo = new GridRegion((Dictionary)r); + rinfos.Add(rinfo); + } + } + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetRegionsByName {0}, {1}, {2} received null response", + scopeID, name, maxNumber); + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetRegionsByName received null reply"); + + return rinfos; + } + + public List GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax) + { + Dictionary sendData = new Dictionary(); + + sendData["SCOPEID"] = scopeID.ToString(); + sendData["XMIN"] = xmin.ToString(); + sendData["XMAX"] = xmax.ToString(); + sendData["YMIN"] = ymin.ToString(); + sendData["YMAX"] = ymax.ToString(); + + sendData["METHOD"] = "get_region_range"; + + List rinfos = new List(); + string reply = string.Empty; + string uri = m_ServerURI + "/grid"; + + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + ServerUtils.BuildQueryString(sendData)); + + //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); + return rinfos; + } + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData != null) + { + Dictionary.ValueCollection rinfosList = replyData.Values; + foreach (object r in rinfosList) + { + if (r is Dictionary) + { + GridRegion rinfo = new GridRegion((Dictionary)r); + rinfos.Add(rinfo); + } + } + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetRegionRange {0}, {1}-{2} {3}-{4} received null response", + scopeID, xmin, xmax, ymin, ymax); + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetRegionRange received null reply"); + + return rinfos; + } + + public List GetDefaultRegions(UUID scopeID) + { + Dictionary sendData = new Dictionary(); + + sendData["SCOPEID"] = scopeID.ToString(); + + sendData["METHOD"] = "get_default_regions"; + + List rinfos = new List(); + string reply = string.Empty; + string uri = m_ServerURI + "/grid"; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + ServerUtils.BuildQueryString(sendData)); + + //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); + return rinfos; + } + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData != null) + { + Dictionary.ValueCollection rinfosList = replyData.Values; + foreach (object r in rinfosList) + { + if (r is Dictionary) + { + GridRegion rinfo = new GridRegion((Dictionary)r); + rinfos.Add(rinfo); + } + } + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultRegions {0} received null response", + scopeID); + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultRegions received null reply"); + + return rinfos; + } + + public List GetFallbackRegions(UUID scopeID, int x, int y) + { + Dictionary sendData = new Dictionary(); + + sendData["SCOPEID"] = scopeID.ToString(); + sendData["X"] = x.ToString(); + sendData["Y"] = y.ToString(); + + sendData["METHOD"] = "get_fallback_regions"; + + List rinfos = new List(); + string reply = string.Empty; + string uri = m_ServerURI + "/grid"; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + ServerUtils.BuildQueryString(sendData)); + + //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); + return rinfos; + } + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData != null) + { + Dictionary.ValueCollection rinfosList = replyData.Values; + foreach (object r in rinfosList) + { + if (r is Dictionary) + { + GridRegion rinfo = new GridRegion((Dictionary)r); + rinfos.Add(rinfo); + } + } + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetFallbackRegions {0}, {1}-{2} received null response", + scopeID, x, y); + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetFallbackRegions received null reply"); + + return rinfos; + } + + public List GetHyperlinks(UUID scopeID) + { + Dictionary sendData = new Dictionary(); + + sendData["SCOPEID"] = scopeID.ToString(); + + sendData["METHOD"] = "get_hyperlinks"; + + List rinfos = new List(); + string reply = string.Empty; + string uri = m_ServerURI + "/grid"; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + ServerUtils.BuildQueryString(sendData)); + + //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); + return rinfos; + } + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData != null) + { + Dictionary.ValueCollection rinfosList = replyData.Values; + foreach (object r in rinfosList) + { + if (r is Dictionary) + { + GridRegion rinfo = new GridRegion((Dictionary)r); + rinfos.Add(rinfo); + } + } + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetHyperlinks {0} received null response", + scopeID); + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetHyperlinks received null reply"); + + return rinfos; + } + + public int GetRegionFlags(UUID scopeID, UUID regionID) + { + Dictionary sendData = new Dictionary(); + + sendData["SCOPEID"] = scopeID.ToString(); + sendData["REGIONID"] = regionID.ToString(); + + sendData["METHOD"] = "get_region_flags"; + + string reply = string.Empty; + string uri = m_ServerURI + "/grid"; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + ServerUtils.BuildQueryString(sendData)); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); + return -1; + } + + int flags = -1; + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null)) + { + Int32.TryParse((string)replyData["result"], out flags); + //else + // m_log.DebugFormat("[GRID CONNECTOR]: GetRegionFlags {0}, {1} received wrong type {2}", + // scopeID, regionID, replyData["result"].GetType()); + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetRegionFlags {0}, {1} received null response", + scopeID, regionID); + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetRegionFlags received null reply"); + + return flags; + } + + #endregion + + } +} diff --git a/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs b/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs deleted file mode 100644 index 20d7eaf..0000000 --- a/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs +++ /dev/null @@ -1,290 +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 log4net; -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Services.Interfaces; -using GridRegion = OpenSim.Services.Interfaces.GridRegion; -using OpenSim.Server.Base; -using OpenMetaverse; - -namespace OpenSim.Services.Connectors -{ - public class GridUserServicesConnector : IGridUserService - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - private string m_ServerURI = String.Empty; - - public GridUserServicesConnector() - { - } - - public GridUserServicesConnector(string serverURI) - { - m_ServerURI = serverURI.TrimEnd('/'); - } - - public GridUserServicesConnector(IConfigSource source) - { - Initialise(source); - } - - public virtual void Initialise(IConfigSource source) - { - IConfig gridConfig = source.Configs["GridUserService"]; - if (gridConfig == null) - { - m_log.Error("[GRID USER CONNECTOR]: GridUserService missing from OpenSim.ini"); - throw new Exception("GridUser connector init error"); - } - - string serviceURI = gridConfig.GetString("GridUserServerURI", - String.Empty); - - if (serviceURI == String.Empty) - { - m_log.Error("[GRID USER CONNECTOR]: No Server URI named in section GridUserService"); - throw new Exception("GridUser connector init error"); - } - m_ServerURI = serviceURI; - } - - - #region IGridUserService - - - public GridUserInfo LoggedIn(string userID) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "loggedin"; - - sendData["UserID"] = userID; - - return Get(sendData); - - } - - public bool LoggedOut(string userID, UUID sessionID, UUID region, Vector3 position, Vector3 lookat) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "loggedout"; - - return Set(sendData, userID, region, position, lookat); - } - - public bool SetHome(string userID, UUID regionID, Vector3 position, Vector3 lookAt) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "sethome"; - - return Set(sendData, userID, regionID, position, lookAt); - } - - public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "setposition"; - - return Set(sendData, userID, regionID, position, lookAt); - } - - public GridUserInfo GetGridUserInfo(string userID) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "getgriduserinfo"; - - sendData["UserID"] = userID; - - return Get(sendData); - } - - #endregion - - protected bool Set(Dictionary sendData, string userID, UUID regionID, Vector3 position, Vector3 lookAt) - { - sendData["UserID"] = userID; - sendData["RegionID"] = regionID.ToString(); - sendData["Position"] = position.ToString(); - sendData["LookAt"] = lookAt.ToString(); - - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/griduser"; - // m_log.DebugFormat("[GRID USER CONNECTOR]: queryString = {0}", reqString); - try - { - string reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - reqString); - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData.ContainsKey("result")) - { - if (replyData["result"].ToString().ToLower() == "success") - return true; - else - return false; - } - else - m_log.DebugFormat("[GRID USER CONNECTOR]: SetPosition reply data does not contain result field"); - - } - else - m_log.DebugFormat("[GRID USER CONNECTOR]: SetPosition received empty reply"); - } - catch (Exception e) - { - m_log.DebugFormat("[GRID USER CONNECTOR]: Exception when contacting grid user server at {0}: {1}", uri, e.Message); - } - - return false; - } - - protected GridUserInfo Get(Dictionary sendData) - { - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/griduser"; - // m_log.DebugFormat("[GRID USER CONNECTOR]: queryString = {0}", reqString); - try - { - string reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - reqString); - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - GridUserInfo guinfo = null; - - if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null)) - { - if (replyData["result"] is Dictionary) - guinfo = new GridUserInfo((Dictionary)replyData["result"]); - } - - return guinfo; - - } - else - m_log.DebugFormat("[GRID USER CONNECTOR]: Loggedin received empty reply"); - } - catch (Exception e) - { - m_log.DebugFormat("[GRID USER CONNECTOR]: Exception when contacting grid user server at {0}: {1}", uri, e.Message); - } - - return null; - - } - - public GridUserInfo[] GetGridUserInfo(string[] userIDs) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "getgriduserinfos"; - - sendData["AgentIDs"] = new List(userIDs); - - string reply = string.Empty; - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/griduser"; - //m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - reqString); - if (reply == null || (reply != null && reply == string.Empty)) - { - m_log.DebugFormat("[GRID USER CONNECTOR]: GetGridUserInfo received null or empty reply"); - return null; - } - } - catch (Exception e) - { - m_log.DebugFormat("[GRID USER CONNECTOR]: Exception when contacting grid user server at {0}: {1}", uri, e.Message); - } - - List rinfos = new List(); - - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData != null) - { - if (replyData.ContainsKey("result") && - (replyData["result"].ToString() == "null" || replyData["result"].ToString() == "Failure")) - { - return new GridUserInfo[0]; - } - - Dictionary.ValueCollection pinfosList = replyData.Values; - //m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents returned {0} elements", pinfosList.Count); - foreach (object griduser in pinfosList) - { - if (griduser is Dictionary) - { - GridUserInfo pinfo = new GridUserInfo((Dictionary)griduser); - rinfos.Add(pinfo); - } - else - m_log.DebugFormat("[GRID USER CONNECTOR]: GetGridUserInfo received invalid response type {0}", - griduser.GetType()); - } - } - else - m_log.DebugFormat("[GRID USER CONNECTOR]: GetGridUserInfo received null response"); - - return rinfos.ToArray(); - } - } -} diff --git a/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs b/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs new file mode 100644 index 0000000..20d7eaf --- /dev/null +++ b/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs @@ -0,0 +1,290 @@ +/* + * 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 log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Services.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using OpenSim.Server.Base; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors +{ + public class GridUserServicesConnector : IGridUserService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + + public GridUserServicesConnector() + { + } + + public GridUserServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + + public GridUserServicesConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig gridConfig = source.Configs["GridUserService"]; + if (gridConfig == null) + { + m_log.Error("[GRID USER CONNECTOR]: GridUserService missing from OpenSim.ini"); + throw new Exception("GridUser connector init error"); + } + + string serviceURI = gridConfig.GetString("GridUserServerURI", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[GRID USER CONNECTOR]: No Server URI named in section GridUserService"); + throw new Exception("GridUser connector init error"); + } + m_ServerURI = serviceURI; + } + + + #region IGridUserService + + + public GridUserInfo LoggedIn(string userID) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "loggedin"; + + sendData["UserID"] = userID; + + return Get(sendData); + + } + + public bool LoggedOut(string userID, UUID sessionID, UUID region, Vector3 position, Vector3 lookat) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "loggedout"; + + return Set(sendData, userID, region, position, lookat); + } + + public bool SetHome(string userID, UUID regionID, Vector3 position, Vector3 lookAt) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "sethome"; + + return Set(sendData, userID, regionID, position, lookAt); + } + + public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "setposition"; + + return Set(sendData, userID, regionID, position, lookAt); + } + + public GridUserInfo GetGridUserInfo(string userID) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "getgriduserinfo"; + + sendData["UserID"] = userID; + + return Get(sendData); + } + + #endregion + + protected bool Set(Dictionary sendData, string userID, UUID regionID, Vector3 position, Vector3 lookAt) + { + sendData["UserID"] = userID; + sendData["RegionID"] = regionID.ToString(); + sendData["Position"] = position.ToString(); + sendData["LookAt"] = lookAt.ToString(); + + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/griduser"; + // m_log.DebugFormat("[GRID USER CONNECTOR]: queryString = {0}", reqString); + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + reqString); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("result")) + { + if (replyData["result"].ToString().ToLower() == "success") + return true; + else + return false; + } + else + m_log.DebugFormat("[GRID USER CONNECTOR]: SetPosition reply data does not contain result field"); + + } + else + m_log.DebugFormat("[GRID USER CONNECTOR]: SetPosition received empty reply"); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID USER CONNECTOR]: Exception when contacting grid user server at {0}: {1}", uri, e.Message); + } + + return false; + } + + protected GridUserInfo Get(Dictionary sendData) + { + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/griduser"; + // m_log.DebugFormat("[GRID USER CONNECTOR]: queryString = {0}", reqString); + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + reqString); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + GridUserInfo guinfo = null; + + if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null)) + { + if (replyData["result"] is Dictionary) + guinfo = new GridUserInfo((Dictionary)replyData["result"]); + } + + return guinfo; + + } + else + m_log.DebugFormat("[GRID USER CONNECTOR]: Loggedin received empty reply"); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID USER CONNECTOR]: Exception when contacting grid user server at {0}: {1}", uri, e.Message); + } + + return null; + + } + + public GridUserInfo[] GetGridUserInfo(string[] userIDs) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "getgriduserinfos"; + + sendData["AgentIDs"] = new List(userIDs); + + string reply = string.Empty; + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/griduser"; + //m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + reqString); + if (reply == null || (reply != null && reply == string.Empty)) + { + m_log.DebugFormat("[GRID USER CONNECTOR]: GetGridUserInfo received null or empty reply"); + return null; + } + } + catch (Exception e) + { + m_log.DebugFormat("[GRID USER CONNECTOR]: Exception when contacting grid user server at {0}: {1}", uri, e.Message); + } + + List rinfos = new List(); + + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData != null) + { + if (replyData.ContainsKey("result") && + (replyData["result"].ToString() == "null" || replyData["result"].ToString() == "Failure")) + { + return new GridUserInfo[0]; + } + + Dictionary.ValueCollection pinfosList = replyData.Values; + //m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents returned {0} elements", pinfosList.Count); + foreach (object griduser in pinfosList) + { + if (griduser is Dictionary) + { + GridUserInfo pinfo = new GridUserInfo((Dictionary)griduser); + rinfos.Add(pinfo); + } + else + m_log.DebugFormat("[GRID USER CONNECTOR]: GetGridUserInfo received invalid response type {0}", + griduser.GetType()); + } + } + else + m_log.DebugFormat("[GRID USER CONNECTOR]: GetGridUserInfo received null response"); + + return rinfos.ToArray(); + } + } +} diff --git a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs deleted file mode 100644 index e984a54..0000000 --- a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs +++ /dev/null @@ -1,312 +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 log4net; -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Services.Interfaces; -using OpenSim.Services.Connectors.Friends; -using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; -using OpenSim.Server.Base; -using OpenMetaverse; - -namespace OpenSim.Services.Connectors.Hypergrid -{ - public class HGFriendsServicesConnector : FriendsSimConnector - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - private string m_ServerURI = String.Empty; - private string m_ServiceKey = String.Empty; - private UUID m_SessionID; - - public HGFriendsServicesConnector() - { - } - - public HGFriendsServicesConnector(string serverURI) - { - m_ServerURI = serverURI.TrimEnd('/'); - } - - public HGFriendsServicesConnector(string serverURI, UUID sessionID, string serviceKey) - { - m_ServerURI = serverURI.TrimEnd('/'); - m_ServiceKey = serviceKey; - m_SessionID = sessionID; - } - - protected override string ServicePath() - { - return "hgfriends"; - } - - #region IFriendsService - - public uint GetFriendPerms(UUID PrincipalID, UUID friendID) - { - Dictionary sendData = new Dictionary(); - - sendData["PRINCIPALID"] = PrincipalID.ToString(); - sendData["FRIENDID"] = friendID.ToString(); - sendData["METHOD"] = "getfriendperms"; - sendData["KEY"] = m_ServiceKey; - sendData["SESSIONID"] = m_SessionID.ToString(); - - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/hgfriends"; - - try - { - string reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - reqString); - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if ((replyData != null) && replyData.ContainsKey("Value") && (replyData["Value"] != null)) - { - uint perms = 0; - uint.TryParse(replyData["Value"].ToString(), out perms); - return perms; - } - else - m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriendPerms {0} received null response", - PrincipalID); - - } - } - catch (Exception e) - { - m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message); - } - - return 0; - - } - - public bool NewFriendship(UUID PrincipalID, string Friend) - { - FriendInfo finfo = new FriendInfo(); - finfo.PrincipalID = PrincipalID; - finfo.Friend = Friend; - - Dictionary sendData = finfo.ToKeyValuePairs(); - - sendData["METHOD"] = "newfriendship"; - sendData["KEY"] = m_ServiceKey; - sendData["SESSIONID"] = m_SessionID.ToString(); - - string reply = string.Empty; - string uri = m_ServerURI + "/hgfriends"; - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - ServerUtils.BuildQueryString(sendData)); - } - catch (Exception e) - { - m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message); - return false; - } - - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null)) - { - bool success = false; - Boolean.TryParse(replyData["Result"].ToString(), out success); - return success; - } - else - m_log.DebugFormat("[HGFRIENDS CONNECTOR]: StoreFriend {0} {1} received null response", - PrincipalID, Friend); - } - else - m_log.DebugFormat("[HGFRIENDS CONNECTOR]: StoreFriend received null reply"); - - return false; - - } - - public bool DeleteFriendship(UUID PrincipalID, UUID Friend, string secret) - { - FriendInfo finfo = new FriendInfo(); - finfo.PrincipalID = PrincipalID; - finfo.Friend = Friend.ToString(); - - Dictionary sendData = finfo.ToKeyValuePairs(); - - sendData["METHOD"] = "deletefriendship"; - sendData["SECRET"] = secret; - - string reply = string.Empty; - string uri = m_ServerURI + "/hgfriends"; - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - ServerUtils.BuildQueryString(sendData)); - } - catch (Exception e) - { - m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message); - return false; - } - - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData.ContainsKey("RESULT")) - { - if (replyData["RESULT"].ToString().ToLower() == "true") - return true; - else - return false; - } - else - m_log.DebugFormat("[HGFRIENDS CONNECTOR]: reply data does not contain result field"); - - } - else - m_log.DebugFormat("[HGFRIENDS CONNECTOR]: received empty reply"); - - return false; - - } - - public bool ValidateFriendshipOffered(UUID fromID, UUID toID) - { - FriendInfo finfo = new FriendInfo(); - finfo.PrincipalID = fromID; - finfo.Friend = toID.ToString(); - - Dictionary sendData = finfo.ToKeyValuePairs(); - - sendData["METHOD"] = "validate_friendship_offered"; - - string reply = string.Empty; - string uri = m_ServerURI + "/hgfriends"; - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - ServerUtils.BuildQueryString(sendData)); - } - catch (Exception e) - { - m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message); - return false; - } - - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData.ContainsKey("RESULT")) - { - if (replyData["RESULT"].ToString().ToLower() == "true") - return true; - else - return false; - } - else - m_log.DebugFormat("[HGFRIENDS CONNECTOR]: reply data does not contain result field"); - - } - else - m_log.DebugFormat("[HGFRIENDS CONNECTOR]: received empty reply"); - - return false; - - } - - public List StatusNotification(List friends, UUID userID, bool online) - { - Dictionary sendData = new Dictionary(); - List friendsOnline = new List(); - - sendData["METHOD"] = "statusnotification"; - sendData["userID"] = userID.ToString(); - sendData["online"] = online.ToString(); - int i = 0; - foreach (string s in friends) - { - sendData["friend_" + i.ToString()] = s; - i++; - } - - string reply = string.Empty; - string uri = m_ServerURI + "/hgfriends"; - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - ServerUtils.BuildQueryString(sendData)); - } - catch (Exception e) - { - m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message); - return friendsOnline; - } - - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - // Here is the actual response - foreach (string key in replyData.Keys) - { - if (key.StartsWith("friend_") && replyData[key] != null) - { - UUID uuid; - if (UUID.TryParse(replyData[key].ToString(), out uuid)) - friendsOnline.Add(uuid); - } - } - } - else - m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Received empty reply from remote StatusNotify"); - - return friendsOnline; - - } - - #endregion - } -} \ No newline at end of file diff --git a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServicesConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServicesConnector.cs new file mode 100644 index 0000000..e984a54 --- /dev/null +++ b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServicesConnector.cs @@ -0,0 +1,312 @@ +/* + * 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 log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Connectors.Friends; +using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; +using OpenSim.Server.Base; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors.Hypergrid +{ + public class HGFriendsServicesConnector : FriendsSimConnector + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + private string m_ServiceKey = String.Empty; + private UUID m_SessionID; + + public HGFriendsServicesConnector() + { + } + + public HGFriendsServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + + public HGFriendsServicesConnector(string serverURI, UUID sessionID, string serviceKey) + { + m_ServerURI = serverURI.TrimEnd('/'); + m_ServiceKey = serviceKey; + m_SessionID = sessionID; + } + + protected override string ServicePath() + { + return "hgfriends"; + } + + #region IFriendsService + + public uint GetFriendPerms(UUID PrincipalID, UUID friendID) + { + Dictionary sendData = new Dictionary(); + + sendData["PRINCIPALID"] = PrincipalID.ToString(); + sendData["FRIENDID"] = friendID.ToString(); + sendData["METHOD"] = "getfriendperms"; + sendData["KEY"] = m_ServiceKey; + sendData["SESSIONID"] = m_SessionID.ToString(); + + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/hgfriends"; + + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + reqString); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if ((replyData != null) && replyData.ContainsKey("Value") && (replyData["Value"] != null)) + { + uint perms = 0; + uint.TryParse(replyData["Value"].ToString(), out perms); + return perms; + } + else + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriendPerms {0} received null response", + PrincipalID); + + } + } + catch (Exception e) + { + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message); + } + + return 0; + + } + + public bool NewFriendship(UUID PrincipalID, string Friend) + { + FriendInfo finfo = new FriendInfo(); + finfo.PrincipalID = PrincipalID; + finfo.Friend = Friend; + + Dictionary sendData = finfo.ToKeyValuePairs(); + + sendData["METHOD"] = "newfriendship"; + sendData["KEY"] = m_ServiceKey; + sendData["SESSIONID"] = m_SessionID.ToString(); + + string reply = string.Empty; + string uri = m_ServerURI + "/hgfriends"; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + ServerUtils.BuildQueryString(sendData)); + } + catch (Exception e) + { + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message); + return false; + } + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null)) + { + bool success = false; + Boolean.TryParse(replyData["Result"].ToString(), out success); + return success; + } + else + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: StoreFriend {0} {1} received null response", + PrincipalID, Friend); + } + else + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: StoreFriend received null reply"); + + return false; + + } + + public bool DeleteFriendship(UUID PrincipalID, UUID Friend, string secret) + { + FriendInfo finfo = new FriendInfo(); + finfo.PrincipalID = PrincipalID; + finfo.Friend = Friend.ToString(); + + Dictionary sendData = finfo.ToKeyValuePairs(); + + sendData["METHOD"] = "deletefriendship"; + sendData["SECRET"] = secret; + + string reply = string.Empty; + string uri = m_ServerURI + "/hgfriends"; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + ServerUtils.BuildQueryString(sendData)); + } + catch (Exception e) + { + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message); + return false; + } + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("RESULT")) + { + if (replyData["RESULT"].ToString().ToLower() == "true") + return true; + else + return false; + } + else + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: reply data does not contain result field"); + + } + else + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: received empty reply"); + + return false; + + } + + public bool ValidateFriendshipOffered(UUID fromID, UUID toID) + { + FriendInfo finfo = new FriendInfo(); + finfo.PrincipalID = fromID; + finfo.Friend = toID.ToString(); + + Dictionary sendData = finfo.ToKeyValuePairs(); + + sendData["METHOD"] = "validate_friendship_offered"; + + string reply = string.Empty; + string uri = m_ServerURI + "/hgfriends"; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + ServerUtils.BuildQueryString(sendData)); + } + catch (Exception e) + { + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message); + return false; + } + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("RESULT")) + { + if (replyData["RESULT"].ToString().ToLower() == "true") + return true; + else + return false; + } + else + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: reply data does not contain result field"); + + } + else + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: received empty reply"); + + return false; + + } + + public List StatusNotification(List friends, UUID userID, bool online) + { + Dictionary sendData = new Dictionary(); + List friendsOnline = new List(); + + sendData["METHOD"] = "statusnotification"; + sendData["userID"] = userID.ToString(); + sendData["online"] = online.ToString(); + int i = 0; + foreach (string s in friends) + { + sendData["friend_" + i.ToString()] = s; + i++; + } + + string reply = string.Empty; + string uri = m_ServerURI + "/hgfriends"; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + ServerUtils.BuildQueryString(sendData)); + } + catch (Exception e) + { + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message); + return friendsOnline; + } + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + // Here is the actual response + foreach (string key in replyData.Keys) + { + if (key.StartsWith("friend_") && replyData[key] != null) + { + UUID uuid; + if (UUID.TryParse(replyData[key].ToString(), out uuid)) + friendsOnline.Add(uuid); + } + } + } + else + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Received empty reply from remote StatusNotify"); + + return friendsOnline; + + } + + #endregion + } +} \ No newline at end of file diff --git a/OpenSim/Services/Connectors/Hypergrid/HeloServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HeloServiceConnector.cs deleted file mode 100644 index 5c50936..0000000 --- a/OpenSim/Services/Connectors/Hypergrid/HeloServiceConnector.cs +++ /dev/null @@ -1,100 +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 log4net; -using System; -using System.Net; -using System.Reflection; -using Nini.Config; - -namespace OpenSim.Services.Connectors -{ - public class HeloServicesConnector - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - private string m_ServerURI = String.Empty; - - public HeloServicesConnector() - { - } - - public HeloServicesConnector(string serverURI) - { - if (!serverURI.EndsWith("=")) - m_ServerURI = serverURI.TrimEnd('/') + "/helo/"; - else - { - // Simian sends malformed urls like this: - // http://valley.virtualportland.org/simtest/Grid/?id= - // - try - { - Uri uri = new Uri(serverURI + "xxx"); - if (uri.Query == string.Empty) - m_ServerURI = serverURI.TrimEnd('/') + "/helo/"; - else - { - serverURI = serverURI + "xxx"; - m_ServerURI = serverURI.Replace(uri.Query, ""); - m_ServerURI = m_ServerURI.TrimEnd('/') + "/helo/"; - } - } - catch (UriFormatException) - { - m_log.WarnFormat("[HELO SERVICE]: Malformed URL {0}", serverURI); - } - } - } - - - public virtual string Helo() - { - HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(m_ServerURI); - // Eventually we need to switch to HEAD - /* req.Method = "HEAD"; */ - - try - { - WebResponse response = req.GetResponse(); - if (response.Headers.Get("X-Handlers-Provided") == null) // just in case this ever returns a null - return string.Empty; - return response.Headers.Get("X-Handlers-Provided"); - } - catch (Exception e) - { - m_log.DebugFormat("[HELO SERVICE]: Unable to perform HELO request to {0}: {1}", m_ServerURI, e.Message); - } - - // fail - return string.Empty; - } - - } -} diff --git a/OpenSim/Services/Connectors/Hypergrid/HeloServicesConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HeloServicesConnector.cs new file mode 100644 index 0000000..5c50936 --- /dev/null +++ b/OpenSim/Services/Connectors/Hypergrid/HeloServicesConnector.cs @@ -0,0 +1,100 @@ +/* + * 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 log4net; +using System; +using System.Net; +using System.Reflection; +using Nini.Config; + +namespace OpenSim.Services.Connectors +{ + public class HeloServicesConnector + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + + public HeloServicesConnector() + { + } + + public HeloServicesConnector(string serverURI) + { + if (!serverURI.EndsWith("=")) + m_ServerURI = serverURI.TrimEnd('/') + "/helo/"; + else + { + // Simian sends malformed urls like this: + // http://valley.virtualportland.org/simtest/Grid/?id= + // + try + { + Uri uri = new Uri(serverURI + "xxx"); + if (uri.Query == string.Empty) + m_ServerURI = serverURI.TrimEnd('/') + "/helo/"; + else + { + serverURI = serverURI + "xxx"; + m_ServerURI = serverURI.Replace(uri.Query, ""); + m_ServerURI = m_ServerURI.TrimEnd('/') + "/helo/"; + } + } + catch (UriFormatException) + { + m_log.WarnFormat("[HELO SERVICE]: Malformed URL {0}", serverURI); + } + } + } + + + public virtual string Helo() + { + HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(m_ServerURI); + // Eventually we need to switch to HEAD + /* req.Method = "HEAD"; */ + + try + { + WebResponse response = req.GetResponse(); + if (response.Headers.Get("X-Handlers-Provided") == null) // just in case this ever returns a null + return string.Empty; + return response.Headers.Get("X-Handlers-Provided"); + } + catch (Exception e) + { + m_log.DebugFormat("[HELO SERVICE]: Unable to perform HELO request to {0}: {1}", m_ServerURI, e.Message); + } + + // fail + return string.Empty; + } + + } +} diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs deleted file mode 100644 index 9d96703..0000000 --- a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs +++ /dev/null @@ -1,623 +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 log4net; -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Console; -using OpenSim.Framework.Communications; -using OpenSim.Services.Interfaces; -using OpenSim.Server.Base; -using OpenMetaverse; - -namespace OpenSim.Services.Connectors -{ - public class XInventoryServicesConnector : IInventoryService - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - private string m_ServerURI = String.Empty; - - private object m_Lock = new object(); - - public XInventoryServicesConnector() - { - } - - public XInventoryServicesConnector(string serverURI) - { - m_ServerURI = serverURI.TrimEnd('/'); - } - - public XInventoryServicesConnector(IConfigSource source) - { - Initialise(source); - } - - public virtual void Initialise(IConfigSource source) - { - IConfig assetConfig = source.Configs["InventoryService"]; - if (assetConfig == null) - { - m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini"); - throw new Exception("Inventory connector init error"); - } - - string serviceURI = assetConfig.GetString("InventoryServerURI", - String.Empty); - - if (serviceURI == String.Empty) - { - m_log.Error("[INVENTORY CONNECTOR]: No Server URI named in section InventoryService"); - throw new Exception("Inventory connector init error"); - } - m_ServerURI = serviceURI; - } - - public bool CreateUserInventory(UUID principalID) - { - Dictionary ret = MakeRequest("CREATEUSERINVENTORY", - new Dictionary { - { "PRINCIPAL", principalID.ToString() } - }); - - if (ret == null) - return false; - if (ret.Count == 0) - return false; - - return bool.Parse(ret["RESULT"].ToString()); - } - - public List GetInventorySkeleton(UUID principalID) - { - Dictionary ret = MakeRequest("GETINVENTORYSKELETON", - new Dictionary { - { "PRINCIPAL", principalID.ToString() } - }); - - if (ret == null) - return null; - if (ret.Count == 0) - return null; - - Dictionary folders = (Dictionary)ret["FOLDERS"]; - - List fldrs = new List(); - - try - { - foreach (Object o in folders.Values) - fldrs.Add(BuildFolder((Dictionary)o)); - } - catch (Exception e) - { - m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception unwrapping folder list: {0}", e.Message); - } - - return fldrs; - } - - public InventoryFolderBase GetRootFolder(UUID principalID) - { - Dictionary ret = MakeRequest("GETROOTFOLDER", - new Dictionary { - { "PRINCIPAL", principalID.ToString() } - }); - - if (ret == null) - return null; - if (ret.Count == 0) - return null; - - return BuildFolder((Dictionary)ret["folder"]); - } - - public InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) - { - Dictionary ret = MakeRequest("GETFOLDERFORTYPE", - new Dictionary { - { "PRINCIPAL", principalID.ToString() }, - { "TYPE", ((int)type).ToString() } - }); - - if (ret == null) - return null; - if (ret.Count == 0) - return null; - - return BuildFolder((Dictionary)ret["folder"]); - } - - public InventoryCollection GetFolderContent(UUID principalID, UUID folderID) - { - InventoryCollection inventory = new InventoryCollection(); - inventory.Folders = new List(); - inventory.Items = new List(); - inventory.UserID = principalID; - - try - { - Dictionary ret = MakeRequest("GETFOLDERCONTENT", - new Dictionary { - { "PRINCIPAL", principalID.ToString() }, - { "FOLDER", folderID.ToString() } - }); - - if (ret == null) - return null; - if (ret.Count == 0) - return null; - - Dictionary folders = - (Dictionary)ret["FOLDERS"]; - Dictionary items = - (Dictionary)ret["ITEMS"]; - - foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i - inventory.Folders.Add(BuildFolder((Dictionary)o)); - foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i - inventory.Items.Add(BuildItem((Dictionary)o)); - } - catch (Exception e) - { - m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetFolderContent: {0}", e.Message); - } - - return inventory; - } - - public List GetFolderItems(UUID principalID, UUID folderID) - { - Dictionary ret = MakeRequest("GETFOLDERITEMS", - new Dictionary { - { "PRINCIPAL", principalID.ToString() }, - { "FOLDER", folderID.ToString() } - }); - - if (ret == null) - return null; - if (ret.Count == 0) - return null; - - Dictionary items = (Dictionary)ret["ITEMS"]; - List fitems = new List(); - foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i - fitems.Add(BuildItem((Dictionary)o)); - - return fitems; - } - - public bool AddFolder(InventoryFolderBase folder) - { - Dictionary ret = MakeRequest("ADDFOLDER", - new Dictionary { - { "ParentID", folder.ParentID.ToString() }, - { "Type", folder.Type.ToString() }, - { "Version", folder.Version.ToString() }, - { "Name", folder.Name.ToString() }, - { "Owner", folder.Owner.ToString() }, - { "ID", folder.ID.ToString() } - }); - - if (ret == null) - return false; - - return bool.Parse(ret["RESULT"].ToString()); - } - - public bool UpdateFolder(InventoryFolderBase folder) - { - Dictionary ret = MakeRequest("UPDATEFOLDER", - new Dictionary { - { "ParentID", folder.ParentID.ToString() }, - { "Type", folder.Type.ToString() }, - { "Version", folder.Version.ToString() }, - { "Name", folder.Name.ToString() }, - { "Owner", folder.Owner.ToString() }, - { "ID", folder.ID.ToString() } - }); - - if (ret == null) - return false; - - return bool.Parse(ret["RESULT"].ToString()); - } - - public bool MoveFolder(InventoryFolderBase folder) - { - Dictionary ret = MakeRequest("MOVEFOLDER", - new Dictionary { - { "ParentID", folder.ParentID.ToString() }, - { "ID", folder.ID.ToString() }, - { "PRINCIPAL", folder.Owner.ToString() } - }); - - if (ret == null) - return false; - - return bool.Parse(ret["RESULT"].ToString()); - } - - public bool DeleteFolders(UUID principalID, List folderIDs) - { - List slist = new List(); - - foreach (UUID f in folderIDs) - slist.Add(f.ToString()); - - Dictionary ret = MakeRequest("DELETEFOLDERS", - new Dictionary { - { "PRINCIPAL", principalID.ToString() }, - { "FOLDERS", slist } - }); - - if (ret == null) - return false; - - return bool.Parse(ret["RESULT"].ToString()); - } - - public bool PurgeFolder(InventoryFolderBase folder) - { - Dictionary ret = MakeRequest("PURGEFOLDER", - new Dictionary { - { "ID", folder.ID.ToString() } - }); - - if (ret == null) - return false; - - return bool.Parse(ret["RESULT"].ToString()); - } - - public bool AddItem(InventoryItemBase item) - { - if (item.CreatorData == null) - item.CreatorData = String.Empty; - Dictionary ret = MakeRequest("ADDITEM", - new Dictionary { - { "AssetID", item.AssetID.ToString() }, - { "AssetType", item.AssetType.ToString() }, - { "Name", item.Name.ToString() }, - { "Owner", item.Owner.ToString() }, - { "ID", item.ID.ToString() }, - { "InvType", item.InvType.ToString() }, - { "Folder", item.Folder.ToString() }, - { "CreatorId", item.CreatorId.ToString() }, - { "CreatorData", item.CreatorData.ToString() }, - { "Description", item.Description.ToString() }, - { "NextPermissions", item.NextPermissions.ToString() }, - { "CurrentPermissions", item.CurrentPermissions.ToString() }, - { "BasePermissions", item.BasePermissions.ToString() }, - { "EveryOnePermissions", item.EveryOnePermissions.ToString() }, - { "GroupPermissions", item.GroupPermissions.ToString() }, - { "GroupID", item.GroupID.ToString() }, - { "GroupOwned", item.GroupOwned.ToString() }, - { "SalePrice", item.SalePrice.ToString() }, - { "SaleType", item.SaleType.ToString() }, - { "Flags", item.Flags.ToString() }, - { "CreationDate", item.CreationDate.ToString() } - }); - - if (ret == null) - return false; - - return bool.Parse(ret["RESULT"].ToString()); - } - - public bool UpdateItem(InventoryItemBase item) - { - if (item.CreatorData == null) - item.CreatorData = String.Empty; - Dictionary ret = MakeRequest("UPDATEITEM", - new Dictionary { - { "AssetID", item.AssetID.ToString() }, - { "AssetType", item.AssetType.ToString() }, - { "Name", item.Name.ToString() }, - { "Owner", item.Owner.ToString() }, - { "ID", item.ID.ToString() }, - { "InvType", item.InvType.ToString() }, - { "Folder", item.Folder.ToString() }, - { "CreatorId", item.CreatorId.ToString() }, - { "CreatorData", item.CreatorData.ToString() }, - { "Description", item.Description.ToString() }, - { "NextPermissions", item.NextPermissions.ToString() }, - { "CurrentPermissions", item.CurrentPermissions.ToString() }, - { "BasePermissions", item.BasePermissions.ToString() }, - { "EveryOnePermissions", item.EveryOnePermissions.ToString() }, - { "GroupPermissions", item.GroupPermissions.ToString() }, - { "GroupID", item.GroupID.ToString() }, - { "GroupOwned", item.GroupOwned.ToString() }, - { "SalePrice", item.SalePrice.ToString() }, - { "SaleType", item.SaleType.ToString() }, - { "Flags", item.Flags.ToString() }, - { "CreationDate", item.CreationDate.ToString() } - }); - - if (ret == null) - return false; - - return bool.Parse(ret["RESULT"].ToString()); - } - - public bool MoveItems(UUID principalID, List items) - { - List idlist = new List(); - List destlist = new List(); - - foreach (InventoryItemBase item in items) - { - idlist.Add(item.ID.ToString()); - destlist.Add(item.Folder.ToString()); - } - - Dictionary ret = MakeRequest("MOVEITEMS", - new Dictionary { - { "PRINCIPAL", principalID.ToString() }, - { "IDLIST", idlist }, - { "DESTLIST", destlist } - }); - - if (ret == null) - return false; - - return bool.Parse(ret["RESULT"].ToString()); - } - - public bool DeleteItems(UUID principalID, List itemIDs) - { - List slist = new List(); - - foreach (UUID f in itemIDs) - slist.Add(f.ToString()); - - Dictionary ret = MakeRequest("DELETEITEMS", - new Dictionary { - { "PRINCIPAL", principalID.ToString() }, - { "ITEMS", slist } - }); - - if (ret == null) - return false; - - return bool.Parse(ret["RESULT"].ToString()); - } - - public InventoryItemBase GetItem(InventoryItemBase item) - { - try - { - Dictionary ret = MakeRequest("GETITEM", - new Dictionary { - { "ID", item.ID.ToString() } - }); - - if (ret == null) - return null; - if (ret.Count == 0) - return null; - - return BuildItem((Dictionary)ret["item"]); - } - catch (Exception e) - { - m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetItem: {0}", e.Message); - } - - return null; - } - - public InventoryFolderBase GetFolder(InventoryFolderBase folder) - { - try - { - Dictionary ret = MakeRequest("GETFOLDER", - new Dictionary { - { "ID", folder.ID.ToString() } - }); - - if (ret == null) - return null; - if (ret.Count == 0) - return null; - - return BuildFolder((Dictionary)ret["folder"]); - } - catch (Exception e) - { - m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetFolder: {0}", e.Message); - } - - return null; - } - - public List GetActiveGestures(UUID principalID) - { - Dictionary ret = MakeRequest("GETACTIVEGESTURES", - new Dictionary { - { "PRINCIPAL", principalID.ToString() } - }); - - if (ret == null) - return null; - - List items = new List(); - - foreach (Object o in ret.Values) // getting the values directly, we don't care about the keys item_i - items.Add(BuildItem((Dictionary)o)); - - return items; - } - - public int GetAssetPermissions(UUID principalID, UUID assetID) - { - Dictionary ret = MakeRequest("GETASSETPERMISSIONS", - new Dictionary { - { "PRINCIPAL", principalID.ToString() }, - { "ASSET", assetID.ToString() } - }); - - if (ret == null) - return 0; - - return int.Parse(ret["RESULT"].ToString()); - } - - public InventoryCollection GetUserInventory(UUID principalID) - { - InventoryCollection inventory = new InventoryCollection(); - inventory.Folders = new List(); - inventory.Items = new List(); - inventory.UserID = principalID; - - try - { - Dictionary ret = MakeRequest("GETUSERINVENTORY", - new Dictionary { - { "PRINCIPAL", principalID.ToString() } - }); - - if (ret == null) - return null; - if (ret.Count == 0) - return null; - - Dictionary folders = - (Dictionary)ret["FOLDERS"]; - Dictionary items = - (Dictionary)ret["ITEMS"]; - - foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i - inventory.Folders.Add(BuildFolder((Dictionary)o)); - foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i - inventory.Items.Add(BuildItem((Dictionary)o)); - } - catch (Exception e) - { - m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetUserInventory: {0}", e.Message); - } - - return inventory; - } - - public void GetUserInventory(UUID principalID, InventoryReceiptCallback callback) - { - } - - public bool HasInventoryForUser(UUID principalID) - { - return false; - } - - // Helpers - // - private Dictionary MakeRequest(string method, - Dictionary sendData) - { - sendData["METHOD"] = method; - - string reply = string.Empty; - lock (m_Lock) - reply = SynchronousRestFormsRequester.MakeRequest("POST", - m_ServerURI + "/xinventory", - ServerUtils.BuildQueryString(sendData)); - - Dictionary replyData = ServerUtils.ParseXmlResponse( - reply); - - return replyData; - } - - private InventoryFolderBase BuildFolder(Dictionary data) - { - InventoryFolderBase folder = new InventoryFolderBase(); - - try - { - folder.ParentID = new UUID(data["ParentID"].ToString()); - folder.Type = short.Parse(data["Type"].ToString()); - folder.Version = ushort.Parse(data["Version"].ToString()); - folder.Name = data["Name"].ToString(); - folder.Owner = new UUID(data["Owner"].ToString()); - folder.ID = new UUID(data["ID"].ToString()); - } - catch (Exception e) - { - m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception building folder: {0}", e.Message); - } - - return folder; - } - - private InventoryItemBase BuildItem(Dictionary data) - { - InventoryItemBase item = new InventoryItemBase(); - - try - { - item.AssetID = new UUID(data["AssetID"].ToString()); - item.AssetType = int.Parse(data["AssetType"].ToString()); - item.Name = data["Name"].ToString(); - item.Owner = new UUID(data["Owner"].ToString()); - item.ID = new UUID(data["ID"].ToString()); - item.InvType = int.Parse(data["InvType"].ToString()); - item.Folder = new UUID(data["Folder"].ToString()); - item.CreatorId = data["CreatorId"].ToString(); - if (data.ContainsKey("CreatorData")) - item.CreatorData = data["CreatorData"].ToString(); - else - item.CreatorData = String.Empty; - item.Description = data["Description"].ToString(); - item.NextPermissions = uint.Parse(data["NextPermissions"].ToString()); - item.CurrentPermissions = uint.Parse(data["CurrentPermissions"].ToString()); - item.BasePermissions = uint.Parse(data["BasePermissions"].ToString()); - item.EveryOnePermissions = uint.Parse(data["EveryOnePermissions"].ToString()); - item.GroupPermissions = uint.Parse(data["GroupPermissions"].ToString()); - item.GroupID = new UUID(data["GroupID"].ToString()); - item.GroupOwned = bool.Parse(data["GroupOwned"].ToString()); - item.SalePrice = int.Parse(data["SalePrice"].ToString()); - item.SaleType = byte.Parse(data["SaleType"].ToString()); - item.Flags = uint.Parse(data["Flags"].ToString()); - item.CreationDate = int.Parse(data["CreationDate"].ToString()); - } - catch (Exception e) - { - m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception building item: {0}", e.Message); - } - - return item; - } - - } -} diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs new file mode 100644 index 0000000..9d96703 --- /dev/null +++ b/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs @@ -0,0 +1,623 @@ +/* + * 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 log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Communications; +using OpenSim.Services.Interfaces; +using OpenSim.Server.Base; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors +{ + public class XInventoryServicesConnector : IInventoryService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + + private object m_Lock = new object(); + + public XInventoryServicesConnector() + { + } + + public XInventoryServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + + public XInventoryServicesConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig assetConfig = source.Configs["InventoryService"]; + if (assetConfig == null) + { + m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini"); + throw new Exception("Inventory connector init error"); + } + + string serviceURI = assetConfig.GetString("InventoryServerURI", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[INVENTORY CONNECTOR]: No Server URI named in section InventoryService"); + throw new Exception("Inventory connector init error"); + } + m_ServerURI = serviceURI; + } + + public bool CreateUserInventory(UUID principalID) + { + Dictionary ret = MakeRequest("CREATEUSERINVENTORY", + new Dictionary { + { "PRINCIPAL", principalID.ToString() } + }); + + if (ret == null) + return false; + if (ret.Count == 0) + return false; + + return bool.Parse(ret["RESULT"].ToString()); + } + + public List GetInventorySkeleton(UUID principalID) + { + Dictionary ret = MakeRequest("GETINVENTORYSKELETON", + new Dictionary { + { "PRINCIPAL", principalID.ToString() } + }); + + if (ret == null) + return null; + if (ret.Count == 0) + return null; + + Dictionary folders = (Dictionary)ret["FOLDERS"]; + + List fldrs = new List(); + + try + { + foreach (Object o in folders.Values) + fldrs.Add(BuildFolder((Dictionary)o)); + } + catch (Exception e) + { + m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception unwrapping folder list: {0}", e.Message); + } + + return fldrs; + } + + public InventoryFolderBase GetRootFolder(UUID principalID) + { + Dictionary ret = MakeRequest("GETROOTFOLDER", + new Dictionary { + { "PRINCIPAL", principalID.ToString() } + }); + + if (ret == null) + return null; + if (ret.Count == 0) + return null; + + return BuildFolder((Dictionary)ret["folder"]); + } + + public InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) + { + Dictionary ret = MakeRequest("GETFOLDERFORTYPE", + new Dictionary { + { "PRINCIPAL", principalID.ToString() }, + { "TYPE", ((int)type).ToString() } + }); + + if (ret == null) + return null; + if (ret.Count == 0) + return null; + + return BuildFolder((Dictionary)ret["folder"]); + } + + public InventoryCollection GetFolderContent(UUID principalID, UUID folderID) + { + InventoryCollection inventory = new InventoryCollection(); + inventory.Folders = new List(); + inventory.Items = new List(); + inventory.UserID = principalID; + + try + { + Dictionary ret = MakeRequest("GETFOLDERCONTENT", + new Dictionary { + { "PRINCIPAL", principalID.ToString() }, + { "FOLDER", folderID.ToString() } + }); + + if (ret == null) + return null; + if (ret.Count == 0) + return null; + + Dictionary folders = + (Dictionary)ret["FOLDERS"]; + Dictionary items = + (Dictionary)ret["ITEMS"]; + + foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i + inventory.Folders.Add(BuildFolder((Dictionary)o)); + foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i + inventory.Items.Add(BuildItem((Dictionary)o)); + } + catch (Exception e) + { + m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetFolderContent: {0}", e.Message); + } + + return inventory; + } + + public List GetFolderItems(UUID principalID, UUID folderID) + { + Dictionary ret = MakeRequest("GETFOLDERITEMS", + new Dictionary { + { "PRINCIPAL", principalID.ToString() }, + { "FOLDER", folderID.ToString() } + }); + + if (ret == null) + return null; + if (ret.Count == 0) + return null; + + Dictionary items = (Dictionary)ret["ITEMS"]; + List fitems = new List(); + foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i + fitems.Add(BuildItem((Dictionary)o)); + + return fitems; + } + + public bool AddFolder(InventoryFolderBase folder) + { + Dictionary ret = MakeRequest("ADDFOLDER", + new Dictionary { + { "ParentID", folder.ParentID.ToString() }, + { "Type", folder.Type.ToString() }, + { "Version", folder.Version.ToString() }, + { "Name", folder.Name.ToString() }, + { "Owner", folder.Owner.ToString() }, + { "ID", folder.ID.ToString() } + }); + + if (ret == null) + return false; + + return bool.Parse(ret["RESULT"].ToString()); + } + + public bool UpdateFolder(InventoryFolderBase folder) + { + Dictionary ret = MakeRequest("UPDATEFOLDER", + new Dictionary { + { "ParentID", folder.ParentID.ToString() }, + { "Type", folder.Type.ToString() }, + { "Version", folder.Version.ToString() }, + { "Name", folder.Name.ToString() }, + { "Owner", folder.Owner.ToString() }, + { "ID", folder.ID.ToString() } + }); + + if (ret == null) + return false; + + return bool.Parse(ret["RESULT"].ToString()); + } + + public bool MoveFolder(InventoryFolderBase folder) + { + Dictionary ret = MakeRequest("MOVEFOLDER", + new Dictionary { + { "ParentID", folder.ParentID.ToString() }, + { "ID", folder.ID.ToString() }, + { "PRINCIPAL", folder.Owner.ToString() } + }); + + if (ret == null) + return false; + + return bool.Parse(ret["RESULT"].ToString()); + } + + public bool DeleteFolders(UUID principalID, List folderIDs) + { + List slist = new List(); + + foreach (UUID f in folderIDs) + slist.Add(f.ToString()); + + Dictionary ret = MakeRequest("DELETEFOLDERS", + new Dictionary { + { "PRINCIPAL", principalID.ToString() }, + { "FOLDERS", slist } + }); + + if (ret == null) + return false; + + return bool.Parse(ret["RESULT"].ToString()); + } + + public bool PurgeFolder(InventoryFolderBase folder) + { + Dictionary ret = MakeRequest("PURGEFOLDER", + new Dictionary { + { "ID", folder.ID.ToString() } + }); + + if (ret == null) + return false; + + return bool.Parse(ret["RESULT"].ToString()); + } + + public bool AddItem(InventoryItemBase item) + { + if (item.CreatorData == null) + item.CreatorData = String.Empty; + Dictionary ret = MakeRequest("ADDITEM", + new Dictionary { + { "AssetID", item.AssetID.ToString() }, + { "AssetType", item.AssetType.ToString() }, + { "Name", item.Name.ToString() }, + { "Owner", item.Owner.ToString() }, + { "ID", item.ID.ToString() }, + { "InvType", item.InvType.ToString() }, + { "Folder", item.Folder.ToString() }, + { "CreatorId", item.CreatorId.ToString() }, + { "CreatorData", item.CreatorData.ToString() }, + { "Description", item.Description.ToString() }, + { "NextPermissions", item.NextPermissions.ToString() }, + { "CurrentPermissions", item.CurrentPermissions.ToString() }, + { "BasePermissions", item.BasePermissions.ToString() }, + { "EveryOnePermissions", item.EveryOnePermissions.ToString() }, + { "GroupPermissions", item.GroupPermissions.ToString() }, + { "GroupID", item.GroupID.ToString() }, + { "GroupOwned", item.GroupOwned.ToString() }, + { "SalePrice", item.SalePrice.ToString() }, + { "SaleType", item.SaleType.ToString() }, + { "Flags", item.Flags.ToString() }, + { "CreationDate", item.CreationDate.ToString() } + }); + + if (ret == null) + return false; + + return bool.Parse(ret["RESULT"].ToString()); + } + + public bool UpdateItem(InventoryItemBase item) + { + if (item.CreatorData == null) + item.CreatorData = String.Empty; + Dictionary ret = MakeRequest("UPDATEITEM", + new Dictionary { + { "AssetID", item.AssetID.ToString() }, + { "AssetType", item.AssetType.ToString() }, + { "Name", item.Name.ToString() }, + { "Owner", item.Owner.ToString() }, + { "ID", item.ID.ToString() }, + { "InvType", item.InvType.ToString() }, + { "Folder", item.Folder.ToString() }, + { "CreatorId", item.CreatorId.ToString() }, + { "CreatorData", item.CreatorData.ToString() }, + { "Description", item.Description.ToString() }, + { "NextPermissions", item.NextPermissions.ToString() }, + { "CurrentPermissions", item.CurrentPermissions.ToString() }, + { "BasePermissions", item.BasePermissions.ToString() }, + { "EveryOnePermissions", item.EveryOnePermissions.ToString() }, + { "GroupPermissions", item.GroupPermissions.ToString() }, + { "GroupID", item.GroupID.ToString() }, + { "GroupOwned", item.GroupOwned.ToString() }, + { "SalePrice", item.SalePrice.ToString() }, + { "SaleType", item.SaleType.ToString() }, + { "Flags", item.Flags.ToString() }, + { "CreationDate", item.CreationDate.ToString() } + }); + + if (ret == null) + return false; + + return bool.Parse(ret["RESULT"].ToString()); + } + + public bool MoveItems(UUID principalID, List items) + { + List idlist = new List(); + List destlist = new List(); + + foreach (InventoryItemBase item in items) + { + idlist.Add(item.ID.ToString()); + destlist.Add(item.Folder.ToString()); + } + + Dictionary ret = MakeRequest("MOVEITEMS", + new Dictionary { + { "PRINCIPAL", principalID.ToString() }, + { "IDLIST", idlist }, + { "DESTLIST", destlist } + }); + + if (ret == null) + return false; + + return bool.Parse(ret["RESULT"].ToString()); + } + + public bool DeleteItems(UUID principalID, List itemIDs) + { + List slist = new List(); + + foreach (UUID f in itemIDs) + slist.Add(f.ToString()); + + Dictionary ret = MakeRequest("DELETEITEMS", + new Dictionary { + { "PRINCIPAL", principalID.ToString() }, + { "ITEMS", slist } + }); + + if (ret == null) + return false; + + return bool.Parse(ret["RESULT"].ToString()); + } + + public InventoryItemBase GetItem(InventoryItemBase item) + { + try + { + Dictionary ret = MakeRequest("GETITEM", + new Dictionary { + { "ID", item.ID.ToString() } + }); + + if (ret == null) + return null; + if (ret.Count == 0) + return null; + + return BuildItem((Dictionary)ret["item"]); + } + catch (Exception e) + { + m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetItem: {0}", e.Message); + } + + return null; + } + + public InventoryFolderBase GetFolder(InventoryFolderBase folder) + { + try + { + Dictionary ret = MakeRequest("GETFOLDER", + new Dictionary { + { "ID", folder.ID.ToString() } + }); + + if (ret == null) + return null; + if (ret.Count == 0) + return null; + + return BuildFolder((Dictionary)ret["folder"]); + } + catch (Exception e) + { + m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetFolder: {0}", e.Message); + } + + return null; + } + + public List GetActiveGestures(UUID principalID) + { + Dictionary ret = MakeRequest("GETACTIVEGESTURES", + new Dictionary { + { "PRINCIPAL", principalID.ToString() } + }); + + if (ret == null) + return null; + + List items = new List(); + + foreach (Object o in ret.Values) // getting the values directly, we don't care about the keys item_i + items.Add(BuildItem((Dictionary)o)); + + return items; + } + + public int GetAssetPermissions(UUID principalID, UUID assetID) + { + Dictionary ret = MakeRequest("GETASSETPERMISSIONS", + new Dictionary { + { "PRINCIPAL", principalID.ToString() }, + { "ASSET", assetID.ToString() } + }); + + if (ret == null) + return 0; + + return int.Parse(ret["RESULT"].ToString()); + } + + public InventoryCollection GetUserInventory(UUID principalID) + { + InventoryCollection inventory = new InventoryCollection(); + inventory.Folders = new List(); + inventory.Items = new List(); + inventory.UserID = principalID; + + try + { + Dictionary ret = MakeRequest("GETUSERINVENTORY", + new Dictionary { + { "PRINCIPAL", principalID.ToString() } + }); + + if (ret == null) + return null; + if (ret.Count == 0) + return null; + + Dictionary folders = + (Dictionary)ret["FOLDERS"]; + Dictionary items = + (Dictionary)ret["ITEMS"]; + + foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i + inventory.Folders.Add(BuildFolder((Dictionary)o)); + foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i + inventory.Items.Add(BuildItem((Dictionary)o)); + } + catch (Exception e) + { + m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetUserInventory: {0}", e.Message); + } + + return inventory; + } + + public void GetUserInventory(UUID principalID, InventoryReceiptCallback callback) + { + } + + public bool HasInventoryForUser(UUID principalID) + { + return false; + } + + // Helpers + // + private Dictionary MakeRequest(string method, + Dictionary sendData) + { + sendData["METHOD"] = method; + + string reply = string.Empty; + lock (m_Lock) + reply = SynchronousRestFormsRequester.MakeRequest("POST", + m_ServerURI + "/xinventory", + ServerUtils.BuildQueryString(sendData)); + + Dictionary replyData = ServerUtils.ParseXmlResponse( + reply); + + return replyData; + } + + private InventoryFolderBase BuildFolder(Dictionary data) + { + InventoryFolderBase folder = new InventoryFolderBase(); + + try + { + folder.ParentID = new UUID(data["ParentID"].ToString()); + folder.Type = short.Parse(data["Type"].ToString()); + folder.Version = ushort.Parse(data["Version"].ToString()); + folder.Name = data["Name"].ToString(); + folder.Owner = new UUID(data["Owner"].ToString()); + folder.ID = new UUID(data["ID"].ToString()); + } + catch (Exception e) + { + m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception building folder: {0}", e.Message); + } + + return folder; + } + + private InventoryItemBase BuildItem(Dictionary data) + { + InventoryItemBase item = new InventoryItemBase(); + + try + { + item.AssetID = new UUID(data["AssetID"].ToString()); + item.AssetType = int.Parse(data["AssetType"].ToString()); + item.Name = data["Name"].ToString(); + item.Owner = new UUID(data["Owner"].ToString()); + item.ID = new UUID(data["ID"].ToString()); + item.InvType = int.Parse(data["InvType"].ToString()); + item.Folder = new UUID(data["Folder"].ToString()); + item.CreatorId = data["CreatorId"].ToString(); + if (data.ContainsKey("CreatorData")) + item.CreatorData = data["CreatorData"].ToString(); + else + item.CreatorData = String.Empty; + item.Description = data["Description"].ToString(); + item.NextPermissions = uint.Parse(data["NextPermissions"].ToString()); + item.CurrentPermissions = uint.Parse(data["CurrentPermissions"].ToString()); + item.BasePermissions = uint.Parse(data["BasePermissions"].ToString()); + item.EveryOnePermissions = uint.Parse(data["EveryOnePermissions"].ToString()); + item.GroupPermissions = uint.Parse(data["GroupPermissions"].ToString()); + item.GroupID = new UUID(data["GroupID"].ToString()); + item.GroupOwned = bool.Parse(data["GroupOwned"].ToString()); + item.SalePrice = int.Parse(data["SalePrice"].ToString()); + item.SaleType = byte.Parse(data["SaleType"].ToString()); + item.Flags = uint.Parse(data["Flags"].ToString()); + item.CreationDate = int.Parse(data["CreationDate"].ToString()); + } + catch (Exception e) + { + m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception building item: {0}", e.Message); + } + + return item; + } + + } +} diff --git a/OpenSim/Services/Connectors/Land/LandServiceConnector.cs b/OpenSim/Services/Connectors/Land/LandServiceConnector.cs deleted file mode 100644 index 30a73a4..0000000 --- a/OpenSim/Services/Connectors/Land/LandServiceConnector.cs +++ /dev/null @@ -1,133 +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 log4net; -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Services.Interfaces; -using OpenMetaverse; -using Nwc.XmlRpc; -using GridRegion = OpenSim.Services.Interfaces.GridRegion; - -namespace OpenSim.Services.Connectors -{ - public class LandServicesConnector : ILandService - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - protected IGridService m_GridService = null; - - public LandServicesConnector() - { - } - - public LandServicesConnector(IGridService gridServices) - { - Initialise(gridServices); - } - - public virtual void Initialise(IGridService gridServices) - { - m_GridService = gridServices; - } - - public virtual LandData GetLandData(UUID scopeID, ulong regionHandle, uint x, uint y, out byte regionAccess) - { - LandData landData = null; - Hashtable hash = new Hashtable(); - hash["region_handle"] = regionHandle.ToString(); - hash["x"] = x.ToString(); - hash["y"] = y.ToString(); - - IList paramList = new ArrayList(); - paramList.Add(hash); - regionAccess = 42; // Default to adult. Better safe... - - try - { - uint xpos = 0, ypos = 0; - Utils.LongToUInts(regionHandle, out xpos, out ypos); - GridRegion info = m_GridService.GetRegionByPosition(scopeID, (int)xpos, (int)ypos); - if (info != null) // just to be sure - { - XmlRpcRequest request = new XmlRpcRequest("land_data", paramList); - XmlRpcResponse response = request.Send(info.ServerURI, 10000); - if (response.IsFault) - { - m_log.ErrorFormat("[LAND CONNECTOR]: remote call returned an error: {0}", response.FaultString); - } - else - { - hash = (Hashtable)response.Value; - try - { - landData = new LandData(); - landData.AABBMax = Vector3.Parse((string)hash["AABBMax"]); - landData.AABBMin = Vector3.Parse((string)hash["AABBMin"]); - landData.Area = Convert.ToInt32(hash["Area"]); - landData.AuctionID = Convert.ToUInt32(hash["AuctionID"]); - landData.Description = (string)hash["Description"]; - landData.Flags = Convert.ToUInt32(hash["Flags"]); - landData.GlobalID = new UUID((string)hash["GlobalID"]); - landData.Name = (string)hash["Name"]; - landData.OwnerID = new UUID((string)hash["OwnerID"]); - landData.SalePrice = Convert.ToInt32(hash["SalePrice"]); - landData.SnapshotID = new UUID((string)hash["SnapshotID"]); - landData.UserLocation = Vector3.Parse((string)hash["UserLocation"]); - if (hash["RegionAccess"] != null) - regionAccess = (byte)Convert.ToInt32((string)hash["RegionAccess"]); - m_log.DebugFormat("[LAND CONNECTOR]: Got land data for parcel {0}", landData.Name); - } - catch (Exception e) - { - m_log.ErrorFormat( - "[LAND CONNECTOR]: Got exception while parsing land-data: {0} {1}", - e.Message, e.StackTrace); - } - } - } - else - m_log.WarnFormat("[LAND CONNECTOR]: Couldn't find region with handle {0}", regionHandle); - } - catch (Exception e) - { - m_log.ErrorFormat( - "[LAND CONNECTOR]: Couldn't contact region {0}: {1} {2}", regionHandle, e.Message, e.StackTrace); - } - - return landData; - } - } -} \ No newline at end of file diff --git a/OpenSim/Services/Connectors/Land/LandServicesConnector.cs b/OpenSim/Services/Connectors/Land/LandServicesConnector.cs new file mode 100644 index 0000000..30a73a4 --- /dev/null +++ b/OpenSim/Services/Connectors/Land/LandServicesConnector.cs @@ -0,0 +1,133 @@ +/* + * 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 log4net; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Services.Interfaces; +using OpenMetaverse; +using Nwc.XmlRpc; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +namespace OpenSim.Services.Connectors +{ + public class LandServicesConnector : ILandService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + protected IGridService m_GridService = null; + + public LandServicesConnector() + { + } + + public LandServicesConnector(IGridService gridServices) + { + Initialise(gridServices); + } + + public virtual void Initialise(IGridService gridServices) + { + m_GridService = gridServices; + } + + public virtual LandData GetLandData(UUID scopeID, ulong regionHandle, uint x, uint y, out byte regionAccess) + { + LandData landData = null; + Hashtable hash = new Hashtable(); + hash["region_handle"] = regionHandle.ToString(); + hash["x"] = x.ToString(); + hash["y"] = y.ToString(); + + IList paramList = new ArrayList(); + paramList.Add(hash); + regionAccess = 42; // Default to adult. Better safe... + + try + { + uint xpos = 0, ypos = 0; + Utils.LongToUInts(regionHandle, out xpos, out ypos); + GridRegion info = m_GridService.GetRegionByPosition(scopeID, (int)xpos, (int)ypos); + if (info != null) // just to be sure + { + XmlRpcRequest request = new XmlRpcRequest("land_data", paramList); + XmlRpcResponse response = request.Send(info.ServerURI, 10000); + if (response.IsFault) + { + m_log.ErrorFormat("[LAND CONNECTOR]: remote call returned an error: {0}", response.FaultString); + } + else + { + hash = (Hashtable)response.Value; + try + { + landData = new LandData(); + landData.AABBMax = Vector3.Parse((string)hash["AABBMax"]); + landData.AABBMin = Vector3.Parse((string)hash["AABBMin"]); + landData.Area = Convert.ToInt32(hash["Area"]); + landData.AuctionID = Convert.ToUInt32(hash["AuctionID"]); + landData.Description = (string)hash["Description"]; + landData.Flags = Convert.ToUInt32(hash["Flags"]); + landData.GlobalID = new UUID((string)hash["GlobalID"]); + landData.Name = (string)hash["Name"]; + landData.OwnerID = new UUID((string)hash["OwnerID"]); + landData.SalePrice = Convert.ToInt32(hash["SalePrice"]); + landData.SnapshotID = new UUID((string)hash["SnapshotID"]); + landData.UserLocation = Vector3.Parse((string)hash["UserLocation"]); + if (hash["RegionAccess"] != null) + regionAccess = (byte)Convert.ToInt32((string)hash["RegionAccess"]); + m_log.DebugFormat("[LAND CONNECTOR]: Got land data for parcel {0}", landData.Name); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[LAND CONNECTOR]: Got exception while parsing land-data: {0} {1}", + e.Message, e.StackTrace); + } + } + } + else + m_log.WarnFormat("[LAND CONNECTOR]: Couldn't find region with handle {0}", regionHandle); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[LAND CONNECTOR]: Couldn't contact region {0}: {1} {2}", regionHandle, e.Message, e.StackTrace); + } + + return landData; + } + } +} \ No newline at end of file diff --git a/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs b/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs deleted file mode 100644 index 30bfb70..0000000 --- a/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs +++ /dev/null @@ -1,159 +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 log4net; -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Reflection; - -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Console; -using OpenSim.Framework.Communications; -using OpenSim.Server.Base; -using OpenSim.Services.Interfaces; -using OpenMetaverse; -using OpenMetaverse.StructuredData; - -namespace OpenSim.Services.Connectors -{ - public class MapImageServicesConnector : IMapImageService - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - private string m_ServerURI = String.Empty; - - public MapImageServicesConnector() - { - } - - public MapImageServicesConnector(string serverURI) - { - m_ServerURI = serverURI.TrimEnd('/'); - } - - public MapImageServicesConnector(IConfigSource source) - { - Initialise(source); - } - - public virtual void Initialise(IConfigSource source) - { - IConfig config = source.Configs["MapImageService"]; - if (config == null) - { - m_log.Error("[MAP IMAGE CONNECTOR]: MapImageService missing"); - throw new Exception("MapImage connector init error"); - } - - string serviceURI = config.GetString("MapImageServerURI", - String.Empty); - - if (serviceURI == String.Empty) - { - m_log.Error("[MAP IMAGE CONNECTOR]: No Server URI named in section MapImageService"); - throw new Exception("MapImage connector init error"); - } - m_ServerURI = serviceURI; - m_ServerURI = serviceURI.TrimEnd('/'); - } - - public bool AddMapTile(int x, int y, byte[] jpgData, out string reason) - { - reason = string.Empty; - int tickstart = Util.EnvironmentTickCount(); - Dictionary sendData = new Dictionary(); - sendData["X"] = x.ToString(); - sendData["Y"] = y.ToString(); - sendData["TYPE"] = "image/jpeg"; - sendData["DATA"] = Convert.ToBase64String(jpgData); - - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/map"; - - try - { - string reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - reqString); - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData.ContainsKey("Result") && (replyData["Result"].ToString().ToLower() == "success")) - { - return true; - } - else if (replyData.ContainsKey("Result") && (replyData["Result"].ToString().ToLower() == "failure")) - { - m_log.DebugFormat("[MAP IMAGE CONNECTOR]: Registration failed: {0}", replyData["Message"].ToString()); - reason = replyData["Message"].ToString(); - return false; - } - else if (!replyData.ContainsKey("Result")) - { - m_log.DebugFormat("[MAP IMAGE CONNECTOR]: reply data does not contain result field"); - } - else - { - m_log.DebugFormat("[MAP IMAGE CONNECTOR]: unexpected result {0}", replyData["Result"].ToString()); - reason = "Unexpected result " + replyData["Result"].ToString(); - } - - } - else - { - m_log.DebugFormat("[MAP IMAGE CONNECTOR]: Map post received null reply"); - } - } - catch (Exception e) - { - m_log.DebugFormat("[MAP IMAGE CONNECTOR]: Exception when contacting map server at {0}: {1}", uri, e.Message); - } - finally - { - // This just dumps a warning for any operation that takes more than 100 ms - int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); - m_log.DebugFormat("[MAP IMAGE CONNECTOR]: map tile uploaded in {0}ms", tickdiff); - } - - return false; - - } - - public byte[] GetMapTile(string fileName, out string format) - { - format = string.Empty; - new Exception("GetMapTile method not Implemented"); - return null; - } - } -} diff --git a/OpenSim/Services/Connectors/MapImage/MapImageServicesConnector.cs b/OpenSim/Services/Connectors/MapImage/MapImageServicesConnector.cs new file mode 100644 index 0000000..30bfb70 --- /dev/null +++ b/OpenSim/Services/Connectors/MapImage/MapImageServicesConnector.cs @@ -0,0 +1,159 @@ +/* + * 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 log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Reflection; + +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Communications; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Services.Connectors +{ + public class MapImageServicesConnector : IMapImageService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + + public MapImageServicesConnector() + { + } + + public MapImageServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + + public MapImageServicesConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig config = source.Configs["MapImageService"]; + if (config == null) + { + m_log.Error("[MAP IMAGE CONNECTOR]: MapImageService missing"); + throw new Exception("MapImage connector init error"); + } + + string serviceURI = config.GetString("MapImageServerURI", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[MAP IMAGE CONNECTOR]: No Server URI named in section MapImageService"); + throw new Exception("MapImage connector init error"); + } + m_ServerURI = serviceURI; + m_ServerURI = serviceURI.TrimEnd('/'); + } + + public bool AddMapTile(int x, int y, byte[] jpgData, out string reason) + { + reason = string.Empty; + int tickstart = Util.EnvironmentTickCount(); + Dictionary sendData = new Dictionary(); + sendData["X"] = x.ToString(); + sendData["Y"] = y.ToString(); + sendData["TYPE"] = "image/jpeg"; + sendData["DATA"] = Convert.ToBase64String(jpgData); + + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/map"; + + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + reqString); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("Result") && (replyData["Result"].ToString().ToLower() == "success")) + { + return true; + } + else if (replyData.ContainsKey("Result") && (replyData["Result"].ToString().ToLower() == "failure")) + { + m_log.DebugFormat("[MAP IMAGE CONNECTOR]: Registration failed: {0}", replyData["Message"].ToString()); + reason = replyData["Message"].ToString(); + return false; + } + else if (!replyData.ContainsKey("Result")) + { + m_log.DebugFormat("[MAP IMAGE CONNECTOR]: reply data does not contain result field"); + } + else + { + m_log.DebugFormat("[MAP IMAGE CONNECTOR]: unexpected result {0}", replyData["Result"].ToString()); + reason = "Unexpected result " + replyData["Result"].ToString(); + } + + } + else + { + m_log.DebugFormat("[MAP IMAGE CONNECTOR]: Map post received null reply"); + } + } + catch (Exception e) + { + m_log.DebugFormat("[MAP IMAGE CONNECTOR]: Exception when contacting map server at {0}: {1}", uri, e.Message); + } + finally + { + // This just dumps a warning for any operation that takes more than 100 ms + int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); + m_log.DebugFormat("[MAP IMAGE CONNECTOR]: map tile uploaded in {0}ms", tickdiff); + } + + return false; + + } + + public byte[] GetMapTile(string fileName, out string format) + { + format = string.Empty; + new Exception("GetMapTile method not Implemented"); + return null; + } + } +} diff --git a/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs b/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs deleted file mode 100644 index 888b072..0000000 --- a/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs +++ /dev/null @@ -1,206 +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 log4net; -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Reflection; -using System.Text; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Services.Interfaces; -using OpenMetaverse; -using OpenMetaverse.StructuredData; - -using GridRegion = OpenSim.Services.Interfaces.GridRegion; - -namespace OpenSim.Services.Connectors -{ - public class NeighbourServicesConnector : INeighbourService - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - protected IGridService m_GridService = null; - - public NeighbourServicesConnector() - { - } - - public NeighbourServicesConnector(IGridService gridServices) - { - Initialise(gridServices); - } - - public virtual void Initialise(IGridService gridServices) - { - m_GridService = gridServices; - } - - public virtual GridRegion HelloNeighbour(ulong regionHandle, RegionInfo thisRegion) - { - uint x = 0, y = 0; - Utils.LongToUInts(regionHandle, out x, out y); - GridRegion regInfo = m_GridService.GetRegionByPosition(thisRegion.ScopeID, (int)x, (int)y); - if ((regInfo != null) && - // Don't remote-call this instance; that's a startup hickup - !((regInfo.ExternalHostName == thisRegion.ExternalHostName) && (regInfo.HttpPort == thisRegion.HttpPort))) - { - if (!DoHelloNeighbourCall(regInfo, thisRegion)) - return null; - } - else - return null; - - return regInfo; - } - - public bool DoHelloNeighbourCall(GridRegion region, RegionInfo thisRegion) - { - string uri = region.ServerURI + "region/" + thisRegion.RegionID + "/"; -// m_log.Debug(" >>> DoHelloNeighbourCall <<< " + uri); - - WebRequest helloNeighbourRequest; - - try - { - helloNeighbourRequest = WebRequest.Create(uri); - } - catch (Exception e) - { - m_log.WarnFormat( - "[NEIGHBOUR SERVICE CONNCTOR]: Unable to parse uri {0} to send HelloNeighbour from {1} to {2}. Exception {3}{4}", - uri, thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); - - return false; - } - - helloNeighbourRequest.Method = "POST"; - helloNeighbourRequest.ContentType = "application/json"; - helloNeighbourRequest.Timeout = 10000; - - // Fill it in - OSDMap args = null; - try - { - args = thisRegion.PackRegionInfoData(); - } - catch (Exception e) - { - m_log.WarnFormat( - "[NEIGHBOUR SERVICE CONNCTOR]: PackRegionInfoData failed for HelloNeighbour from {0} to {1}. Exception {2}{3}", - thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); - - return false; - } - - // Add the regionhandle of the destination region - args["destination_handle"] = OSD.FromString(region.RegionHandle.ToString()); - - string strBuffer = ""; - byte[] buffer = new byte[1]; - - try - { - strBuffer = OSDParser.SerializeJsonString(args); - UTF8Encoding str = new UTF8Encoding(); - buffer = str.GetBytes(strBuffer); - } - catch (Exception e) - { - m_log.WarnFormat( - "[NEIGHBOUR SERVICE CONNCTOR]: Exception thrown on serialization of HelloNeighbour from {0} to {1}. Exception {2}{3}", - thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); - - return false; - } - - Stream os = null; - try - { // send the Post - helloNeighbourRequest.ContentLength = buffer.Length; //Count bytes to send - os = helloNeighbourRequest.GetRequestStream(); - os.Write(buffer, 0, strBuffer.Length); //Send it - //m_log.InfoFormat("[REST COMMS]: Posted HelloNeighbour request to remote sim {0}", uri); - } - catch (Exception e) - { - m_log.WarnFormat( - "[NEIGHBOUR SERVICE CONNCTOR]: Unable to send HelloNeighbour from {0} to {1}. Exception {2}{3}", - thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); - - return false; - } - finally - { - if (os != null) - os.Close(); - } - - // Let's wait for the response - //m_log.Info("[REST COMMS]: Waiting for a reply after DoHelloNeighbourCall"); - - StreamReader sr = null; - try - { - WebResponse webResponse = helloNeighbourRequest.GetResponse(); - if (webResponse == null) - { - m_log.DebugFormat( - "[REST COMMS]: Null reply on DoHelloNeighbourCall post from {0} to {1}", - thisRegion.RegionName, region.RegionName); - } - - sr = new StreamReader(webResponse.GetResponseStream()); - //reply = sr.ReadToEnd().Trim(); - sr.ReadToEnd().Trim(); - //m_log.InfoFormat("[REST COMMS]: DoHelloNeighbourCall reply was {0} ", reply); - - } - catch (Exception e) - { - m_log.WarnFormat( - "[NEIGHBOUR SERVICE CONNCTOR]: Exception on reply of DoHelloNeighbourCall from {0} back to {1}. Exception {2}{3}", - region.RegionName, thisRegion.RegionName, e.Message, e.StackTrace); - - return false; - } - finally - { - if (sr != null) - sr.Close(); - } - - return true; - } - } -} \ No newline at end of file diff --git a/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs b/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs new file mode 100644 index 0000000..888b072 --- /dev/null +++ b/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs @@ -0,0 +1,206 @@ +/* + * 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 log4net; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Reflection; +using System.Text; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Services.Interfaces; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +namespace OpenSim.Services.Connectors +{ + public class NeighbourServicesConnector : INeighbourService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + protected IGridService m_GridService = null; + + public NeighbourServicesConnector() + { + } + + public NeighbourServicesConnector(IGridService gridServices) + { + Initialise(gridServices); + } + + public virtual void Initialise(IGridService gridServices) + { + m_GridService = gridServices; + } + + public virtual GridRegion HelloNeighbour(ulong regionHandle, RegionInfo thisRegion) + { + uint x = 0, y = 0; + Utils.LongToUInts(regionHandle, out x, out y); + GridRegion regInfo = m_GridService.GetRegionByPosition(thisRegion.ScopeID, (int)x, (int)y); + if ((regInfo != null) && + // Don't remote-call this instance; that's a startup hickup + !((regInfo.ExternalHostName == thisRegion.ExternalHostName) && (regInfo.HttpPort == thisRegion.HttpPort))) + { + if (!DoHelloNeighbourCall(regInfo, thisRegion)) + return null; + } + else + return null; + + return regInfo; + } + + public bool DoHelloNeighbourCall(GridRegion region, RegionInfo thisRegion) + { + string uri = region.ServerURI + "region/" + thisRegion.RegionID + "/"; +// m_log.Debug(" >>> DoHelloNeighbourCall <<< " + uri); + + WebRequest helloNeighbourRequest; + + try + { + helloNeighbourRequest = WebRequest.Create(uri); + } + catch (Exception e) + { + m_log.WarnFormat( + "[NEIGHBOUR SERVICE CONNCTOR]: Unable to parse uri {0} to send HelloNeighbour from {1} to {2}. Exception {3}{4}", + uri, thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); + + return false; + } + + helloNeighbourRequest.Method = "POST"; + helloNeighbourRequest.ContentType = "application/json"; + helloNeighbourRequest.Timeout = 10000; + + // Fill it in + OSDMap args = null; + try + { + args = thisRegion.PackRegionInfoData(); + } + catch (Exception e) + { + m_log.WarnFormat( + "[NEIGHBOUR SERVICE CONNCTOR]: PackRegionInfoData failed for HelloNeighbour from {0} to {1}. Exception {2}{3}", + thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); + + return false; + } + + // Add the regionhandle of the destination region + args["destination_handle"] = OSD.FromString(region.RegionHandle.ToString()); + + string strBuffer = ""; + byte[] buffer = new byte[1]; + + try + { + strBuffer = OSDParser.SerializeJsonString(args); + UTF8Encoding str = new UTF8Encoding(); + buffer = str.GetBytes(strBuffer); + } + catch (Exception e) + { + m_log.WarnFormat( + "[NEIGHBOUR SERVICE CONNCTOR]: Exception thrown on serialization of HelloNeighbour from {0} to {1}. Exception {2}{3}", + thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); + + return false; + } + + Stream os = null; + try + { // send the Post + helloNeighbourRequest.ContentLength = buffer.Length; //Count bytes to send + os = helloNeighbourRequest.GetRequestStream(); + os.Write(buffer, 0, strBuffer.Length); //Send it + //m_log.InfoFormat("[REST COMMS]: Posted HelloNeighbour request to remote sim {0}", uri); + } + catch (Exception e) + { + m_log.WarnFormat( + "[NEIGHBOUR SERVICE CONNCTOR]: Unable to send HelloNeighbour from {0} to {1}. Exception {2}{3}", + thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); + + return false; + } + finally + { + if (os != null) + os.Close(); + } + + // Let's wait for the response + //m_log.Info("[REST COMMS]: Waiting for a reply after DoHelloNeighbourCall"); + + StreamReader sr = null; + try + { + WebResponse webResponse = helloNeighbourRequest.GetResponse(); + if (webResponse == null) + { + m_log.DebugFormat( + "[REST COMMS]: Null reply on DoHelloNeighbourCall post from {0} to {1}", + thisRegion.RegionName, region.RegionName); + } + + sr = new StreamReader(webResponse.GetResponseStream()); + //reply = sr.ReadToEnd().Trim(); + sr.ReadToEnd().Trim(); + //m_log.InfoFormat("[REST COMMS]: DoHelloNeighbourCall reply was {0} ", reply); + + } + catch (Exception e) + { + m_log.WarnFormat( + "[NEIGHBOUR SERVICE CONNCTOR]: Exception on reply of DoHelloNeighbourCall from {0} back to {1}. Exception {2}{3}", + region.RegionName, thisRegion.RegionName, e.Message, e.StackTrace); + + return false; + } + finally + { + if (sr != null) + sr.Close(); + } + + return true; + } + } +} \ No newline at end of file diff --git a/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs deleted file mode 100644 index f7d8c53..0000000 --- a/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs +++ /dev/null @@ -1,378 +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 log4net; -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Services.Interfaces; -using GridRegion = OpenSim.Services.Interfaces.GridRegion; -using OpenSim.Server.Base; -using OpenMetaverse; - -namespace OpenSim.Services.Connectors -{ - public class PresenceServicesConnector : IPresenceService - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - private string m_ServerURI = String.Empty; - - public PresenceServicesConnector() - { - } - - public PresenceServicesConnector(string serverURI) - { - m_ServerURI = serverURI.TrimEnd('/'); - } - - public PresenceServicesConnector(IConfigSource source) - { - Initialise(source); - } - - public virtual void Initialise(IConfigSource source) - { - IConfig gridConfig = source.Configs["PresenceService"]; - if (gridConfig == null) - { - m_log.Error("[PRESENCE CONNECTOR]: PresenceService missing from OpenSim.ini"); - throw new Exception("Presence connector init error"); - } - - string serviceURI = gridConfig.GetString("PresenceServerURI", - String.Empty); - - if (serviceURI == String.Empty) - { - m_log.Error("[PRESENCE CONNECTOR]: No Server URI named in section PresenceService"); - throw new Exception("Presence connector init error"); - } - m_ServerURI = serviceURI; - } - - - #region IPresenceService - - public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "login"; - - sendData["UserID"] = userID; - sendData["SessionID"] = sessionID.ToString(); - sendData["SecureSessionID"] = secureSessionID.ToString(); - - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/presence"; - // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); - try - { - string reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - reqString); - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData.ContainsKey("result")) - { - if (replyData["result"].ToString().ToLower() == "success") - return true; - else - return false; - } - else - m_log.DebugFormat("[PRESENCE CONNECTOR]: LoginAgent reply data does not contain result field"); - - } - else - m_log.DebugFormat("[PRESENCE CONNECTOR]: LoginAgent received empty reply"); - } - catch (Exception e) - { - m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); - } - - return false; - - } - - public bool LogoutAgent(UUID sessionID) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "logout"; - - sendData["SessionID"] = sessionID.ToString(); - - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/presence"; - // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); - try - { - string reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - reqString); - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData.ContainsKey("result")) - { - if (replyData["result"].ToString().ToLower() == "success") - return true; - else - return false; - } - else - m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutAgent reply data does not contain result field"); - - } - else - m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutAgent received empty reply"); - } - catch (Exception e) - { - m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); - } - - return false; - } - - public bool LogoutRegionAgents(UUID regionID) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "logoutregion"; - - sendData["RegionID"] = regionID.ToString(); - - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/presence"; - // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); - try - { - string reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - reqString); - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData.ContainsKey("result")) - { - if (replyData["result"].ToString().ToLower() == "success") - return true; - else - return false; - } - else - m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutRegionAgents reply data does not contain result field"); - - } - else - m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutRegionAgents received empty reply"); - } - catch (Exception e) - { - m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); - } - - return false; - } - - public bool ReportAgent(UUID sessionID, UUID regionID) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "report"; - - sendData["SessionID"] = sessionID.ToString(); - sendData["RegionID"] = regionID.ToString(); - - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/presence"; - // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); - try - { - string reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - reqString); - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData.ContainsKey("result")) - { - if (replyData["result"].ToString().ToLower() == "success") - return true; - else - return false; - } - else - m_log.DebugFormat("[PRESENCE CONNECTOR]: ReportAgent reply data does not contain result field"); - - } - else - m_log.DebugFormat("[PRESENCE CONNECTOR]: ReportAgent received empty reply"); - } - catch (Exception e) - { - m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); - } - - return false; - } - - public PresenceInfo GetAgent(UUID sessionID) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "getagent"; - - sendData["SessionID"] = sessionID.ToString(); - - string reply = string.Empty; - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/presence"; - // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - reqString); - if (reply == null || (reply != null && reply == string.Empty)) - { - m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgent received null or empty reply"); - return null; - } - } - catch (Exception e) - { - m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); - } - - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - PresenceInfo pinfo = null; - - if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null)) - { - if (replyData["result"] is Dictionary) - { - pinfo = new PresenceInfo((Dictionary)replyData["result"]); - } - } - - return pinfo; - } - - public PresenceInfo[] GetAgents(string[] userIDs) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "getagents"; - - sendData["uuids"] = new List(userIDs); - - string reply = string.Empty; - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/presence"; - //m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - reqString); - if (reply == null || (reply != null && reply == string.Empty)) - { - m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received null or empty reply"); - return null; - } - } - catch (Exception e) - { - m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); - } - - List rinfos = new List(); - - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData != null) - { - if (replyData.ContainsKey("result") && - (replyData["result"].ToString() == "null" || replyData["result"].ToString() == "Failure")) - { - return new PresenceInfo[0]; - } - - Dictionary.ValueCollection pinfosList = replyData.Values; - //m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents returned {0} elements", pinfosList.Count); - foreach (object presence in pinfosList) - { - if (presence is Dictionary) - { - PresenceInfo pinfo = new PresenceInfo((Dictionary)presence); - rinfos.Add(pinfo); - } - else - m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received invalid response type {0}", - presence.GetType()); - } - } - else - m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received null response"); - - return rinfos.ToArray(); - } - - - #endregion - - } -} diff --git a/OpenSim/Services/Connectors/Presence/PresenceServicesConnector.cs b/OpenSim/Services/Connectors/Presence/PresenceServicesConnector.cs new file mode 100644 index 0000000..f7d8c53 --- /dev/null +++ b/OpenSim/Services/Connectors/Presence/PresenceServicesConnector.cs @@ -0,0 +1,378 @@ +/* + * 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 log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Services.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using OpenSim.Server.Base; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors +{ + public class PresenceServicesConnector : IPresenceService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + + public PresenceServicesConnector() + { + } + + public PresenceServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + + public PresenceServicesConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig gridConfig = source.Configs["PresenceService"]; + if (gridConfig == null) + { + m_log.Error("[PRESENCE CONNECTOR]: PresenceService missing from OpenSim.ini"); + throw new Exception("Presence connector init error"); + } + + string serviceURI = gridConfig.GetString("PresenceServerURI", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[PRESENCE CONNECTOR]: No Server URI named in section PresenceService"); + throw new Exception("Presence connector init error"); + } + m_ServerURI = serviceURI; + } + + + #region IPresenceService + + public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "login"; + + sendData["UserID"] = userID; + sendData["SessionID"] = sessionID.ToString(); + sendData["SecureSessionID"] = secureSessionID.ToString(); + + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/presence"; + // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + reqString); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("result")) + { + if (replyData["result"].ToString().ToLower() == "success") + return true; + else + return false; + } + else + m_log.DebugFormat("[PRESENCE CONNECTOR]: LoginAgent reply data does not contain result field"); + + } + else + m_log.DebugFormat("[PRESENCE CONNECTOR]: LoginAgent received empty reply"); + } + catch (Exception e) + { + m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); + } + + return false; + + } + + public bool LogoutAgent(UUID sessionID) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "logout"; + + sendData["SessionID"] = sessionID.ToString(); + + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/presence"; + // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + reqString); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("result")) + { + if (replyData["result"].ToString().ToLower() == "success") + return true; + else + return false; + } + else + m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutAgent reply data does not contain result field"); + + } + else + m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutAgent received empty reply"); + } + catch (Exception e) + { + m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); + } + + return false; + } + + public bool LogoutRegionAgents(UUID regionID) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "logoutregion"; + + sendData["RegionID"] = regionID.ToString(); + + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/presence"; + // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + reqString); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("result")) + { + if (replyData["result"].ToString().ToLower() == "success") + return true; + else + return false; + } + else + m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutRegionAgents reply data does not contain result field"); + + } + else + m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutRegionAgents received empty reply"); + } + catch (Exception e) + { + m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); + } + + return false; + } + + public bool ReportAgent(UUID sessionID, UUID regionID) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "report"; + + sendData["SessionID"] = sessionID.ToString(); + sendData["RegionID"] = regionID.ToString(); + + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/presence"; + // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + reqString); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("result")) + { + if (replyData["result"].ToString().ToLower() == "success") + return true; + else + return false; + } + else + m_log.DebugFormat("[PRESENCE CONNECTOR]: ReportAgent reply data does not contain result field"); + + } + else + m_log.DebugFormat("[PRESENCE CONNECTOR]: ReportAgent received empty reply"); + } + catch (Exception e) + { + m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); + } + + return false; + } + + public PresenceInfo GetAgent(UUID sessionID) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "getagent"; + + sendData["SessionID"] = sessionID.ToString(); + + string reply = string.Empty; + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/presence"; + // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + reqString); + if (reply == null || (reply != null && reply == string.Empty)) + { + m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgent received null or empty reply"); + return null; + } + } + catch (Exception e) + { + m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); + } + + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + PresenceInfo pinfo = null; + + if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null)) + { + if (replyData["result"] is Dictionary) + { + pinfo = new PresenceInfo((Dictionary)replyData["result"]); + } + } + + return pinfo; + } + + public PresenceInfo[] GetAgents(string[] userIDs) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "getagents"; + + sendData["uuids"] = new List(userIDs); + + string reply = string.Empty; + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/presence"; + //m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + reqString); + if (reply == null || (reply != null && reply == string.Empty)) + { + m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received null or empty reply"); + return null; + } + } + catch (Exception e) + { + m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); + } + + List rinfos = new List(); + + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData != null) + { + if (replyData.ContainsKey("result") && + (replyData["result"].ToString() == "null" || replyData["result"].ToString() == "Failure")) + { + return new PresenceInfo[0]; + } + + Dictionary.ValueCollection pinfosList = replyData.Values; + //m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents returned {0} elements", pinfosList.Count); + foreach (object presence in pinfosList) + { + if (presence is Dictionary) + { + PresenceInfo pinfo = new PresenceInfo((Dictionary)presence); + rinfos.Add(pinfo); + } + else + m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received invalid response type {0}", + presence.GetType()); + } + } + else + m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received null response"); + + return rinfos.ToArray(); + } + + + #endregion + + } +} diff --git a/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs deleted file mode 100644 index 6d5ce28..0000000 --- a/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs +++ /dev/null @@ -1,287 +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 log4net; -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Server.Base; -using OpenSim.Services.Interfaces; -using OpenMetaverse; - -namespace OpenSim.Services.Connectors -{ - public class UserAccountServicesConnector : IUserAccountService - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - private string m_ServerURI = String.Empty; - - public UserAccountServicesConnector() - { - } - - public UserAccountServicesConnector(string serverURI) - { - m_ServerURI = serverURI.TrimEnd('/'); - } - - public UserAccountServicesConnector(IConfigSource source) - { - Initialise(source); - } - - public virtual void Initialise(IConfigSource source) - { - IConfig assetConfig = source.Configs["UserAccountService"]; - if (assetConfig == null) - { - m_log.Error("[ACCOUNT CONNECTOR]: UserAccountService missing from OpenSim.ini"); - throw new Exception("User account connector init error"); - } - - string serviceURI = assetConfig.GetString("UserAccountServerURI", - String.Empty); - - if (serviceURI == String.Empty) - { - m_log.Error("[ACCOUNT CONNECTOR]: No Server URI named in section UserAccountService"); - throw new Exception("User account connector init error"); - } - m_ServerURI = serviceURI; - } - - public virtual UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "getaccount"; - - sendData["ScopeID"] = scopeID; - sendData["FirstName"] = firstName.ToString(); - sendData["LastName"] = lastName.ToString(); - - return SendAndGetReply(sendData); - } - - public virtual UserAccount GetUserAccount(UUID scopeID, string email) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "getaccount"; - - sendData["ScopeID"] = scopeID; - sendData["Email"] = email; - - return SendAndGetReply(sendData); - } - - public virtual UserAccount GetUserAccount(UUID scopeID, UUID userID) - { - //m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUserAccount {0}", userID); - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "getaccount"; - - sendData["ScopeID"] = scopeID; - sendData["UserID"] = userID.ToString(); - - return SendAndGetReply(sendData); - } - - public List GetUserAccounts(UUID scopeID, string query) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "getaccounts"; - - sendData["ScopeID"] = scopeID.ToString(); - sendData["query"] = query; - - string reply = string.Empty; - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/accounts"; - // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString); - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - reqString); - if (reply == null || (reply != null && reply == string.Empty)) - { - m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccounts received null or empty reply"); - return null; - } - } - catch (Exception e) - { - m_log.DebugFormat("[ACCOUNT CONNECTOR]: Exception when contacting user accounts server at {0}: {1}", uri, e.Message); - } - - List accounts = new List(); - - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData != null) - { - if (replyData.ContainsKey("result") && replyData.ContainsKey("result").ToString() == "null") - { - return accounts; - } - - Dictionary.ValueCollection accountList = replyData.Values; - //m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetAgents returned {0} elements", pinfosList.Count); - foreach (object acc in accountList) - { - if (acc is Dictionary) - { - UserAccount pinfo = new UserAccount((Dictionary)acc); - accounts.Add(pinfo); - } - else - m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccounts received invalid response type {0}", - acc.GetType()); - } - } - else - m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUserAccounts received null response"); - - return accounts; - } - - public virtual bool StoreUserAccount(UserAccount data) - { - Dictionary sendData = new Dictionary(); - //sendData["SCOPEID"] = scopeID.ToString(); - sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); - sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); - sendData["METHOD"] = "setaccount"; - - Dictionary structData = data.ToKeyValuePairs(); - - foreach (KeyValuePair kvp in structData) - { - if (kvp.Value == null) - { - m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Null value for {0}", kvp.Key); - continue; - } - sendData[kvp.Key] = kvp.Value.ToString(); - } - - return SendAndGetBoolReply(sendData); - } - - private UserAccount SendAndGetReply(Dictionary sendData) - { - string reply = string.Empty; - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/accounts"; - // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString); - try - { - reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - reqString); - if (reply == null || (reply != null && reply == string.Empty)) - { - m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccount received null or empty reply"); - return null; - } - } - catch (Exception e) - { - m_log.DebugFormat("[ACCOUNT CONNECTOR]: Exception when contacting user accounts server at {0}: {1}", uri, e.Message); - } - - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - UserAccount account = null; - - if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null)) - { - if (replyData["result"] is Dictionary) - { - account = new UserAccount((Dictionary)replyData["result"]); - } - } - - return account; - - } - - private bool SendAndGetBoolReply(Dictionary sendData) - { - string reqString = ServerUtils.BuildQueryString(sendData); - string uri = m_ServerURI + "/accounts"; - // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString); - try - { - string reply = SynchronousRestFormsRequester.MakeRequest("POST", - uri, - reqString); - if (reply != string.Empty) - { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData.ContainsKey("result")) - { - if (replyData["result"].ToString().ToLower() == "success") - return true; - else - return false; - } - else - m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Set or Create UserAccount reply data does not contain result field"); - - } - else - m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Set or Create UserAccount received empty reply"); - } - catch (Exception e) - { - m_log.DebugFormat("[ACCOUNT CONNECTOR]: Exception when contacting user accounts server at {0}: {1}", uri, e.Message); - } - - return false; - } - - } -} diff --git a/OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs b/OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs new file mode 100644 index 0000000..6d5ce28 --- /dev/null +++ b/OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs @@ -0,0 +1,287 @@ +/* + * 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 log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors +{ + public class UserAccountServicesConnector : IUserAccountService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + + public UserAccountServicesConnector() + { + } + + public UserAccountServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + + public UserAccountServicesConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig assetConfig = source.Configs["UserAccountService"]; + if (assetConfig == null) + { + m_log.Error("[ACCOUNT CONNECTOR]: UserAccountService missing from OpenSim.ini"); + throw new Exception("User account connector init error"); + } + + string serviceURI = assetConfig.GetString("UserAccountServerURI", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[ACCOUNT CONNECTOR]: No Server URI named in section UserAccountService"); + throw new Exception("User account connector init error"); + } + m_ServerURI = serviceURI; + } + + public virtual UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "getaccount"; + + sendData["ScopeID"] = scopeID; + sendData["FirstName"] = firstName.ToString(); + sendData["LastName"] = lastName.ToString(); + + return SendAndGetReply(sendData); + } + + public virtual UserAccount GetUserAccount(UUID scopeID, string email) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "getaccount"; + + sendData["ScopeID"] = scopeID; + sendData["Email"] = email; + + return SendAndGetReply(sendData); + } + + public virtual UserAccount GetUserAccount(UUID scopeID, UUID userID) + { + //m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUserAccount {0}", userID); + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "getaccount"; + + sendData["ScopeID"] = scopeID; + sendData["UserID"] = userID.ToString(); + + return SendAndGetReply(sendData); + } + + public List GetUserAccounts(UUID scopeID, string query) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "getaccounts"; + + sendData["ScopeID"] = scopeID.ToString(); + sendData["query"] = query; + + string reply = string.Empty; + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/accounts"; + // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString); + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + reqString); + if (reply == null || (reply != null && reply == string.Empty)) + { + m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccounts received null or empty reply"); + return null; + } + } + catch (Exception e) + { + m_log.DebugFormat("[ACCOUNT CONNECTOR]: Exception when contacting user accounts server at {0}: {1}", uri, e.Message); + } + + List accounts = new List(); + + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData != null) + { + if (replyData.ContainsKey("result") && replyData.ContainsKey("result").ToString() == "null") + { + return accounts; + } + + Dictionary.ValueCollection accountList = replyData.Values; + //m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetAgents returned {0} elements", pinfosList.Count); + foreach (object acc in accountList) + { + if (acc is Dictionary) + { + UserAccount pinfo = new UserAccount((Dictionary)acc); + accounts.Add(pinfo); + } + else + m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccounts received invalid response type {0}", + acc.GetType()); + } + } + else + m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUserAccounts received null response"); + + return accounts; + } + + public virtual bool StoreUserAccount(UserAccount data) + { + Dictionary sendData = new Dictionary(); + //sendData["SCOPEID"] = scopeID.ToString(); + sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); + sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); + sendData["METHOD"] = "setaccount"; + + Dictionary structData = data.ToKeyValuePairs(); + + foreach (KeyValuePair kvp in structData) + { + if (kvp.Value == null) + { + m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Null value for {0}", kvp.Key); + continue; + } + sendData[kvp.Key] = kvp.Value.ToString(); + } + + return SendAndGetBoolReply(sendData); + } + + private UserAccount SendAndGetReply(Dictionary sendData) + { + string reply = string.Empty; + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/accounts"; + // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString); + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + reqString); + if (reply == null || (reply != null && reply == string.Empty)) + { + m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccount received null or empty reply"); + return null; + } + } + catch (Exception e) + { + m_log.DebugFormat("[ACCOUNT CONNECTOR]: Exception when contacting user accounts server at {0}: {1}", uri, e.Message); + } + + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + UserAccount account = null; + + if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null)) + { + if (replyData["result"] is Dictionary) + { + account = new UserAccount((Dictionary)replyData["result"]); + } + } + + return account; + + } + + private bool SendAndGetBoolReply(Dictionary sendData) + { + string reqString = ServerUtils.BuildQueryString(sendData); + string uri = m_ServerURI + "/accounts"; + // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString); + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + reqString); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("result")) + { + if (replyData["result"].ToString().ToLower() == "success") + return true; + else + return false; + } + else + m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Set or Create UserAccount reply data does not contain result field"); + + } + else + m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Set or Create UserAccount received empty reply"); + } + catch (Exception e) + { + m_log.DebugFormat("[ACCOUNT CONNECTOR]: Exception when contacting user accounts server at {0}: {1}", uri, e.Message); + } + + return false; + } + + } +} -- cgit v1.1 From de44734fe9a0b31cd8cb78c0f58e61a35fe2a259 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Thu, 10 May 2012 09:08:40 -0700 Subject: Saving estate state is really slow (relatively) and it gets completely rewritten every time a region starts up. This makes the data write only when the data was not already read from the database. There is a still a major race condition whenever two regions share the same estate data, but at least it won't be triggered on startup. --- OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs | 5 +++-- OpenSim/Region/Application/OpenSim.cs | 5 +++-- OpenSim/Region/Application/OpenSimBase.cs | 12 +++++++----- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs index 45b8d6f..0065702 100644 --- a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs +++ b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs @@ -122,9 +122,10 @@ namespace OpenSim.ApplicationPlugins.LoadRegions Thread.CurrentThread.ManagedThreadId.ToString() + ")"); - m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]); + bool changed = m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]); m_openSim.CreateRegion(regionsToLoad[i], true, out scene); - regionsToLoad[i].EstateSettings.Save(); + if (changed) + regionsToLoad[i].EstateSettings.Save(); if (scene != null) { diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 4ec64ee..6796f2b 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -618,10 +618,11 @@ namespace OpenSim return; } - PopulateRegionEstateInfo(regInfo); + bool changed = PopulateRegionEstateInfo(regInfo); IScene scene; CreateRegion(regInfo, true, out scene); - regInfo.EstateSettings.Save(); + if (changed) + regInfo.EstateSettings.Save(); } /// diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 79259d8..045e8d2 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -977,13 +977,13 @@ namespace OpenSim /// Load the estate information for the provided RegionInfo object. /// /// - public void PopulateRegionEstateInfo(RegionInfo regInfo) + public bool PopulateRegionEstateInfo(RegionInfo regInfo) { if (EstateDataService != null) regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, false); if (regInfo.EstateSettings.EstateID != 0) - return; + return false; // estate info in the database did not change m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName); @@ -1018,7 +1018,7 @@ namespace OpenSim } if (defaultEstateJoined) - return; + return true; // need to update the database else m_log.ErrorFormat( "[OPENSIM BASE]: Joining default estate {0} failed", defaultEstateName); @@ -1080,8 +1080,10 @@ namespace OpenSim MainConsole.Instance.Output("Joining the estate failed. Please try again."); } } - } - } + } + + return true; // need to update the database + } } public class OpenSimConfigSource -- cgit v1.1 From f374b63ac8a2f75b59b2c0442ab8000f76466f70 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Thu, 10 May 2012 14:42:46 -0700 Subject: Add even for terrain tainting and synchronize terrain module with physics scene before physics simulation step rather than after --- .../CoreModules/World/Terrain/TerrainModule.cs | 1 + OpenSim/Region/Framework/Scenes/EventManager.cs | 25 ++++++++++++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 15 +++++++------ 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 8535a5a..2eac0fa 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -722,6 +722,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain } if (shouldTaint) { + m_scene.EventManager.TriggerTerrainTainted(); m_tainted = true; } } diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index ace8313..f97b0a9 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -53,6 +53,10 @@ namespace OpenSim.Region.Framework.Scenes public event ClientMovement OnClientMovement; + public delegate void OnTerrainTaintedDelegate(); + + public event OnTerrainTaintedDelegate OnTerrainTainted; + public delegate void OnTerrainTickDelegate(); public event OnTerrainTickDelegate OnTerrainTick; @@ -914,6 +918,27 @@ namespace OpenSim.Region.Framework.Scenes } } + public void TriggerTerrainTainted() + { + OnTerrainTaintedDelegate handlerTerrainTainted = OnTerrainTainted; + if (handlerTerrainTainted != null) + { + foreach (OnTerrainTickDelegate d in handlerTerrainTainted.GetInvocationList()) + { + try + { + d(); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[EVENT MANAGER]: Delegate for TriggerTerrainTainted failed - continuing. {0} {1}", + e.Message, e.StackTrace); + } + } + } + } + public void TriggerParcelPrimCountAdd(SceneObjectGroup obj) { OnParcelPrimCountAddDelegate handlerParcelPrimCountAdd = OnParcelPrimCountAdd; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 4d0aa6f..3d2213a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1353,6 +1353,14 @@ namespace OpenSim.Region.Framework.Scenes try { + // Apply taints in terrain module to terrain in physics scene + if (Frame % m_update_terrain == 0) + { + terMS = Util.EnvironmentTickCount(); + UpdateTerrain(); + terrainMS = Util.EnvironmentTickCountSubtract(terMS); + } + tmpPhysicsMS2 = Util.EnvironmentTickCount(); if ((Frame % m_update_physics == 0) && m_physics_enabled) m_sceneGraph.UpdatePreparePhysics(); @@ -1417,13 +1425,6 @@ namespace OpenSim.Region.Framework.Scenes backupMS = Util.EnvironmentTickCountSubtract(backMS); } - if (Frame % m_update_terrain == 0) - { - terMS = Util.EnvironmentTickCount(); - UpdateTerrain(); - terrainMS = Util.EnvironmentTickCountSubtract(terMS); - } - //if (Frame % m_update_land == 0) //{ // int ldMS = Util.EnvironmentTickCount(); -- cgit v1.1 From bce3e7cb06611db887ee50c793d72674ad326ba7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 10 May 2012 22:48:03 +0100 Subject: Add "attachments" show console command that will show the server's record of which attachments an in-scene avatar has. For debugging purposes. --- .../Avatar/Attachments/AttachmentsCommandModule.cs | 177 +++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs new file mode 100644 index 0000000..ce23613 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs @@ -0,0 +1,177 @@ +/* + * 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.Linq; +using System.Reflection; +using System.Text; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Statistics; +using OpenSim.Region.ClientStack.LindenUDP; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.OptionalModules.Avatar.Attachments +{ + /// + /// A module that just holds commands for inspecting avatar appearance. + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AttachmentsCommandModule")] + public class AttachmentsCommandModule : ISharedRegionModule + { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private List m_scenes = new List(); +// private IAvatarFactoryModule m_avatarFactory; + + public string Name { get { return "Attachments Command Module"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { +// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: INITIALIZED MODULE"); + } + + public void PostInitialise() + { +// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: POST INITIALIZED MODULE"); + } + + public void Close() + { +// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: CLOSED MODULE"); + } + + public void AddRegion(Scene scene) + { +// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); + } + + public void RemoveRegion(Scene scene) + { +// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); + + lock (m_scenes) + m_scenes.Remove(scene); + } + + public void RegionLoaded(Scene scene) + { +// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); + + lock (m_scenes) + m_scenes.Add(scene); + + scene.AddCommand( + "Users", this, "attachments show", + "attachments show [ ]", + "Show attachment information for avatars in this simulator.", + HandleShowAttachmentsCommand); + } + + protected void HandleShowAttachmentsCommand(string module, string[] cmd) + { + if (cmd.Length != 2 && cmd.Length < 4) + { + MainConsole.Instance.OutputFormat("Usage: attachments show [ ]"); + return; + } + + bool targetNameSupplied = false; + string optionalTargetFirstName = null; + string optionalTargetLastName = null; + + if (cmd.Length >= 4) + { + targetNameSupplied = true; + optionalTargetFirstName = cmd[2]; + optionalTargetLastName = cmd[3]; + } + + StringBuilder sb = new StringBuilder(); + + lock (m_scenes) + { + foreach (Scene scene in m_scenes) + { + if (targetNameSupplied) + { + ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName); + if (sp != null && !sp.IsChildAgent) + GetAttachmentsReport(sp, sb); + } + else + { + scene.ForEachRootScenePresence(sp => GetAttachmentsReport(sp, sb)); + } + } + } + + MainConsole.Instance.Output(sb.ToString()); + } + + private void GetAttachmentsReport(ScenePresence sp, StringBuilder sb) + { + sb.AppendFormat("Attachments for {0}\n", sp.Name); + + sb.AppendFormat( + " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", + "Attachment Name", "Local ID", "Item ID", "Attach Point", "Position"); + + List attachmentObjects = sp.GetAttachments(); + foreach (SceneObjectGroup attachmentObject in attachmentObjects) + { +// InventoryItemBase attachmentItem +// = m_scenes[0].InventoryService.GetItem(new InventoryItemBase(attachmentObject.FromItemID)); + +// if (attachmentItem == null) +// { +// sb.AppendFormat( +// "WARNING: Couldn't find attachment for item {0} at point {1}\n", +// attachmentData.ItemID, (AttachmentPoint)attachmentData.AttachPoint); +// continue; +// } +// else +// { + sb.AppendFormat( + " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", + attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, + (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); +// } + } + + sb.Append("\n"); + } + } +} \ No newline at end of file -- cgit v1.1 From 903cff9264ce405d00eab2739fcfb461749b4772 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 10 May 2012 23:47:39 +0100 Subject: Add ConsoleTable framework class for future uniform formatting of console output tables. Still subject to change - if you use this be prepared to change your output code if/when the methods change. Make new "attachments show" command use this. --- OpenSim/Framework/Console/ConsoleTable.cs | 139 +++++++++++++++++++++ .../Avatar/Attachments/AttachmentsCommandModule.cs | 34 +++-- 2 files changed, 165 insertions(+), 8 deletions(-) create mode 100644 OpenSim/Framework/Console/ConsoleTable.cs diff --git a/OpenSim/Framework/Console/ConsoleTable.cs b/OpenSim/Framework/Console/ConsoleTable.cs new file mode 100644 index 0000000..be3025b --- /dev/null +++ b/OpenSim/Framework/Console/ConsoleTable.cs @@ -0,0 +1,139 @@ +/* + * 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.Linq; +using System.Text; + +namespace OpenSim.Framework.Console +{ + /// + /// Used to generated a formatted table for the console. + /// + /// + /// Currently subject to change. If you use this, be prepared to change your code when this class changes. + /// + public class ConsoleTable + { + /// + /// Default number of spaces between table columns. + /// + public const int DefaultTableSpacing = 2; + + /// + /// Table columns. + /// + public List Columns { get; private set; } + + /// + /// Table rows + /// + public List Rows { get; private set; } + + /// + /// Number of spaces to indent the table. + /// + public int Indent { get; set; } + + /// + /// Spacing between table columns + /// + public int TableSpacing { get; set; } + + public ConsoleTable() + { + TableSpacing = DefaultTableSpacing; + Columns = new List(); + Rows = new List(); + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + AddToStringBuilder(sb); + return sb.ToString(); + } + + public void AddToStringBuilder(StringBuilder sb) + { + string formatString = GetFormatString(); +// System.Console.WriteLine("FORMAT STRING [{0}]", formatString); + + // columns + sb.AppendFormat(formatString, Columns.ConvertAll(c => c.Header).ToArray()); + + // rows + foreach (ConsoleTableRow row in Rows) + sb.AppendFormat(formatString, row.Cells.ToArray()); + } + + /// + /// Gets the format string for the table. + /// + private string GetFormatString() + { + StringBuilder formatSb = new StringBuilder(); + + formatSb.Append(' ', Indent); + + for (int i = 0; i < Columns.Count; i++) + { + formatSb.Append(' ', TableSpacing); + + // Can only do left formatting for now + formatSb.AppendFormat("{{{0},-{1}}}", i, Columns[i].Width); + } + + formatSb.Append('\n'); + + return formatSb.ToString(); + } + } + + public struct ConsoleTableColumn + { + public string Header { get; set; } + public int Width { get; set; } + + public ConsoleTableColumn(string header, int width) : this() + { + Header = header; + Width = width; + } + } + + public struct ConsoleTableRow + { + public List Cells { get; private set; } + + public ConsoleTableRow(List cells) : this() + { + Cells = cells; + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs index ce23613..a95514c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs @@ -53,7 +53,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments private List m_scenes = new List(); // private IAvatarFactoryModule m_avatarFactory; - + public string Name { get { return "Attachments Command Module"; } } public Type ReplaceableInterface { get { return null; } } @@ -145,9 +145,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments { sb.AppendFormat("Attachments for {0}\n", sp.Name); - sb.AppendFormat( - " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", - "Attachment Name", "Local ID", "Item ID", "Attach Point", "Position"); + ConsoleTable ct = new ConsoleTable() { Indent = 2 }; + ct.Columns.Add(new ConsoleTableColumn("Attachment Name", 36)); + ct.Columns.Add(new ConsoleTableColumn("Local ID", 10)); + ct.Columns.Add(new ConsoleTableColumn("Item ID", 36)); + ct.Columns.Add(new ConsoleTableColumn("Attach Point", 14)); + ct.Columns.Add(new ConsoleTableColumn("Position", 15)); + +// sb.AppendFormat( +// " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", +// "Attachment Name", "Local ID", "Item ID", "Attach Point", "Position"); List attachmentObjects = sp.GetAttachments(); foreach (SceneObjectGroup attachmentObject in attachmentObjects) @@ -164,13 +171,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments // } // else // { - sb.AppendFormat( - " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", - attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, - (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); +// sb.AppendFormat( +// " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", +// attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, +// (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); + ct.Rows.Add( + new ConsoleTableRow( + new List() + { + attachmentObject.Name, + attachmentObject.LocalId.ToString(), + attachmentObject.FromItemID.ToString(), + ((AttachmentPoint)attachmentObject.AttachmentPoint).ToString(), + attachmentObject.RootPart.AttachedPos.ToString() + })); // } } + ct.AddToStringBuilder(sb); sb.Append("\n"); } } -- cgit v1.1 From ab4e6a02a52bfd473ea3c2050774103ec8eb3934 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 11 May 2012 00:37:20 +0100 Subject: If a bot is not connected, show region name "(none)" instead of throwing an exception in the "show bots" command of pCampbot --- OpenSim/Tools/pCampBot/BotManager.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 0f501b7..fd32a6a 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -302,9 +302,11 @@ namespace pCampBot { foreach (Bot pb in m_lBot) { + Simulator currentSim = pb.Client.Network.CurrentSim; + MainConsole.Instance.OutputFormat( outputFormat, - pb.Name, pb.Client.Network.CurrentSim.Name, pb.IsConnected ? "Connected" : "Disconnected"); + pb.Name, currentSim != null ? currentSim.Name : "(none)", pb.IsConnected ? "Connected" : "Disconnected"); } } } -- cgit v1.1 From dc39ec82fa8343657ad9b45a7d9cfeb27bf26e79 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 11 May 2012 00:53:21 +0100 Subject: Change bot.IsConnected to be ConnectionState with Disconnected, Connecting, Connnected and Disconnecting states --- OpenSim/Tools/pCampBot/Bot.cs | 23 ++++++++++++++++++++--- OpenSim/Tools/pCampBot/BotManager.cs | 4 ++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index da090dd..2b4a171 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs @@ -43,6 +43,14 @@ using Timer = System.Timers.Timer; namespace pCampBot { + public enum ConnectionState + { + Disconnected, + Connecting, + Connected, + Disconnecting + } + public class Bot { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -86,7 +94,7 @@ namespace pCampBot /// /// Is this bot connected to the grid? /// - public bool IsConnected { get; private set; } + public ConnectionState ConnectionState { get; private set; } public string FirstName { get; private set; } public string LastName { get; private set; } @@ -130,6 +138,8 @@ namespace pCampBot BotManager bm, List behaviours, string firstName, string lastName, string password, string loginUri) { + ConnectionState = ConnectionState.Disconnected; + behaviours.ForEach(b => b.Initialize(this)); Client = new GridClient(); @@ -178,6 +188,8 @@ namespace pCampBot /// public void shutdown() { + ConnectionState = ConnectionState.Disconnecting; + if (m_actionThread != null) m_actionThread.Abort(); @@ -209,9 +221,11 @@ namespace pCampBot Client.Network.Disconnected += this.Network_OnDisconnected; Client.Objects.ObjectUpdate += Objects_NewPrim; + ConnectionState = ConnectionState.Connecting; + if (Client.Network.Login(FirstName, LastName, Password, "pCampBot", "Your name")) { - IsConnected = true; + ConnectionState = ConnectionState.Connected; Thread.Sleep(Random.Next(1000, 10000)); m_actionThread = new Thread(Action); @@ -241,6 +255,8 @@ namespace pCampBot } else { + ConnectionState = ConnectionState.Disconnected; + m_log.ErrorFormat( "{0} {1} cannot login: {2}", FirstName, LastName, Client.Network.LoginMessage); @@ -439,6 +455,8 @@ namespace pCampBot public void Network_OnDisconnected(object sender, DisconnectedEventArgs args) { + ConnectionState = ConnectionState.Disconnected; + m_log.DebugFormat( "[BOT]: Bot {0} disconnected reason {1}, message {2}", Name, args.Reason, args.Message); @@ -456,7 +474,6 @@ namespace pCampBot && OnDisconnected != null) // if (OnDisconnected != null) { - IsConnected = false; OnDisconnected(this, EventType.DISCONNECTED); } } diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index fd32a6a..d4bbc2a 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -242,7 +242,7 @@ namespace pCampBot lock (m_lBot) { - if (m_lBot.TrueForAll(b => !b.IsConnected)) + if (m_lBot.TrueForAll(b => b.ConnectionState == ConnectionState.Disconnected)) Environment.Exit(0); break; @@ -306,7 +306,7 @@ namespace pCampBot MainConsole.Instance.OutputFormat( outputFormat, - pb.Name, currentSim != null ? currentSim.Name : "(none)", pb.IsConnected ? "Connected" : "Disconnected"); + pb.Name, currentSim != null ? currentSim.Name : "(none)", pb.ConnectionState); } } } -- cgit v1.1 From 93b615c51df3dec8276aead52141534a7ed32ff9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 11 May 2012 01:37:03 +0100 Subject: Do each bot shutdown on its own threads to prevent one slow shutdown holding up all the rest. This does increase the aggressiveness of shutdown Also prevents the bot list being locked for a long period, which was preventing commands such as "show bots" from working during shutdown --- OpenSim/Tools/pCampBot/BotManager.cs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index d4bbc2a..d06c55b 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -251,13 +251,21 @@ namespace pCampBot } /// - /// Shutting down all bots + /// Shut down all bots /// + /// + /// We launch each shutdown on its own thread so that a slow shutting down bot doesn't hold up all the others. + /// public void doBotShutdown() { lock (m_lBot) - foreach (Bot pb in m_lBot) - pb.shutdown(); + { + foreach (Bot bot in m_lBot) + { + Bot thisBot = bot; + Util.FireAndForget(o => thisBot.shutdown()); + } + } } /// @@ -271,11 +279,8 @@ namespace pCampBot private void HandleShutdown(string module, string[] cmd) { - Util.FireAndForget(o => - { - m_log.Warn("[BOTMANAGER]: Shutting down bots"); - doBotShutdown(); - }); + m_log.Info("[BOTMANAGER]: Shutting down bots"); + doBotShutdown(); } private void HandleShowRegions(string module, string[] cmd) -- cgit v1.1 From 0ddf3c5289f32fc5ed3283d493f305286058e48c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 11 May 2012 01:56:00 +0100 Subject: Do bot startup on another thread so console is responsive during this process --- OpenSim/Tools/pCampBot/BotManager.cs | 1 + OpenSim/Tools/pCampBot/pCampBot.cs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index d06c55b..6d4bdb1 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -222,6 +222,7 @@ namespace pCampBot Thread pbThread = new Thread(pb.startup); pbThread.Name = pb.Name; pbThread.IsBackground = true; + pbThread.Start(); } diff --git a/OpenSim/Tools/pCampBot/pCampBot.cs b/OpenSim/Tools/pCampBot/pCampBot.cs index ec5ad04..52e7501 100644 --- a/OpenSim/Tools/pCampBot/pCampBot.cs +++ b/OpenSim/Tools/pCampBot/pCampBot.cs @@ -27,6 +27,7 @@ using System; using System.Reflection; +using System.Threading; using log4net; using Nini.Config; using OpenSim.Framework; @@ -67,7 +68,9 @@ namespace pCampBot BotManager bm = new BotManager(); //startup specified number of bots. 1 is the default - bm.dobotStartup(botcount, config); + Thread startBotThread = new Thread(o => bm.dobotStartup(botcount, config)); + startBotThread.Name = "Initial start bots thread"; + startBotThread.Start(); while (true) { -- cgit v1.1 From 9c392f6a6894d532917a3b4b44720fa1e6e30be7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 11 May 2012 02:05:32 +0100 Subject: Stagger multiple bot logins by 5 seconds to make this part of the test more 'realistic' TODO: Need to make this value configurable by a command line parameter to pCampbot --- OpenSim/Tools/pCampBot/BotManager.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 6d4bdb1..b9eabbf 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -49,6 +49,14 @@ namespace pCampBot { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public const int DefaultLoginDelay = 5000; + + /// + /// Delay between logins of multiple bots. + /// + /// TODO: This value needs to be configurable by a command line argument. + public int LoginDelay { get; set; } + /// /// Command console /// @@ -84,6 +92,8 @@ namespace pCampBot /// public BotManager() { + LoginDelay = DefaultLoginDelay; + Rng = new Random(Environment.TickCount); AssetsReceived = new Dictionary(); RegionsKnown = new Dictionary(); @@ -224,6 +234,9 @@ namespace pCampBot pbThread.IsBackground = true; pbThread.Start(); + + // Stagger logins + Thread.Sleep(LoginDelay); } /// -- cgit v1.1 From f231ac39de7348965b5c4c04d8b29a885501c90d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 11 May 2012 02:23:18 +0100 Subject: Increase minimum period between bot actions to 3 seconds, so that teleport doesn't fall under the minimum 2 second limits that clients take to process it --- OpenSim/Tools/pCampBot/Bot.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index 2b4a171..95dba9f 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs @@ -167,10 +167,10 @@ namespace pCampBot Behaviours.ForEach( b => { + Thread.Sleep(Random.Next(3000, 10000)); + // m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType()); b.Action(); - - Thread.Sleep(Random.Next(1000, 10000)); } ); } -- cgit v1.1 From 480216f50f40bdb9709f9c6eec189a2ca027f395 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 11 May 2012 02:38:29 +0100 Subject: Print out more information on connecting bots --- OpenSim/Tools/pCampBot/Bot.cs | 2 +- OpenSim/Tools/pCampBot/BotManager.cs | 26 ++++++++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index 95dba9f..b6cd287 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs @@ -168,7 +168,7 @@ namespace pCampBot b => { Thread.Sleep(Random.Next(3000, 10000)); - + // m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType()); b.Action(); } diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index b9eabbf..d615b3f 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -161,28 +161,34 @@ namespace pCampBot Array.ForEach( cs.GetString("behaviours", "p").Split(new char[] { ',' }), b => behaviourSwitches.Add(b)); + MainConsole.Instance.OutputFormat( + "[BOT MANAGER]: Starting {0} bots connecting to {1}, named {2} {3}_", + botcount, + loginUri, + firstName, + lastNameStem); + + MainConsole.Instance.OutputFormat("[BOT MANAGER]: Delay between logins is {0}ms", LoginDelay); + for (int i = 0; i < botcount; i++) { string lastName = string.Format("{0}_{1}", lastNameStem, i); + // We must give each bot its own list of instantiated behaviours since they store state. List behaviours = new List(); - + // Hard-coded for now if (behaviourSwitches.Contains("p")) behaviours.Add(new PhysicsBehaviour()); - + if (behaviourSwitches.Contains("g")) behaviours.Add(new GrabbingBehaviour()); - + if (behaviourSwitches.Contains("t")) behaviours.Add(new TeleportBehaviour()); - + if (behaviourSwitches.Contains("c")) behaviours.Add(new CrossBehaviour()); - - MainConsole.Instance.OutputFormat( - "[BOT MANAGER]: Bot {0} {1} configured for behaviours {2}", - firstName, lastName, string.Join(",", behaviours.ConvertAll(b => b.Name).ToArray())); StartBot(this, behaviours, firstName, lastName, password, loginUri); } @@ -221,6 +227,10 @@ namespace pCampBot BotManager bm, List behaviours, string firstName, string lastName, string password, string loginUri) { + MainConsole.Instance.OutputFormat( + "[BOT MANAGER]: Starting bot {0} {1}, behaviours are {2}", + firstName, lastName, string.Join(",", behaviours.ConvertAll(b => b.Name).ToArray())); + Bot pb = new Bot(bm, behaviours, firstName, lastName, password, loginUri); pb.OnConnected += handlebotEvent; -- cgit v1.1 From b0b7b45b943dd94546bcfcf5d3bb871cfe35b507 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 3 May 2012 19:38:35 +0300 Subject: Save the Telehub and its Spawn Points in the OAR Signed-off-by: BlueWall --- OpenSim/Framework/RegionSettings.cs | 29 ++++++++++++++++- .../External/RegionSettingsSerializer.cs | 37 ++++++++++++++++++++-- .../Tests/RegionSettingsSerializerTests.cs | 8 +++++ .../World/Archiver/ArchiveReadRequest.cs | 25 ++++++++++++++- .../Archiver/ArchiveWriteRequestPreparation.cs | 2 +- .../World/Archiver/Tests/ArchiverTests.cs | 4 +++ 6 files changed, 100 insertions(+), 5 deletions(-) diff --git a/OpenSim/Framework/RegionSettings.cs b/OpenSim/Framework/RegionSettings.cs index 4ce3392..011a97a 100644 --- a/OpenSim/Framework/RegionSettings.cs +++ b/OpenSim/Framework/RegionSettings.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.IO; using OpenMetaverse; +using System.Runtime.Serialization; namespace OpenSim.Framework { @@ -71,6 +72,32 @@ namespace OpenSim.Framework return pos + offset; } + + /// + /// Returns a string representation of this SpawnPoint. + /// + /// + public override string ToString() + { + return string.Format("{0},{1},{2}", Yaw, Pitch, Distance); + } + + /// + /// Generate a SpawnPoint from a string + /// + /// + public static SpawnPoint Parse(string str) + { + string[] parts = str.Split(','); + if (parts.Length != 3) + throw new ArgumentException("Invalid string: " + str); + + SpawnPoint sp = new SpawnPoint(); + sp.Yaw = float.Parse(parts[0]); + sp.Pitch = float.Parse(parts[1]); + sp.Distance = float.Parse(parts[2]); + return sp; + } } public class RegionSettings @@ -456,7 +483,7 @@ namespace OpenSim.Framework } // Connected Telehub object - private UUID m_TelehubObject; + private UUID m_TelehubObject = UUID.Zero; public UUID TelehubObject { get diff --git a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs index 931898c..f18435d 100644 --- a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs +++ b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs @@ -30,6 +30,8 @@ using System.Text; using System.Xml; using OpenMetaverse; using OpenSim.Framework; +using log4net; +using System.Reflection; namespace OpenSim.Framework.Serialization.External { @@ -187,7 +189,29 @@ namespace OpenSim.Framework.Serialization.External break; } } - + + xtr.ReadEndElement(); + + if (xtr.IsStartElement("Telehub")) + { + xtr.ReadStartElement("Telehub"); + + while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement) + { + switch (xtr.Name) + { + case "TelehubObject": + settings.TelehubObject = UUID.Parse(xtr.ReadElementContentAsString()); + break; + case "SpawnPoint": + string str = xtr.ReadElementContentAsString(); + SpawnPoint sp = SpawnPoint.Parse(str); + settings.AddSpawnPoint(sp); + break; + } + } + } + xtr.Close(); sr.Close(); @@ -243,7 +267,16 @@ namespace OpenSim.Framework.Serialization.External xtw.WriteElementString("SunPosition", settings.SunPosition.ToString()); // Note: 'SunVector' isn't saved because this value is owned by the Sun Module, which // calculates it automatically according to the date and other factors. - xtw.WriteEndElement(); + xtw.WriteEndElement(); + + xtw.WriteStartElement("Telehub"); + if (settings.TelehubObject != UUID.Zero) + { + xtw.WriteElementString("TelehubObject", settings.TelehubObject.ToString()); + foreach (SpawnPoint sp in settings.SpawnPoints()) + xtw.WriteElementString("SpawnPoint", sp.ToString()); + } + xtw.WriteEndElement(); xtw.WriteEndElement(); diff --git a/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs b/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs index a61e4af..09b6f6d 100644 --- a/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs +++ b/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs @@ -78,6 +78,10 @@ namespace OpenSim.Framework.Serialization.Tests true 12 + + 00000000-0000-0000-0000-111111111111 + 1,-2,0.33 + "; private RegionSettings m_rs; @@ -116,6 +120,8 @@ namespace OpenSim.Framework.Serialization.Tests m_rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080"); m_rs.UseEstateSun = true; m_rs.WaterHeight = 23; + m_rs.TelehubObject = UUID.Parse("00000000-0000-0000-0000-111111111111"); + m_rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33")); } [Test] @@ -129,6 +135,8 @@ namespace OpenSim.Framework.Serialization.Tests Assert.That(deserRs.TerrainTexture2, Is.EqualTo(m_rs.TerrainTexture2)); Assert.That(deserRs.DisablePhysics, Is.EqualTo(m_rs.DisablePhysics)); Assert.That(deserRs.TerrainLowerLimit, Is.EqualTo(m_rs.TerrainLowerLimit)); + Assert.That(deserRs.TelehubObject, Is.EqualTo(m_rs.TelehubObject)); + Assert.That(deserRs.SpawnPoints()[0].ToString(), Is.EqualTo(m_rs.SpawnPoints()[0].ToString())); } } } diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index a6dbaba..bf0ff75 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -245,6 +245,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver // Reload serialized prims m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); + UUID oldTelehubUUID = m_scene.RegionInfo.RegionSettings.TelehubObject; + IRegionSerialiserModule serialiser = m_scene.RequestModuleInterface(); int sceneObjectsLoadedCount = 0; @@ -266,11 +268,21 @@ namespace OpenSim.Region.CoreModules.World.Archiver SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); + bool isTelehub = (sceneObject.UUID == oldTelehubUUID); + // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned // on the same region server and multiple examples a single object archive to be imported // to the same scene (when this is possible). sceneObject.ResetIDs(); + if (isTelehub) + { + // Change the Telehub Object to the new UUID + m_scene.RegionInfo.RegionSettings.TelehubObject = sceneObject.UUID; + m_scene.RegionInfo.RegionSettings.Save(); + oldTelehubUUID = UUID.Zero; + } + // Try to retain the original creator/owner/lastowner if their uuid is present on this grid // or creator data is present. Otherwise, use the estate owner instead. foreach (SceneObjectPart part in sceneObject.Parts) @@ -329,7 +341,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver int ignoredObjects = serialisedSceneObjects.Count - sceneObjectsLoadedCount; if (ignoredObjects > 0) - m_log.WarnFormat("[ARCHIVER]: Ignored {0} scene objects that already existed in the scene", ignoredObjects); + m_log.WarnFormat("[ARCHIVER]: Ignored {0} scene objects that already existed in the scene", ignoredObjects); + + if (oldTelehubUUID != UUID.Zero) + { + m_log.WarnFormat("Telehub object not found: {0}", oldTelehubUUID); + m_scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero; + m_scene.RegionInfo.RegionSettings.ClearSpawnPoints(); + } } /// @@ -505,6 +524,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver currentRegionSettings.TerrainTexture4 = loadedRegionSettings.TerrainTexture4; currentRegionSettings.UseEstateSun = loadedRegionSettings.UseEstateSun; currentRegionSettings.WaterHeight = loadedRegionSettings.WaterHeight; + currentRegionSettings.TelehubObject = loadedRegionSettings.TelehubObject; + currentRegionSettings.ClearSpawnPoints(); + foreach (SpawnPoint sp in loadedRegionSettings.SpawnPoints()) + currentRegionSettings.AddSpawnPoint(sp); currentRegionSettings.Save(); diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index eabe46e..5679ad5 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -328,7 +328,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// public string CreateControlFile(Dictionary options) { - int majorVersion = MAX_MAJOR_VERSION, minorVersion = 7; + int majorVersion = MAX_MAJOR_VERSION, minorVersion = 8; // // if (options.ContainsKey("version")) // { diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index 053c6f5..394ca27 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -534,6 +534,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080"); rs.UseEstateSun = true; rs.WaterHeight = 23; + rs.TelehubObject = UUID.Parse("00000000-0000-0000-0000-111111111111"); + rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33")); tar.WriteFile(ArchiveConstants.SETTINGS_PATH + "region1.xml", RegionSettingsSerializer.Serialize(rs)); @@ -580,6 +582,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests Assert.That(loadedRs.TerrainTexture4, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000080"))); Assert.That(loadedRs.UseEstateSun, Is.True); Assert.That(loadedRs.WaterHeight, Is.EqualTo(23)); + Assert.AreEqual(UUID.Zero, loadedRs.TelehubObject); // because no object was found with the original UUID + Assert.AreEqual(0, loadedRs.SpawnPoints().Count); } /// -- cgit v1.1 From 8b958e7e74d8e4b462c6a59c2854c5072ff8c746 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 12 May 2012 02:36:56 +0100 Subject: Revert "Save the Telehub and its Spawn Points in the OAR" This reverts commit b0b7b45b943dd94546bcfcf5d3bb871cfe35b507. Sorry BlueWall, I wanted to discuss an aspect of the data storage but I couldn't assign bugs in 'patch included' state to myself until I changed mantis just now and I forgot to mention it on irc. I wouldn't normally revert but thinks get tricky when it comes to data formats. Essentially, I would like to see the Yaw, Pitch and Distance values as separate XML entities (as used in other aspects such as vectors, quaternions) rather than as a . delimited string We can discuss this more with Oren in opensimulator.org/mantis/view.php?id=6008 --- OpenSim/Framework/RegionSettings.cs | 29 +---------------- .../External/RegionSettingsSerializer.cs | 37 ++-------------------- .../Tests/RegionSettingsSerializerTests.cs | 8 ----- .../World/Archiver/ArchiveReadRequest.cs | 25 +-------------- .../Archiver/ArchiveWriteRequestPreparation.cs | 2 +- .../World/Archiver/Tests/ArchiverTests.cs | 4 --- 6 files changed, 5 insertions(+), 100 deletions(-) diff --git a/OpenSim/Framework/RegionSettings.cs b/OpenSim/Framework/RegionSettings.cs index 011a97a..4ce3392 100644 --- a/OpenSim/Framework/RegionSettings.cs +++ b/OpenSim/Framework/RegionSettings.cs @@ -29,7 +29,6 @@ using System; using System.Collections.Generic; using System.IO; using OpenMetaverse; -using System.Runtime.Serialization; namespace OpenSim.Framework { @@ -72,32 +71,6 @@ namespace OpenSim.Framework return pos + offset; } - - /// - /// Returns a string representation of this SpawnPoint. - /// - /// - public override string ToString() - { - return string.Format("{0},{1},{2}", Yaw, Pitch, Distance); - } - - /// - /// Generate a SpawnPoint from a string - /// - /// - public static SpawnPoint Parse(string str) - { - string[] parts = str.Split(','); - if (parts.Length != 3) - throw new ArgumentException("Invalid string: " + str); - - SpawnPoint sp = new SpawnPoint(); - sp.Yaw = float.Parse(parts[0]); - sp.Pitch = float.Parse(parts[1]); - sp.Distance = float.Parse(parts[2]); - return sp; - } } public class RegionSettings @@ -483,7 +456,7 @@ namespace OpenSim.Framework } // Connected Telehub object - private UUID m_TelehubObject = UUID.Zero; + private UUID m_TelehubObject; public UUID TelehubObject { get diff --git a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs index f18435d..931898c 100644 --- a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs +++ b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs @@ -30,8 +30,6 @@ using System.Text; using System.Xml; using OpenMetaverse; using OpenSim.Framework; -using log4net; -using System.Reflection; namespace OpenSim.Framework.Serialization.External { @@ -189,29 +187,7 @@ namespace OpenSim.Framework.Serialization.External break; } } - - xtr.ReadEndElement(); - - if (xtr.IsStartElement("Telehub")) - { - xtr.ReadStartElement("Telehub"); - - while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement) - { - switch (xtr.Name) - { - case "TelehubObject": - settings.TelehubObject = UUID.Parse(xtr.ReadElementContentAsString()); - break; - case "SpawnPoint": - string str = xtr.ReadElementContentAsString(); - SpawnPoint sp = SpawnPoint.Parse(str); - settings.AddSpawnPoint(sp); - break; - } - } - } - + xtr.Close(); sr.Close(); @@ -267,16 +243,7 @@ namespace OpenSim.Framework.Serialization.External xtw.WriteElementString("SunPosition", settings.SunPosition.ToString()); // Note: 'SunVector' isn't saved because this value is owned by the Sun Module, which // calculates it automatically according to the date and other factors. - xtw.WriteEndElement(); - - xtw.WriteStartElement("Telehub"); - if (settings.TelehubObject != UUID.Zero) - { - xtw.WriteElementString("TelehubObject", settings.TelehubObject.ToString()); - foreach (SpawnPoint sp in settings.SpawnPoints()) - xtw.WriteElementString("SpawnPoint", sp.ToString()); - } - xtw.WriteEndElement(); + xtw.WriteEndElement(); xtw.WriteEndElement(); diff --git a/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs b/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs index 09b6f6d..a61e4af 100644 --- a/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs +++ b/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs @@ -78,10 +78,6 @@ namespace OpenSim.Framework.Serialization.Tests true 12 - - 00000000-0000-0000-0000-111111111111 - 1,-2,0.33 - "; private RegionSettings m_rs; @@ -120,8 +116,6 @@ namespace OpenSim.Framework.Serialization.Tests m_rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080"); m_rs.UseEstateSun = true; m_rs.WaterHeight = 23; - m_rs.TelehubObject = UUID.Parse("00000000-0000-0000-0000-111111111111"); - m_rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33")); } [Test] @@ -135,8 +129,6 @@ namespace OpenSim.Framework.Serialization.Tests Assert.That(deserRs.TerrainTexture2, Is.EqualTo(m_rs.TerrainTexture2)); Assert.That(deserRs.DisablePhysics, Is.EqualTo(m_rs.DisablePhysics)); Assert.That(deserRs.TerrainLowerLimit, Is.EqualTo(m_rs.TerrainLowerLimit)); - Assert.That(deserRs.TelehubObject, Is.EqualTo(m_rs.TelehubObject)); - Assert.That(deserRs.SpawnPoints()[0].ToString(), Is.EqualTo(m_rs.SpawnPoints()[0].ToString())); } } } diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index bf0ff75..a6dbaba 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -245,8 +245,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver // Reload serialized prims m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); - UUID oldTelehubUUID = m_scene.RegionInfo.RegionSettings.TelehubObject; - IRegionSerialiserModule serialiser = m_scene.RequestModuleInterface(); int sceneObjectsLoadedCount = 0; @@ -268,21 +266,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); - bool isTelehub = (sceneObject.UUID == oldTelehubUUID); - // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned // on the same region server and multiple examples a single object archive to be imported // to the same scene (when this is possible). sceneObject.ResetIDs(); - if (isTelehub) - { - // Change the Telehub Object to the new UUID - m_scene.RegionInfo.RegionSettings.TelehubObject = sceneObject.UUID; - m_scene.RegionInfo.RegionSettings.Save(); - oldTelehubUUID = UUID.Zero; - } - // Try to retain the original creator/owner/lastowner if their uuid is present on this grid // or creator data is present. Otherwise, use the estate owner instead. foreach (SceneObjectPart part in sceneObject.Parts) @@ -341,14 +329,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver int ignoredObjects = serialisedSceneObjects.Count - sceneObjectsLoadedCount; if (ignoredObjects > 0) - m_log.WarnFormat("[ARCHIVER]: Ignored {0} scene objects that already existed in the scene", ignoredObjects); - - if (oldTelehubUUID != UUID.Zero) - { - m_log.WarnFormat("Telehub object not found: {0}", oldTelehubUUID); - m_scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero; - m_scene.RegionInfo.RegionSettings.ClearSpawnPoints(); - } + m_log.WarnFormat("[ARCHIVER]: Ignored {0} scene objects that already existed in the scene", ignoredObjects); } /// @@ -524,10 +505,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver currentRegionSettings.TerrainTexture4 = loadedRegionSettings.TerrainTexture4; currentRegionSettings.UseEstateSun = loadedRegionSettings.UseEstateSun; currentRegionSettings.WaterHeight = loadedRegionSettings.WaterHeight; - currentRegionSettings.TelehubObject = loadedRegionSettings.TelehubObject; - currentRegionSettings.ClearSpawnPoints(); - foreach (SpawnPoint sp in loadedRegionSettings.SpawnPoints()) - currentRegionSettings.AddSpawnPoint(sp); currentRegionSettings.Save(); diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index 5679ad5..eabe46e 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -328,7 +328,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// public string CreateControlFile(Dictionary options) { - int majorVersion = MAX_MAJOR_VERSION, minorVersion = 8; + int majorVersion = MAX_MAJOR_VERSION, minorVersion = 7; // // if (options.ContainsKey("version")) // { diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index 394ca27..053c6f5 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -534,8 +534,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080"); rs.UseEstateSun = true; rs.WaterHeight = 23; - rs.TelehubObject = UUID.Parse("00000000-0000-0000-0000-111111111111"); - rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33")); tar.WriteFile(ArchiveConstants.SETTINGS_PATH + "region1.xml", RegionSettingsSerializer.Serialize(rs)); @@ -582,8 +580,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests Assert.That(loadedRs.TerrainTexture4, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000080"))); Assert.That(loadedRs.UseEstateSun, Is.True); Assert.That(loadedRs.WaterHeight, Is.EqualTo(23)); - Assert.AreEqual(UUID.Zero, loadedRs.TelehubObject); // because no object was found with the original UUID - Assert.AreEqual(0, loadedRs.SpawnPoints().Count); } /// -- cgit v1.1 From 9d66792c2a06a667dc81e249e9ac81b6236b9126 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 12 May 2012 03:04:47 +0100 Subject: Fix mono compiler warning. Last jenkins failure looked like a glitch. --- OpenSim/Tests/Common/Helpers/SceneHelpers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index dc24418..78f9434 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs @@ -66,7 +66,7 @@ namespace OpenSim.Tests.Common private AgentCircuitManager m_acm = new AgentCircuitManager(); private ISimulationDataService m_simDataService = OpenSim.Server.Base.ServerUtils.LoadPlugin("OpenSim.Tests.Common.dll", null); - private IEstateDataService m_estateDataService; + private IEstateDataService m_estateDataService = null; private LocalAssetServicesConnector m_assetService; private LocalAuthenticationServicesConnector m_authenticationService; -- cgit v1.1 From 7c229c8b812b0975133a2612b34225c7c9403f1b Mon Sep 17 00:00:00 2001 From: BlueWall Date: Sun, 13 May 2012 17:11:44 -0400 Subject: Add configurable SpawnPointRouting Will use one of three selected methods to route avatar landing points when using Telehubs. The setting is in [Startup] using SpawnPointRouting = closest/random/sequence closest: The default setting. Routes avatar to the nearest SpawnPoint to the location. random: Picks random SpawnPoints to land the avatar. sequence: Follows a sequence to place the avatar on the next available SpawnPoint location Conflicts: OpenSim/Region/Framework/Scenes/Scene.cs --- OpenSim/Region/Framework/Scenes/Scene.cs | 81 +++++++++++++----- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 103 ++++++++++++++++++----- 2 files changed, 146 insertions(+), 38 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 3d2213a..2a2830f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -569,6 +569,15 @@ namespace OpenSim.Region.Framework.Scenes get { return m_sceneGraph.Entities; } } + // can be closest/random/sequence + private string m_SpawnPointRouting = "closest"; + // used in sequence see: SpawnPoint() + private int m_SpawnPoint; + public string SpawnPointRouting + { + get { return m_SpawnPointRouting; } + } + #endregion Properties #region Constructors @@ -586,7 +595,7 @@ namespace OpenSim.Region.Framework.Scenes Random random = new Random(); - m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue/2))+(uint)(uint.MaxValue/4); + m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue / 2)) + (uint)(uint.MaxValue / 4); m_moduleLoader = moduleLoader; m_authenticateHandler = authen; m_sceneGridService = sceneGridService; @@ -678,7 +687,7 @@ namespace OpenSim.Region.Framework.Scenes { IConfig startupConfig = m_config.Configs["Startup"]; - m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance",m_defaultDrawDistance); + m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance", m_defaultDrawDistance); m_useBackup = startupConfig.GetBoolean("UseSceneBackup", m_useBackup); if (!m_useBackup) m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName); @@ -711,7 +720,7 @@ namespace OpenSim.Region.Framework.Scenes m_clampPrimSize = true; } - m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete",m_useTrashOnDelete); + m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete", m_useTrashOnDelete); m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries); m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings); m_dontPersistBefore = @@ -723,6 +732,8 @@ namespace OpenSim.Region.Framework.Scenes m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); + m_SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); + IConfig packetConfig = m_config.Configs["PacketPool"]; if (packetConfig != null) { @@ -3389,7 +3400,7 @@ namespace OpenSim.Region.Framework.Scenes public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason, bool requirePresenceLookup) { bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || - (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); + (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); bool viahome = ((teleportFlags & (uint)TPFlags.ViaHome) != 0); bool godlike = ((teleportFlags & (uint)TPFlags.Godlike) != 0); @@ -3405,8 +3416,17 @@ namespace OpenSim.Region.Framework.Scenes // Don't disable this log message - it's too helpful m_log.DebugFormat( "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9})", - RegionInfo.RegionName, (agent.child ? "child" : "root"),agent.firstname, agent.lastname, - agent.AgentID, agent.circuitcode, agent.IPAddress, agent.Viewer, ((TPFlags)teleportFlags).ToString(), agent.startpos); + RegionInfo.RegionName, + (agent.child ? "child" : "root"), + agent.firstname, + agent.lastname, + agent.AgentID, + agent.circuitcode, + agent.IPAddress, + agent.Viewer, + ((TPFlags)teleportFlags).ToString(), + agent.startpos + ); if (LoginsDisabled) { @@ -3421,7 +3441,11 @@ namespace OpenSim.Region.Framework.Scenes // We have a zombie from a crashed session. // Or the same user is trying to be root twice here, won't work. // Kill it. - m_log.DebugFormat("[SCENE]: Zombie scene presence detected for {0} in {1}", agent.AgentID, RegionInfo.RegionName); + m_log.DebugFormat( + "[SCENE]: Zombie scene presence detected for {0} in {1}", + agent.AgentID, + RegionInfo.RegionName + ); sp.ControllingClient.Close(); sp = null; } @@ -3445,8 +3469,7 @@ namespace OpenSim.Region.Framework.Scenes { if (!VerifyUserPresence(agent, out reason)) return false; - } - catch (Exception e) + } catch (Exception e) { m_log.ErrorFormat( "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); @@ -3458,8 +3481,7 @@ namespace OpenSim.Region.Framework.Scenes { if (!AuthorizeUser(agent, out reason)) return false; - } - catch (Exception e) + } catch (Exception e) { m_log.ErrorFormat( "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); @@ -3476,8 +3498,7 @@ namespace OpenSim.Region.Framework.Scenes CapsModule.SetAgentCapsSeeds(agent); CapsModule.CreateCaps(agent.AgentID); } - } - else + } else { // Let the SP know how we got here. This has a lot of interesting // uses down the line. @@ -3500,7 +3521,7 @@ namespace OpenSim.Region.Framework.Scenes agent.teleportFlags = teleportFlags; m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); - if (vialogin) + if (vialogin) { // CleanDroppedAttachments(); @@ -3541,8 +3562,7 @@ namespace OpenSim.Region.Framework.Scenes agent.startpos.Z = 720; } } - } - else + } else { if (agent.startpos.X > EastBorders[0].BorderLine.Z) { @@ -3568,10 +3588,19 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject); // Can have multiple SpawnPoints List spawnpoints = RegionInfo.RegionSettings.SpawnPoints(); - if ( spawnpoints.Count > 1) + if (spawnpoints.Count > 1) { - // We have multiple SpawnPoints, Route the agent to a random one - agent.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count)].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); + // We have multiple SpawnPoints, Route the agent to a random or sequential one + if (SpawnPointRouting == "random") + agent.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation( + telehub.AbsolutePosition, + telehub.GroupRotation + ); + else + agent.startpos = spawnpoints[SpawnPoint()].GetLocation( + telehub.AbsolutePosition, + telehub.GroupRotation + ); } else { @@ -5257,5 +5286,19 @@ namespace OpenSim.Region.Framework.Scenes } } } + + // manage and select spawn points in sequence + public int SpawnPoint() + { + int spawnpoints = RegionInfo.RegionSettings.SpawnPoints().Count; + + if (spawnpoints == 0) + return 0; + + m_SpawnPoint++; + if (m_SpawnPoint > spawnpoints) + m_SpawnPoint = 1; + return m_SpawnPoint - 1; + } } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b737f91..bdcef71 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3934,28 +3934,93 @@ namespace OpenSim.Region.Framework.Scenes if (spawnPoints.Length == 0) return; - float distance = 9999; - int closest = -1; + int index; + bool selected = false; - for (int i = 0 ; i < spawnPoints.Length ; i++) + switch (m_scene.SpawnPointRouting) { - Vector3 spawnPosition = spawnPoints[i].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); - Vector3 offset = spawnPosition - pos; - float d = Vector3.Mag(offset); - if (d >= distance) - continue; - ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); - if (land == null) - continue; - if (land.IsEitherBannedOrRestricted(UUID)) - continue; - distance = d; - closest = i; - } - if (closest == -1) - return; + case "closest": - pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); + float distance = 9999; + int closest = -1; + + for (int i = 0; i < spawnPoints.Length; i++) + { + Vector3 spawnPosition = spawnPoints[i].GetLocation( + telehub.AbsolutePosition, + telehub.GroupRotation + ); + Vector3 offset = spawnPosition - pos; + float d = Vector3.Mag(offset); + if (d >= distance) + continue; + ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); + if (land == null) + continue; + if (land.IsEitherBannedOrRestricted(UUID)) + continue; + distance = d; + closest = i; + } + if (closest == -1) + return; + + pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); + return; + + case "random": + + do + { + index = Util.RandomClass.Next(spawnPoints.Length - 1); + + Vector3 spawnPosition = spawnPoints[index].GetLocation( + telehub.AbsolutePosition, + telehub.GroupRotation + ); + // SpawnPoint sp = spawnPoints[index]; + + ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); + if (land == null || land.IsEitherBannedOrRestricted(UUID)) + selected = false; + else + selected = true; + + } while ( selected == false); + + pos = spawnPoints[index].GetLocation( + telehub.AbsolutePosition, + telehub.GroupRotation + ); + return; + + case "sequence": + + do + { + index = m_scene.SpawnPoint(); + + Vector3 spawnPosition = spawnPoints[index].GetLocation( + telehub.AbsolutePosition, + telehub.GroupRotation + ); + // SpawnPoint sp = spawnPoints[index]; + + ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); + if (land == null || land.IsEitherBannedOrRestricted(UUID)) + selected = false; + else + selected = true; + + } while (selected == false); + + pos = spawnPoints[index].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); + ; + return; + + default: + return; + } } } } -- cgit v1.1 From 30a272ba318c2cacc27f6244dcf829c37a789a7c Mon Sep 17 00:00:00 2001 From: Chris Koeritz Date: Sun, 13 May 2012 16:58:47 -0400 Subject: Modifications for SMTP in OpenSimulator. Email size limit was fixed (was out of step with documentation at 1024, so boosted to 4096). Added configuration item for maximum email size. Redundant sleep inside email module was fixed (LSL Api was already sleeping). Added sleep time configuration item for snooze between email sending for LSL Api. Added two new configuration items (email_max_size and email_pause_time) into the example OpenSim.ini, plus fixed a spelling error (llimits) and odd tabbing. Signed-off-by: BlueWall --- .../Scripting/EMailModules/EmailModule.cs | 24 ++++--------------- .../Shared/Api/Implementation/LSL_Api.cs | 28 ++++++++++++++++------ bin/OpenSim.ini.example | 11 ++++++--- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs index 9255791..e91e8b9 100644 --- a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs @@ -64,6 +64,8 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules private TimeSpan m_QueueTimeout = new TimeSpan(2, 0, 0); // 2 hours without llGetNextEmail drops the queue private string m_InterObjectHostname = "lsl.opensim.local"; + private int m_MaxEmailSize = 4096; // largest email allowed by default, as per lsl docs. + // Scenes by Region Handle private Dictionary m_Scenes = new Dictionary(); @@ -127,6 +129,7 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules SMTP_SERVER_PORT = SMTPConfig.GetInt("SMTP_SERVER_PORT", SMTP_SERVER_PORT); SMTP_SERVER_LOGIN = SMTPConfig.GetString("SMTP_SERVER_LOGIN", SMTP_SERVER_LOGIN); SMTP_SERVER_PASSWORD = SMTPConfig.GetString("SMTP_SERVER_PASSWORD", SMTP_SERVER_PASSWORD); + m_MaxEmailSize = SMTPConfig.GetInt("email_max_size", m_MaxEmailSize); } catch (Exception e) { @@ -176,18 +179,6 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules get { return true; } } - /// - /// Delay function using thread in seconds - /// - /// - private void DelayInSeconds(int delay) - { - delay = (int)((float)delay * 1000); - if (delay == 0) - return; - System.Threading.Thread.Sleep(delay); - } - private bool IsLocal(UUID objectID) { string unused; @@ -267,10 +258,9 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules m_log.Error("[EMAIL] REGEX Problem in EMail Address: "+address); return; } - //FIXME:Check if subject + body = 4096 Byte - if ((subject.Length + body.Length) > 1024) + if ((subject.Length + body.Length) > m_MaxEmailSize) { - m_log.Error("[EMAIL] subject + body > 1024 Byte"); + m_log.Error("[EMAIL] subject + body larger than limit of " + m_MaxEmailSize + " bytes"); return; } @@ -345,10 +335,6 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules // TODO FIX } } - - //DONE: Message as Second Life style - //20 second delay - AntiSpam System - for now only 10 seconds - DelayInSeconds(10); } /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 5b5cab8..5bff2e9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -106,6 +106,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected IUrlModule m_UrlModule = null; protected Dictionary m_userInfoCache = new Dictionary(); + protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) { @@ -113,6 +114,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host = host; m_item = item; + LoadLimits(); // read script limits from config. + + m_TransferModule = + m_ScriptEngine.World.RequestModuleInterface(); + m_UrlModule = m_ScriptEngine.World.RequestModuleInterface(); + + AsyncCommands = new AsyncCommandManager(ScriptEngine); + } + + /* load configuration items that affect script, object and run-time behavior. */ + private void LoadLimits() + { m_ScriptDelayFactor = m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); m_ScriptDistanceFactor = @@ -125,12 +138,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255); if (m_notecardLineReadCharsMax > 65535) m_notecardLineReadCharsMax = 65535; - - m_TransferModule = - m_ScriptEngine.World.RequestModuleInterface(); - m_UrlModule = m_ScriptEngine.World.RequestModuleInterface(); - - AsyncCommands = new AsyncCommandManager(ScriptEngine); + // load limits for particular subsystems. + IConfig SMTPConfig; + if ((SMTPConfig = m_ScriptEngine.ConfigSource.Configs["SMTP"]) != null) { + // there's an smtp config, so load in the snooze time. + EMAIL_PAUSE_TIME = SMTPConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME); + } } public override Object InitializeLifetimeService() @@ -2877,6 +2890,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public virtual void llSleep(double sec) { +// m_log.Info("llSleep snoozing " + sec + "s."); m_host.AddScriptLPS(1); Thread.Sleep((int)(sec * 1000)); } @@ -3130,7 +3144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } emailModule.SendEmail(m_host.UUID, address, subject, message); - ScriptSleep(20000); + llSleep(EMAIL_PAUSE_TIME); } public void llGetNextEmail(string address, string subject) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 50366a6..8e7e459 100755 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -273,6 +273,12 @@ ;# {host_domain_header_from} {[Startup]emailmodule:DefaultEmailModule enabled:true} {From address to use in the sent email header?} {} 127.0.0.1 ; host_domain_header_from = "127.0.0.1" + ;# {email_pause_time} {[Startup]emailmodule:DefaultEmailModule enabled:true} {Period in seconds to delay after an email is sent.} {} 20 + ; email_pause_time = 20 + + ;# {email_max_size} {[Startup]emailmodule:DefaultEmailModule enabled:true} {Maximum total size of email in bytes.} {} 4096 + ; email_max_size = 4096 + ;# {SMTP_SERVER_HOSTNAME} {[Startup]emailmodule:DefaultEmailModule enabled:true} {SMTP server name?} {} 127.0.0.1 ; SMTP_SERVER_HOSTNAME = "127.0.0.1" @@ -285,7 +291,6 @@ ;# {SMTP_SERVER_PASSWORD} {[Startup]emailmodule:DefaultEmailModule enabled:true} {SMTP server password} {} ; SMTP_SERVER_PASSWORD = "" - [Network] ;; Configure the remote console user here. This will not actually be used ;; unless you use -console=rest at startup. @@ -677,7 +682,7 @@ ;; Sets the multiplier for the scripting delays ; ScriptDelayFactor = 1.0 - ;; The factor the 10 m distances llimits are multiplied by + ;; The factor the 10 m distances limits are multiplied by ; ScriptDistanceLimitFactor = 1.0 ;; Maximum length of notecard line read @@ -780,7 +785,7 @@ ;; groups service if the service is using these keys ; XmlRpcServiceReadKey = 1234 ; XmlRpcServiceWriteKey = 1234 - + [InterestManagement] ;# {UpdatePrioritizationScheme} {} {Update prioritization scheme?} {BestAvatarResponsiveness Time Distance SimpleAngularDistance FrontBack} BestAvatarResponsiveness ;; This section controls how state updates are prioritized for each client -- cgit v1.1 From 847127f83c4a6fbfb9be0ecef3904393e6968908 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Mon, 14 May 2012 00:15:56 -0400 Subject: Oops - missed the config changes --- bin/OpenSim.ini.example | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 8e7e459..9b88816 100755 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -241,6 +241,14 @@ ;; server to send mail through. ; emailmodule = DefaultEmailModule + ;# {SpawnPointRouting} {} {Set routing method for Telehub Spawnpoints} {closest random sequential} closest + ;; SpawnPointRouting adjusts the landing for incoming avatars. + ;; "closest" will place the avatar at the SpawnPoint located in the closest + ;; available spot to the destination (typically map click/landmark). + ;; "random" will place the avatar on a randomly selected spawnpoint; + ;; "sequential" will place the avatar on the next sequential SpawnPoint + ; SpawnPointRouting = closest + [Estates] ; If these values are commented out then the user will be asked for estate details when required (this is the normal case). ; If these values are uncommented then they will be used to create a default estate as necessary. -- cgit v1.1 From fad557485c78e15380ec35c0dbcf8556a96d29f7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 14 May 2012 18:06:48 +0100 Subject: Add more region information to some teleport related logging --- .../Framework/EntityTransfer/EntityTransferModule.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index cd588e5..9766a25 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -53,7 +53,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public const int DefaultMaxTransferDistance = 4095; public const bool EnableWaitForCallbackFromTeleportDestDefault = true; - /// /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer. /// @@ -531,8 +530,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { // Region doesn't take it m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Returning avatar to source region.", - sp.Name, finalDestination.RegionName); + "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", + sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); Fail(sp, finalDestination, logout); return; @@ -564,8 +563,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (EnableWaitForCallbackFromTeleportDest && !WaitForCallback(sp.UUID)) { m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} failed due to no callback from destination region. Returning avatar to source region.", - sp.Name, finalDestination.RegionName); + "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", + sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); Fail(sp, finalDestination, logout); return; @@ -661,8 +660,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual void SetCallbackURL(AgentData agent, RegionInfo region) { agent.CallbackURI = region.ServerURI + "agent/" + agent.AgentID.ToString() + "/" + region.RegionID.ToString() + "/release/"; - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Set callback URL to {0}", agent.CallbackURI); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Set release callback URL to {0} in {1}", + agent.CallbackURI, region.RegionName); } protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) @@ -2014,4 +2015,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion } -} +} \ No newline at end of file -- cgit v1.1 From c2aa3b90d9d367bcaeba93352ef6b0f513e663f7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 14 May 2012 18:36:26 +0100 Subject: Set the agent in transit teleport flag at the first available opportunity (i.e. when IsInTransit() was being checked) to close down a race condition. On EntityTransferModule.DoTeleport() there was an IsInTransit() check to prevent multiple simultaneous teleport attempts. However, the SetInTransit() was only performed later on, which left a window in which multiple threads could pass the IsInTransit() check. This has been seen in the field and the results aren't pretty. This commit effectively combines the IsInTransit() and SetInTransit() checks so there is no such window. More failure cases are made to to call ResetInTransit() to adjust to this move. --- .../EntityTransfer/EntityTransferModule.cs | 48 +++++++++++++++++----- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 9766a25..d0aead5 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -210,6 +210,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName, e.Message, e.StackTrace); + // Make sure that we clear the in-transit flag so that future teleport attempts don't always fail. + ResetFromTransit(sp.UUID); + sp.ControllingClient.SendTeleportFailed("Internal error"); } } @@ -384,7 +387,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - if (IsInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this. + if (!SetInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this. { m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.", @@ -432,8 +435,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!m_aScene.SimulationService.QueryAccess(finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) { sp.ControllingClient.SendTeleportFailed("Teleport failed: " + reason); + ResetFromTransit(sp.UUID); + return; } + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); sp.ControllingClient.SendTeleportStart(teleportFlags); @@ -473,13 +479,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer bool logout = false; if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) { - sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", - reason)); + sp.ControllingClient.SendTeleportFailed( + String.Format("Teleport refused: {0}", reason)); + ResetFromTransit(sp.UUID); + return; } // OK, it got this agent. Let's close some child agents sp.CloseChildAgents(newRegionX, newRegionY); + IClientIPEndpoint ipepClient; if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) { @@ -516,8 +525,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); } - SetInTransit(sp.UUID); - // Let's send a full update of the agent. This is a synchronous call. AgentData agent = new AgentData(); sp.CopyTo(agent); @@ -1956,25 +1963,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return count > 0; } - protected void SetInTransit(UUID id) + /// + /// Set that an agent is in the process of being teleported. + /// + /// The ID of the agent being teleported + /// true if the agent was not already in transit, false if it was + protected bool SetInTransit(UUID id) { lock (m_agentsInTransit) { if (!m_agentsInTransit.Contains(id)) + { m_agentsInTransit.Add(id); + return true; + } } + + return false; } + /// + /// Show whether the given agent is being teleported. + /// + /// true if the agent is in the process of being teleported, false otherwise. + /// The agent ID protected bool IsInTransit(UUID id) { lock (m_agentsInTransit) - { - if (m_agentsInTransit.Contains(id)) - return true; - } - return false; + return m_agentsInTransit.Contains(id); } + /// + /// Set that an agent is no longer being teleported. + /// + /// + /// + /// true if the agent was flagged as being teleported when this method was called, false otherwise + /// protected bool ResetFromTransit(UUID id) { lock (m_agentsInTransit) @@ -1985,6 +2010,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return true; } } + return false; } -- cgit v1.1 From deeac6931242f1bbb05f0ec36c31a147b32d4b26 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 14 May 2012 18:48:40 +0100 Subject: minor: comment out individual attachment transfer log messages for now --- OpenSim/Region/Framework/Scenes/Scene.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2a2830f..2bf3638 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2576,10 +2576,10 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectGroup grp = sceneObject; - m_log.DebugFormat( - "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.FromItemID, grp.UUID); - m_log.DebugFormat( - "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); +// m_log.DebugFormat( +// "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.FromItemID, grp.UUID); +// m_log.DebugFormat( +// "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); RootPrim.RemFlag(PrimFlags.TemporaryOnRez); -- cgit v1.1 From af6c85308adced4ac4a51bf14bd2beb7f22c6555 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 14 May 2012 18:57:02 +0100 Subject: minor: add explanative comment to 'missing baked texture' logging commonly seen on inter-simulator teleports where avatar baked textures are not available from the asset service. --- .../CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 0ed10d2..705233c 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -371,11 +371,21 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory if (missingTexturesOnly) { if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) + { continue; + } else + { + // On inter-simulator teleports, this occurs if baked textures are not being stored by the + // grid asset service (which means that they are not available to the new region and so have + // to be re-requested from the client). + // + // The only available core OpenSimulator behaviour right now + // is not to store these textures, temporarily or otherwise. m_log.DebugFormat( "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", face.TextureID, idx, sp.Name); + } } else { -- cgit v1.1 From d7fd9b159a7af813cfd6901a65e0ed43a6e1593d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 14 May 2012 19:36:26 +0100 Subject: set executable bit for Ionic.Zip.dll for running OpenSimulator under cygwin --- bin/Ionic.Zip.dll | Bin 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 bin/Ionic.Zip.dll diff --git a/bin/Ionic.Zip.dll b/bin/Ionic.Zip.dll old mode 100644 new mode 100755 -- cgit v1.1 From 52a32878a9573681e3b56d0151c4a0903719eadf Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 3 May 2012 19:38:35 +0300 Subject: Save the Telehub and its Spawn Points in the OAR --- OpenSim/Framework/RegionSettings.cs | 29 ++++++++++++++++- .../External/RegionSettingsSerializer.cs | 37 ++++++++++++++++++++-- .../Tests/RegionSettingsSerializerTests.cs | 8 +++++ .../World/Archiver/ArchiveReadRequest.cs | 25 ++++++++++++++- .../Archiver/ArchiveWriteRequestPreparation.cs | 2 +- .../World/Archiver/Tests/ArchiverTests.cs | 4 +++ 6 files changed, 100 insertions(+), 5 deletions(-) diff --git a/OpenSim/Framework/RegionSettings.cs b/OpenSim/Framework/RegionSettings.cs index 4ce3392..47dbcec 100644 --- a/OpenSim/Framework/RegionSettings.cs +++ b/OpenSim/Framework/RegionSettings.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.IO; using OpenMetaverse; +using System.Runtime.Serialization; namespace OpenSim.Framework { @@ -71,6 +72,32 @@ namespace OpenSim.Framework return pos + offset; } + + /// + /// Returns a string representation of this SpawnPoint. + /// + /// + public override string ToString() + { + return string.Format("{0},{1},{2}", Yaw, Pitch, Distance); + } + + /// + /// Generate a SpawnPoint from a string + /// + /// + public static SpawnPoint Parse(string str) + { + string[] parts = str.Split(','); + if (parts.Length != 3) + throw new ArgumentException("Invalid string: " + str); + + SpawnPoint sp = new SpawnPoint(); + sp.Yaw = float.Parse(parts[0]); + sp.Pitch = float.Parse(parts[1]); + sp.Distance = float.Parse(parts[2]); + return sp; + } } public class RegionSettings @@ -456,7 +483,7 @@ namespace OpenSim.Framework } // Connected Telehub object - private UUID m_TelehubObject; + private UUID m_TelehubObject = UUID.Zero; public UUID TelehubObject { get diff --git a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs index 931898c..f18435d 100644 --- a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs +++ b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs @@ -30,6 +30,8 @@ using System.Text; using System.Xml; using OpenMetaverse; using OpenSim.Framework; +using log4net; +using System.Reflection; namespace OpenSim.Framework.Serialization.External { @@ -187,7 +189,29 @@ namespace OpenSim.Framework.Serialization.External break; } } - + + xtr.ReadEndElement(); + + if (xtr.IsStartElement("Telehub")) + { + xtr.ReadStartElement("Telehub"); + + while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement) + { + switch (xtr.Name) + { + case "TelehubObject": + settings.TelehubObject = UUID.Parse(xtr.ReadElementContentAsString()); + break; + case "SpawnPoint": + string str = xtr.ReadElementContentAsString(); + SpawnPoint sp = SpawnPoint.Parse(str); + settings.AddSpawnPoint(sp); + break; + } + } + } + xtr.Close(); sr.Close(); @@ -243,7 +267,16 @@ namespace OpenSim.Framework.Serialization.External xtw.WriteElementString("SunPosition", settings.SunPosition.ToString()); // Note: 'SunVector' isn't saved because this value is owned by the Sun Module, which // calculates it automatically according to the date and other factors. - xtw.WriteEndElement(); + xtw.WriteEndElement(); + + xtw.WriteStartElement("Telehub"); + if (settings.TelehubObject != UUID.Zero) + { + xtw.WriteElementString("TelehubObject", settings.TelehubObject.ToString()); + foreach (SpawnPoint sp in settings.SpawnPoints()) + xtw.WriteElementString("SpawnPoint", sp.ToString()); + } + xtw.WriteEndElement(); xtw.WriteEndElement(); diff --git a/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs b/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs index a61e4af..09b6f6d 100644 --- a/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs +++ b/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs @@ -78,6 +78,10 @@ namespace OpenSim.Framework.Serialization.Tests true 12 + + 00000000-0000-0000-0000-111111111111 + 1,-2,0.33 + "; private RegionSettings m_rs; @@ -116,6 +120,8 @@ namespace OpenSim.Framework.Serialization.Tests m_rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080"); m_rs.UseEstateSun = true; m_rs.WaterHeight = 23; + m_rs.TelehubObject = UUID.Parse("00000000-0000-0000-0000-111111111111"); + m_rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33")); } [Test] @@ -129,6 +135,8 @@ namespace OpenSim.Framework.Serialization.Tests Assert.That(deserRs.TerrainTexture2, Is.EqualTo(m_rs.TerrainTexture2)); Assert.That(deserRs.DisablePhysics, Is.EqualTo(m_rs.DisablePhysics)); Assert.That(deserRs.TerrainLowerLimit, Is.EqualTo(m_rs.TerrainLowerLimit)); + Assert.That(deserRs.TelehubObject, Is.EqualTo(m_rs.TelehubObject)); + Assert.That(deserRs.SpawnPoints()[0].ToString(), Is.EqualTo(m_rs.SpawnPoints()[0].ToString())); } } } diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index a6dbaba..bf0ff75 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -245,6 +245,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver // Reload serialized prims m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); + UUID oldTelehubUUID = m_scene.RegionInfo.RegionSettings.TelehubObject; + IRegionSerialiserModule serialiser = m_scene.RequestModuleInterface(); int sceneObjectsLoadedCount = 0; @@ -266,11 +268,21 @@ namespace OpenSim.Region.CoreModules.World.Archiver SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); + bool isTelehub = (sceneObject.UUID == oldTelehubUUID); + // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned // on the same region server and multiple examples a single object archive to be imported // to the same scene (when this is possible). sceneObject.ResetIDs(); + if (isTelehub) + { + // Change the Telehub Object to the new UUID + m_scene.RegionInfo.RegionSettings.TelehubObject = sceneObject.UUID; + m_scene.RegionInfo.RegionSettings.Save(); + oldTelehubUUID = UUID.Zero; + } + // Try to retain the original creator/owner/lastowner if their uuid is present on this grid // or creator data is present. Otherwise, use the estate owner instead. foreach (SceneObjectPart part in sceneObject.Parts) @@ -329,7 +341,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver int ignoredObjects = serialisedSceneObjects.Count - sceneObjectsLoadedCount; if (ignoredObjects > 0) - m_log.WarnFormat("[ARCHIVER]: Ignored {0} scene objects that already existed in the scene", ignoredObjects); + m_log.WarnFormat("[ARCHIVER]: Ignored {0} scene objects that already existed in the scene", ignoredObjects); + + if (oldTelehubUUID != UUID.Zero) + { + m_log.WarnFormat("Telehub object not found: {0}", oldTelehubUUID); + m_scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero; + m_scene.RegionInfo.RegionSettings.ClearSpawnPoints(); + } } /// @@ -505,6 +524,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver currentRegionSettings.TerrainTexture4 = loadedRegionSettings.TerrainTexture4; currentRegionSettings.UseEstateSun = loadedRegionSettings.UseEstateSun; currentRegionSettings.WaterHeight = loadedRegionSettings.WaterHeight; + currentRegionSettings.TelehubObject = loadedRegionSettings.TelehubObject; + currentRegionSettings.ClearSpawnPoints(); + foreach (SpawnPoint sp in loadedRegionSettings.SpawnPoints()) + currentRegionSettings.AddSpawnPoint(sp); currentRegionSettings.Save(); diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index eabe46e..5679ad5 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -328,7 +328,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// public string CreateControlFile(Dictionary options) { - int majorVersion = MAX_MAJOR_VERSION, minorVersion = 7; + int majorVersion = MAX_MAJOR_VERSION, minorVersion = 8; // // if (options.ContainsKey("version")) // { diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index 053c6f5..394ca27 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -534,6 +534,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080"); rs.UseEstateSun = true; rs.WaterHeight = 23; + rs.TelehubObject = UUID.Parse("00000000-0000-0000-0000-111111111111"); + rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33")); tar.WriteFile(ArchiveConstants.SETTINGS_PATH + "region1.xml", RegionSettingsSerializer.Serialize(rs)); @@ -580,6 +582,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests Assert.That(loadedRs.TerrainTexture4, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000080"))); Assert.That(loadedRs.UseEstateSun, Is.True); Assert.That(loadedRs.WaterHeight, Is.EqualTo(23)); + Assert.AreEqual(UUID.Zero, loadedRs.TelehubObject); // because no object was found with the original UUID + Assert.AreEqual(0, loadedRs.SpawnPoints().Count); } /// -- cgit v1.1 From e7819ce909e7d0bd7494db9af8a8d5dc4212a6cb Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 15 May 2012 01:02:38 +0100 Subject: Port Avination's collision fixes to core. --- OpenSim/Data/Tests/RegionTests.cs | 1 - .../Region/Framework/Scenes/SceneObjectGroup.cs | 11 - OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 682 ++++++--------------- .../Scenes/Serialization/SceneObjectSerializer.cs | 7 + .../Shared/Api/Implementation/LSL_Api.cs | 21 +- 5 files changed, 199 insertions(+), 523 deletions(-) diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs index 1f03ec5..474609b 100644 --- a/OpenSim/Data/Tests/RegionTests.cs +++ b/OpenSim/Data/Tests/RegionTests.cs @@ -632,7 +632,6 @@ namespace OpenSim.Data.Tests .IgnoreProperty(x=>x.RegionUUID) .IgnoreProperty(x=>x.Scene) .IgnoreProperty(x=>x.Parts) - .IgnoreProperty(x=>x.PassCollision) .IgnoreProperty(x=>x.RootPart)); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 05bea8d..20d7a01 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -505,17 +505,6 @@ namespace OpenSim.Region.Framework.Scenes get { return true; } } - private bool m_passCollision; - public bool PassCollision - { - get { return m_passCollision; } - set - { - m_passCollision = value; - HasGroupChanged = true; - } - } - public bool IsSelected { get { return m_isSelected; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index f911ef8..35986cf 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -254,7 +254,8 @@ namespace OpenSim.Region.Framework.Scenes private readonly Stack m_undo = new Stack(5); private readonly Stack m_redo = new Stack(5); - private bool m_passTouches; + private bool m_passTouches = false; + private bool m_passCollisions = false; protected Vector3 m_acceleration; protected Vector3 m_angularVelocity; @@ -541,6 +542,7 @@ namespace OpenSim.Region.Framework.Scenes } } + [XmlIgnore] public bool PassTouches { get { return m_passTouches; } @@ -553,8 +555,18 @@ namespace OpenSim.Region.Framework.Scenes } } - - + public bool PassCollisions + { + get { return m_passCollisions; } + set + { + m_passCollisions = value; + + if (ParentGroup != null) + ParentGroup.HasGroupChanged = true; + } + } + public Dictionary CollisionFilter { get { return m_CollisionFilter; } @@ -2000,546 +2012,202 @@ namespace OpenSim.Region.Framework.Scenes { } - public void PhysicsCollision(EventArgs e) + private bool CollisionFilteredOut(SceneObjectPart dest, UUID objectID, string objectName) { -// m_log.DebugFormat("Invoking PhysicsCollision on {0} {1} {2}", Name, LocalId, UUID); - - // single threaded here - - CollisionEventUpdate a = (CollisionEventUpdate)e; - Dictionary collissionswith = a.m_objCollisionList; - List thisHitColliders = new List(); - List endedColliders = new List(); - List startedColliders = new List(); - - // calculate things that started colliding this time - // and build up list of colliders this time - foreach (uint localid in collissionswith.Keys) - { - thisHitColliders.Add(localid); - if (!m_lastColliders.Contains(localid)) - { - startedColliders.Add(localid); - } - //m_log.Debug("[OBJECT]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString()); - } + if(dest.CollisionFilter.Count == 0) + return false; - // calculate things that ended colliding - foreach (uint localID in m_lastColliders) + if (dest.CollisionFilter.ContainsValue(objectID.ToString()) || + dest.CollisionFilter.ContainsValue(objectID.ToString() + objectName) || + dest.CollisionFilter.ContainsValue(UUID.Zero.ToString() + objectName)) { - if (!thisHitColliders.Contains(localID)) - { - endedColliders.Add(localID); - } + if (dest.CollisionFilter.ContainsKey(1)) + return false; + return true; } - //add the items that started colliding this time to the last colliders list. - foreach (uint localID in startedColliders) - { - m_lastColliders.Add(localID); - } - // remove things that ended colliding from the last colliders list - foreach (uint localID in endedColliders) - { - m_lastColliders.Remove(localID); - } - - if (ParentGroup.IsDeleted) - return; + if (dest.CollisionFilter.ContainsKey(1)) + return true; - // play the sound. - if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) - { - SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, (byte)0, 0, false, false); - } + return false; + } - if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_start) != 0) - { - // do event notification - if (startedColliders.Count > 0) - { - ColliderArgs StartCollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in startedColliders) - { - if (localId == 0) - continue; + private DetectedObject CreateDetObject(SceneObjectPart obj) + { + DetectedObject detobj = new DetectedObject(); + detobj.keyUUID = obj.UUID; + detobj.nameStr = obj.Name; + detobj.ownerUUID = obj.OwnerID; + detobj.posVector = obj.AbsolutePosition; + detobj.rotQuat = obj.GetWorldRotation(); + detobj.velVector = obj.Velocity; + detobj.colliderType = 0; + detobj.groupUUID = obj.GroupID; - if (ParentGroup.Scene == null) - return; + return detobj; + } - SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); - string data = ""; - if (obj != null) - { - if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) - || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); - //If it is 1, it is to accept ONLY collisions from this object - if (found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - //If it is 0, it is to not accept collisions from this object - else - { - } - } - else - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); - //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work - if (!found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - } - } - else - { - ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av) - { - if (av.LocalId == localId) - { - if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) - || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); - //If it is 1, it is to accept ONLY collisions from this avatar - if (found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = av.UUID; - detobj.nameStr = av.ControllingClient.Name; - detobj.ownerUUID = av.UUID; - detobj.posVector = av.AbsolutePosition; - detobj.rotQuat = av.Rotation; - detobj.velVector = av.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = av.ControllingClient.ActiveGroupId; - colliding.Add(detobj); - } - //If it is 0, it is to not accept collisions from this avatar - else - { - } - } - else - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); - //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work - if (!found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = av.UUID; - detobj.nameStr = av.ControllingClient.Name; - detobj.ownerUUID = av.UUID; - detobj.posVector = av.AbsolutePosition; - detobj.rotQuat = av.Rotation; - detobj.velVector = av.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = av.ControllingClient.ActiveGroupId; - colliding.Add(detobj); - } - } + private DetectedObject CreateDetObject(ScenePresence av) + { + DetectedObject detobj = new DetectedObject(); + detobj.keyUUID = av.UUID; + detobj.nameStr = av.ControllingClient.Name; + detobj.ownerUUID = av.UUID; + detobj.posVector = av.AbsolutePosition; + detobj.rotQuat = av.Rotation; + detobj.velVector = av.Velocity; + detobj.colliderType = 0; + detobj.groupUUID = av.ControllingClient.ActiveGroupId; - } - }); - } - } + return detobj; + } - if (colliding.Count > 0) - { - StartCollidingMessage.Colliders = colliding; + private DetectedObject CreateDetObjectForGround() + { + DetectedObject detobj = new DetectedObject(); + detobj.keyUUID = UUID.Zero; + detobj.nameStr = ""; + detobj.ownerUUID = UUID.Zero; + detobj.posVector = ParentGroup.RootPart.AbsolutePosition; + detobj.rotQuat = Quaternion.Identity; + detobj.velVector = Vector3.Zero; + detobj.colliderType = 0; + detobj.groupUUID = UUID.Zero; - if (ParentGroup.Scene == null) - return; + return detobj; + } -// if (m_parentGroup.PassCollision == true) -// { -// //TODO: Add pass to root prim! -// } + private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List colliders) + { + ColliderArgs colliderArgs = new ColliderArgs(); + List colliding = new List(); + foreach (uint localId in colliders) + { + if (localId == 0) + continue; - ParentGroup.Scene.EventManager.TriggerScriptCollidingStart(LocalId, StartCollidingMessage); - } + SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); + if (obj != null) + { + if (!dest.CollisionFilteredOut(this, obj.UUID, obj.Name)) + colliding.Add(CreateDetObject(obj)); } - } - - if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision) != 0) - { - if (m_lastColliders.Count > 0) + else { - ColliderArgs CollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in m_lastColliders) - { - // always running this check because if the user deletes the object it would return a null reference. - if (localId == 0) - continue; - - if (ParentGroup.Scene == null) - return; - - SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); - string data = ""; - if (obj != null) - { - if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) - || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); - //If it is 1, it is to accept ONLY collisions from this object - if (found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - //If it is 0, it is to not accept collisions from this object - else - { - } - } - else - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); - //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work - if (!found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - } - } - else - { - ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av) - { - if (av.LocalId == localId) - { - if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) - || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); - //If it is 1, it is to accept ONLY collisions from this avatar - if (found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = av.UUID; - detobj.nameStr = av.ControllingClient.Name; - detobj.ownerUUID = av.UUID; - detobj.posVector = av.AbsolutePosition; - detobj.rotQuat = av.Rotation; - detobj.velVector = av.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = av.ControllingClient.ActiveGroupId; - colliding.Add(detobj); - } - //If it is 0, it is to not accept collisions from this avatar - else - { - } - } - else - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); - //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work - if (!found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = av.UUID; - detobj.nameStr = av.ControllingClient.Name; - detobj.ownerUUID = av.UUID; - detobj.posVector = av.AbsolutePosition; - detobj.rotQuat = av.Rotation; - detobj.velVector = av.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = av.ControllingClient.ActiveGroupId; - colliding.Add(detobj); - } - } - - } - }); - } - } - if (colliding.Count > 0) + ScenePresence av = ParentGroup.Scene.GetScenePresence(localId); + if (av != null && (!av.IsChildAgent)) { - CollidingMessage.Colliders = colliding; - - if (ParentGroup.Scene == null) - return; - - ParentGroup.Scene.EventManager.TriggerScriptColliding(LocalId, CollidingMessage); + if (!dest.CollisionFilteredOut(this, av.UUID, av.Name)) + colliding.Add(CreateDetObject(av)); } } } - - if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_end) != 0) - { - if (endedColliders.Count > 0) - { - ColliderArgs EndCollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in endedColliders) - { - if (localId == 0) - continue; - if (ParentGroup.Scene == null) - return; + colliderArgs.Colliders = colliding; - SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); - string data = ""; - if (obj != null) - { - if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); - //If it is 1, it is to accept ONLY collisions from this object - if (found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - //If it is 0, it is to not accept collisions from this object - else - { - } - } - else - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); - //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work - if (!found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - } - } - else - { - ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av) - { - if (av.LocalId == localId) - { - if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) - || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); - //If it is 1, it is to accept ONLY collisions from this avatar - if (found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = av.UUID; - detobj.nameStr = av.ControllingClient.Name; - detobj.ownerUUID = av.UUID; - detobj.posVector = av.AbsolutePosition; - detobj.rotQuat = av.Rotation; - detobj.velVector = av.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = av.ControllingClient.ActiveGroupId; - colliding.Add(detobj); - } - //If it is 0, it is to not accept collisions from this avatar - else - { - } - } - else - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); - //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work - if (!found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = av.UUID; - detobj.nameStr = av.ControllingClient.Name; - detobj.ownerUUID = av.UUID; - detobj.posVector = av.AbsolutePosition; - detobj.rotQuat = av.Rotation; - detobj.velVector = av.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = av.ControllingClient.ActiveGroupId; - colliding.Add(detobj); - } - } + return colliderArgs; + } - } - }); - } - } - - if (colliding.Count > 0) - { - EndCollidingMessage.Colliders = colliding; - - if (ParentGroup.Scene == null) - return; - - ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd(LocalId, EndCollidingMessage); - } - } - } + private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message); + + private void SendCollisionEvent(scriptEvents ev, List colliders, ScriptCollidingNotification notify) + { + bool sendToRoot = false; + ColliderArgs CollidingMessage; - if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_start) != 0) + if (colliders.Count > 0) { - if (startedColliders.Count > 0) + if ((ScriptEvents & ev) != 0) { - ColliderArgs LandStartCollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in startedColliders) - { - if (localId == 0) - { - //Hope that all is left is ground! - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = UUID.Zero; - detobj.nameStr = ""; - detobj.ownerUUID = UUID.Zero; - detobj.posVector = ParentGroup.RootPart.AbsolutePosition; - detobj.rotQuat = Quaternion.Identity; - detobj.velVector = Vector3.Zero; - detobj.colliderType = 0; - detobj.groupUUID = UUID.Zero; - colliding.Add(detobj); - } - } - - if (colliding.Count > 0) - { - LandStartCollidingMessage.Colliders = colliding; + CollidingMessage = CreateColliderArgs(this, colliders); - if (ParentGroup.Scene == null) - return; + if (CollidingMessage.Colliders.Count > 0) + notify(LocalId, CollidingMessage); - ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart(LocalId, LandStartCollidingMessage); - } + if (PassCollisions) + sendToRoot = true; + } + else + { + if ((ParentGroup.RootPart.ScriptEvents & ev) != 0) + sendToRoot = true; + } + if (sendToRoot && ParentGroup.RootPart != this) + { + CollidingMessage = CreateColliderArgs(ParentGroup.RootPart, colliders); + if (CollidingMessage.Colliders.Count > 0) + notify(ParentGroup.RootPart.LocalId, CollidingMessage); } } + } - if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision) != 0) + private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify) + { + if ((ParentGroup.RootPart.ScriptEvents & ev) != 0) { - if (m_lastColliders.Count > 0) - { - ColliderArgs LandCollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in startedColliders) - { - if (localId == 0) - { - //Hope that all is left is ground! - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = UUID.Zero; - detobj.nameStr = ""; - detobj.ownerUUID = UUID.Zero; - detobj.posVector = ParentGroup.RootPart.AbsolutePosition; - detobj.rotQuat = Quaternion.Identity; - detobj.velVector = Vector3.Zero; - detobj.colliderType = 0; - detobj.groupUUID = UUID.Zero; - colliding.Add(detobj); - } - } + ColliderArgs LandCollidingMessage = new ColliderArgs(); + List colliding = new List(); + + colliding.Add(CreateDetObjectForGround()); + LandCollidingMessage.Colliders = colliding; - if (colliding.Count > 0) - { - LandCollidingMessage.Colliders = colliding; + notify(LocalId, LandCollidingMessage); + } + } - if (ParentGroup.Scene == null) - return; + public void PhysicsCollision(EventArgs e) + { + if (ParentGroup.Scene == null || ParentGroup.IsDeleted) + return; - ParentGroup.Scene.EventManager.TriggerScriptLandColliding(LocalId, LandCollidingMessage); - } - } + // single threaded here + CollisionEventUpdate a = (CollisionEventUpdate)e; + Dictionary collissionswith = a.m_objCollisionList; + List thisHitColliders = new List(); + List endedColliders = new List(); + List startedColliders = new List(); + + // calculate things that started colliding this time + // and build up list of colliders this time + foreach (uint localid in collissionswith.Keys) + { + thisHitColliders.Add(localid); + if (!m_lastColliders.Contains(localid)) + startedColliders.Add(localid); } - if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_end) != 0) + // calculate things that ended colliding + foreach (uint localID in m_lastColliders) { - if (endedColliders.Count > 0) - { - ColliderArgs LandEndCollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in startedColliders) - { - if (localId == 0) - { - //Hope that all is left is ground! - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = UUID.Zero; - detobj.nameStr = ""; - detobj.ownerUUID = UUID.Zero; - detobj.posVector = ParentGroup.RootPart.AbsolutePosition; - detobj.rotQuat = Quaternion.Identity; - detobj.velVector = Vector3.Zero; - detobj.colliderType = 0; - detobj.groupUUID = UUID.Zero; - colliding.Add(detobj); - } - } + if (!thisHitColliders.Contains(localID)) + endedColliders.Add(localID); + } - if (colliding.Count > 0) - { - LandEndCollidingMessage.Colliders = colliding; + //add the items that started colliding this time to the last colliders list. + foreach (uint localID in startedColliders) + m_lastColliders.Add(localID); - if (ParentGroup.Scene == null) - return; + // remove things that ended colliding from the last colliders list + foreach (uint localID in endedColliders) + m_lastColliders.Remove(localID); - ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd(LocalId, LandEndCollidingMessage); - } - } + // play the sound. + if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) + SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, (byte)0, 0, false, false); + + SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart); + SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding); + SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); + + if (startedColliders.Contains(0)) + { + if (m_lastColliders.Contains(0)) + SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding); + else + SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart); } + if (endedColliders.Contains(0)) + SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); } public void PhysicsOutOfBounds(Vector3 pos) @@ -4328,6 +3996,12 @@ namespace OpenSim.Region.Framework.Scenes ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || (CollisionSound != UUID.Zero) ) { @@ -4652,6 +4326,12 @@ namespace OpenSim.Region.Framework.Scenes ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || (CollisionSound != UUID.Zero) ) { diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index e6b88a3..a11dc49 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -301,6 +301,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization m_SOPXmlProcessors.Add("Name", ProcessName); m_SOPXmlProcessors.Add("Material", ProcessMaterial); m_SOPXmlProcessors.Add("PassTouches", ProcessPassTouches); + m_SOPXmlProcessors.Add("PassCollisions", ProcessPassCollisions); m_SOPXmlProcessors.Add("RegionHandle", ProcessRegionHandle); m_SOPXmlProcessors.Add("ScriptAccessPin", ProcessScriptAccessPin); m_SOPXmlProcessors.Add("GroupPosition", ProcessGroupPosition); @@ -485,6 +486,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization obj.PassTouches = Util.ReadBoolean(reader); } + private static void ProcessPassCollisions(SceneObjectPart obj, XmlTextReader reader) + { + obj.PassCollisions = Util.ReadBoolean(reader); + } + private static void ProcessRegionHandle(SceneObjectPart obj, XmlTextReader reader) { obj.RegionHandle = (ulong)reader.ReadElementContentAsLong("RegionHandle", String.Empty); @@ -1153,6 +1159,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("Name", sop.Name); writer.WriteElementString("Material", sop.Material.ToString()); writer.WriteElementString("PassTouches", sop.PassTouches.ToString().ToLower()); + writer.WriteElementString("PassCollisions", sop.PassCollisions.ToString().ToLower()); writer.WriteElementString("RegionHandle", sop.RegionHandle.ToString()); writer.WriteElementString("ScriptAccessPin", sop.ScriptAccessPin.ToString()); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 5bff2e9..d213c35 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2929,14 +2929,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); m_host.CollisionFilter.Clear(); - if (id != null) - { - m_host.CollisionFilter.Add(accept,id); - } - else - { - m_host.CollisionFilter.Add(accept,name); - } + UUID objectID; + + if (!UUID.TryParse(id, out objectID)) + objectID = UUID.Zero; + + if (objectID == UUID.Zero && name == "") + return; + + m_host.CollisionFilter.Add(accept,objectID.ToString() + name); } public void llTakeControls(int controls, int accept, int pass_on) @@ -4466,11 +4467,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); if (pass == 0) { - m_host.ParentGroup.PassCollision = false; + m_host.PassCollisions = false; } else { - m_host.ParentGroup.PassCollision = true; + m_host.PassCollisions = true; } } -- cgit v1.1 From 069bcd45e51798c9be88237ece85dcd14eefe575 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 15 May 2012 02:27:21 +0100 Subject: Try to fix sqlite breakage --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 35986cf..ae8f25d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4285,6 +4285,9 @@ namespace OpenSim.Region.Framework.Scenes public void aggregateScriptEvents() { + if (ParentGroup.RootPart == null) + return; + AggregateScriptEvents = 0; // Aggregate script events -- cgit v1.1 From 65e1d7b2d7a9c08799118263219bf77526f34fa5 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 15 May 2012 03:16:12 +0100 Subject: Guard against null root part on SQLite. This really needs to be fixed so SQLite loads roots before children like MySQL does. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ae8f25d..e3f06f8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4285,7 +4285,7 @@ namespace OpenSim.Region.Framework.Scenes public void aggregateScriptEvents() { - if (ParentGroup.RootPart == null) + if (ParentGroup == null || ParentGroup.RootPart == null) return; AggregateScriptEvents = 0; -- cgit v1.1 From 1ce576b115c5f735794d2e0fe8f24e00fa9f7614 Mon Sep 17 00:00:00 2001 From: dahlia Date: Mon, 14 May 2012 19:34:18 -0700 Subject: Add another null check to Melanie's last commit. Seems to eliminate sqlite errors in log but no idea if it's working properly --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ae8f25d..e3f06f8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4285,7 +4285,7 @@ namespace OpenSim.Region.Framework.Scenes public void aggregateScriptEvents() { - if (ParentGroup.RootPart == null) + if (ParentGroup == null || ParentGroup.RootPart == null) return; AggregateScriptEvents = 0; -- cgit v1.1 From 02f3b116c6531f89314be6bc58115537147e512b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 15 May 2012 22:43:47 +0100 Subject: Allow use of regular expressions in "show object name", "show part name" and "delete object name" console commands if --regex switch is used. Deleteing objects by name, creator uuid or owner uuid now requires confirmation to avoid accidental deletion. --- .../World/Objects/Commands/ObjectCommandsModule.cs | 309 ++++++++++++++------- bin/Ionic.Zip.dll | Bin 2 files changed, 208 insertions(+), 101 deletions(-) mode change 100755 => 100644 bin/Ionic.Zip.dll diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index 5e928f3..830d9cb 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -29,8 +29,10 @@ using System; using System.Collections.Generic; using System.Reflection; using System.Text; +using System.Text.RegularExpressions; using log4net; using Mono.Addins; +using NDesk.Options; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -78,25 +80,31 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands m_scene = scene; m_console = MainConsole.Instance; - m_console.Commands.AddCommand("Objects", false, "delete object owner", - "delete object owner ", - "Delete a scene object by owner", HandleDeleteObject); + m_console.Commands.AddCommand( + "Objects", false, "delete object owner", + "delete object owner ", + "Delete a scene object by owner", HandleDeleteObject); - m_console.Commands.AddCommand("Objects", false, "delete object creator", - "delete object creator ", - "Delete a scene object by creator", HandleDeleteObject); + m_console.Commands.AddCommand( + "Objects", false, "delete object creator", + "delete object creator ", + "Delete a scene object by creator", HandleDeleteObject); - m_console.Commands.AddCommand("Objects", false, "delete object uuid", - "delete object uuid ", - "Delete a scene object by uuid", HandleDeleteObject); + m_console.Commands.AddCommand( + "Objects", false, "delete object uuid", + "delete object uuid ", + "Delete a scene object by uuid", HandleDeleteObject); - m_console.Commands.AddCommand("Objects", false, "delete object name", - "delete object name ", - "Delete a scene object by name", HandleDeleteObject); + m_console.Commands.AddCommand( + "Objects", false, "delete object name", + "delete object name [--regex] ", + "Delete a scene object by name.\nIf --regex is specified then the name is treatead as a regular expression", + HandleDeleteObject); - m_console.Commands.AddCommand("Objects", false, "delete object outside", - "delete object outside", - "Delete all scene objects outside region boundaries", HandleDeleteObject); + m_console.Commands.AddCommand( + "Objects", false, "delete object outside", + "delete object outside", + "Delete all scene objects outside region boundaries", HandleDeleteObject); m_console.Commands.AddCommand( "Objects", @@ -109,8 +117,9 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands "Objects", false, "show object name", - "show object name ", - "Show details of scene objects with the given name", HandleShowObjectByName); + "show object name [--regex] ", + "Show details of scene objects with the given name.\nIf --regex is specified then the name is treatead as a regular expression", + HandleShowObjectByName); m_console.Commands.AddCommand( "Objects", @@ -123,8 +132,9 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands "Objects", false, "show part name", - "show part name ", - "Show details of scene object parts with the given name", HandleShowPartByName); + "show part name [--regex] ", + "Show details of scene object parts with the given name.\nIf --regex is specified then the name is treatead as a regular expression", + HandleShowPartByName); } public void RemoveRegion(Scene scene) @@ -169,22 +179,38 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands m_console.OutputFormat(sb.ToString()); } - private void HandleShowObjectByName(string module, string[] cmd) + private void HandleShowObjectByName(string module, string[] cmdparams) { if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) return; - if (cmd.Length < 4) + bool useRegex = false; + OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); + + List mainParams = options.Parse(cmdparams); + + if (mainParams.Count < 4) { - m_console.OutputFormat("Usage: show object name "); + m_console.OutputFormat("Usage: show object name [--regex] "); return; } - string name = cmd[3]; + string name = mainParams[3]; List sceneObjects = new List(); + Action searchAction; + + if (useRegex) + { + Regex nameRegex = new Regex(name); + searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }}; + } + else + { + searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }}; + } - m_scene.ForEachSOG(so => { if (so.Name == name) { sceneObjects.Add(so); }}); + m_scene.ForEachSOG(searchAction); if (sceneObjects.Count == 0) { @@ -235,22 +261,39 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands m_console.OutputFormat(sb.ToString()); } - private void HandleShowPartByName(string module, string[] cmd) + private void HandleShowPartByName(string module, string[] cmdparams) { if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) return; - if (cmd.Length < 4) + bool useRegex = false; + OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); + + List mainParams = options.Parse(cmdparams); + + if (mainParams.Count < 4) { - m_console.OutputFormat("Usage: show part name "); + m_console.OutputFormat("Usage: show part name [--regex] "); return; } - string name = cmd[3]; + string name = mainParams[3]; List parts = new List(); - m_scene.ForEachSOG(so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } })); + Action searchAction; + + if (useRegex) + { + Regex nameRegex = new Regex(name); + searchAction = so => so.ForEachPart(sop => { if (nameRegex.IsMatch(sop.Name)) { parts.Add(sop); } }); + } + else + { + searchAction = so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } }); + } + + m_scene.ForEachSOG(searchAction); if (parts.Count == 0) { @@ -312,105 +355,169 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands o = cmd[3]; } - List deletes = new List(); - + List deletes = null; UUID match; + bool requireConfirmation = true; switch (mode) { - case "owner": - if (!UUID.TryParse(o, out match)) - return; - - m_scene.ForEachSOG(delegate (SceneObjectGroup g) - { - if (g.OwnerID == match && !g.IsAttachment) - deletes.Add(g); - }); + case "owner": + if (!UUID.TryParse(o, out match)) + return; -// if (deletes.Count == 0) -// m_console.OutputFormat("No objects were found with owner {0}", match); + deletes = new List(); - break; + m_scene.ForEachSOG(delegate (SceneObjectGroup g) + { + if (g.OwnerID == match && !g.IsAttachment) + deletes.Add(g); + }); + + // if (deletes.Count == 0) + // m_console.OutputFormat("No objects were found with owner {0}", match); + + break; + + case "creator": + if (!UUID.TryParse(o, out match)) + return; - case "creator": - if (!UUID.TryParse(o, out match)) - return; + deletes = new List(); - m_scene.ForEachSOG(delegate (SceneObjectGroup g) - { - if (g.RootPart.CreatorID == match && !g.IsAttachment) - deletes.Add(g); - }); + m_scene.ForEachSOG(delegate (SceneObjectGroup g) + { + if (g.RootPart.CreatorID == match && !g.IsAttachment) + deletes.Add(g); + }); + + // if (deletes.Count == 0) + // m_console.OutputFormat("No objects were found with creator {0}", match); + + break; + + case "uuid": + if (!UUID.TryParse(o, out match)) + return; -// if (deletes.Count == 0) -// m_console.OutputFormat("No objects were found with creator {0}", match); + requireConfirmation = false; + deletes = new List(); + + m_scene.ForEachSOG(delegate (SceneObjectGroup g) + { + if (g.UUID == match && !g.IsAttachment) + deletes.Add(g); + }); + + // if (deletes.Count == 0) + // m_console.OutputFormat("No objects were found with uuid {0}", match); + + break; + + case "name": + deletes = GetDeleteCandidatesByName(module, cmd); + break; + + case "outside": + deletes = new List(); - break; + m_scene.ForEachSOG(delegate (SceneObjectGroup g) + { + SceneObjectPart rootPart = g.RootPart; + bool delete = false; + + if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0) + { + delete = true; + } + else + { + ILandObject parcel + = m_scene.LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y); + + if (parcel == null || parcel.LandData.Name == "NO LAND") + delete = true; + } + + if (delete && !g.IsAttachment && !deletes.Contains(g)) + deletes.Add(g); + }); + + if (deletes.Count == 0) + m_console.OutputFormat("No objects were found outside region bounds"); + + break; - case "uuid": - if (!UUID.TryParse(o, out match)) + default: + m_console.OutputFormat("Unrecognized mode {0}", mode); return; + } - m_scene.ForEachSOG(delegate (SceneObjectGroup g) - { - if (g.UUID == match && !g.IsAttachment) - deletes.Add(g); - }); - -// if (deletes.Count == 0) -// m_console.OutputFormat("No objects were found with uuid {0}", match); - - break; + if (deletes == null || deletes.Count <= 0) + return; - case "name": - m_scene.ForEachSOG(delegate (SceneObjectGroup g) + if (requireConfirmation) + { + string response = MainConsole.Instance.CmdPrompt( + string.Format( + "Are you sure that you want to delete {0} objects from {1}", + deletes.Count, m_scene.RegionInfo.RegionName), + "n"); + + if (response.ToLower() != "y") { - if (g.RootPart.Name == o && !g.IsAttachment) - deletes.Add(g); - }); - -// if (deletes.Count == 0) -// m_console.OutputFormat("No objects were found with name {0}", o); + MainConsole.Instance.OutputFormat( + "Aborting delete of {0} objects from {1}", deletes.Count, m_scene.RegionInfo.RegionName); - break; + return; + } + } - case "outside": - m_scene.ForEachSOG(delegate (SceneObjectGroup g) - { - SceneObjectPart rootPart = g.RootPart; - bool delete = false; + m_console.OutputFormat("Deleting {0} objects in {1}", deletes.Count, m_scene.RegionInfo.RegionName); - if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0) - { - delete = true; - } - else - { - ILandObject parcel - = m_scene.LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y); + foreach (SceneObjectGroup g in deletes) + { + m_console.OutputFormat("Deleting object {0} {1}", g.UUID, g.Name); + m_scene.DeleteSceneObject(g, false); + } + } - if (parcel == null || parcel.LandData.Name == "NO LAND") - delete = true; - } + private List GetDeleteCandidatesByName(string module, string[] cmdparams) + { + if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) + return null; - if (delete && !g.IsAttachment && !deletes.Contains(g)) - deletes.Add(g); - }); + bool useRegex = false; + OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); -// if (deletes.Count == 0) -// m_console.OutputFormat("No objects were found outside region bounds"); + List mainParams = options.Parse(cmdparams); - break; + if (mainParams.Count < 4) + { + m_console.OutputFormat("Usage: delete object name [--regex] "); + return null; } - m_console.OutputFormat("Deleting {0} objects in {1}", deletes.Count, m_scene.RegionInfo.RegionName); + string name = mainParams[3]; - foreach (SceneObjectGroup g in deletes) + List sceneObjects = new List(); + Action searchAction; + + if (useRegex) { - m_console.OutputFormat("Deleting object {0} {1}", g.UUID, g.Name); - m_scene.DeleteSceneObject(g, false); + Regex nameRegex = new Regex(name); + searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }}; + } + else + { + searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }}; } + + m_scene.ForEachSOG(searchAction); + + if (sceneObjects.Count == 0) + m_console.OutputFormat("No objects with name {0} found in {1}", name, m_scene.RegionInfo.RegionName); + + return sceneObjects; } } } \ No newline at end of file diff --git a/bin/Ionic.Zip.dll b/bin/Ionic.Zip.dll old mode 100755 new mode 100644 -- cgit v1.1 From 1b5ce8c10e492308eeb44c82fee0c65cec855327 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 15 May 2012 23:43:59 +0100 Subject: Fix issue where loading OARs could sometimes result in link numbers being reordered. This was because the parts in scene objects were sometimes not serialized in link order. This is perfectly fine since the parts still have the right link numbers, but an extra fix to adjust for this had not been done in the SerialiserModule methods that OAR loading used. Add regression test for same. Addresses http://opensimulator.org/mantis/view.php?id=5948, http://opensimulator.org/mantis/view.php?id=5749 --- .../World/Archiver/ArchiveReadRequest.cs | 4 +- .../World/Archiver/Tests/ArchiverTests.cs | 53 ++++++++++++++++++++++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 13 +++++- OpenSim/Tests/Common/Helpers/SceneHelpers.cs | 8 ++-- 4 files changed, 72 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index bf0ff75..11eca12 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -41,6 +41,7 @@ using OpenSim.Framework.Serialization.External; using OpenSim.Region.CoreModules.World.Terrain; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.World.Archiver @@ -266,7 +267,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver } */ - SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); + SceneObjectGroup sceneObject = SceneObjectSerializer.FromXml2Format(serialisedSceneObject); +// SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); bool isTelehub = (sceneObject.UUID == oldTelehubUUID); diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index 394ca27..5deaf52 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -292,6 +292,59 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests } /// + /// Test loading an OpenSim Region Archive where the scene object parts are not ordered by link number (e.g. + /// 2 can come after 3). + /// + [Test] + public void TestLoadOarUnorderedParts() + { + TestHelpers.InMethod(); + + UUID ownerId = TestHelpers.ParseTail(0xaaaa); + + MemoryStream archiveWriteStream = new MemoryStream(); + TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); + + tar.WriteFile( + ArchiveConstants.CONTROL_FILE_PATH, + new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary())); + + SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11); + SceneObjectPart sop2 + = SceneHelpers.CreateSceneObjectPart("obj1-Part2", TestHelpers.ParseTail(0x12), ownerId); + SceneObjectPart sop3 + = SceneHelpers.CreateSceneObjectPart("obj1-Part3", TestHelpers.ParseTail(0x13), ownerId); + + // Add the parts so they will be written out in reverse order to the oar + sog1.AddPart(sop3); + sop3.LinkNum = 3; + sog1.AddPart(sop2); + sop2.LinkNum = 2; + + tar.WriteFile( + ArchiveConstants.CreateOarObjectPath(sog1.Name, sog1.UUID, sog1.AbsolutePosition), + SceneObjectSerializer.ToXml2Format(sog1)); + + tar.Close(); + + MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); + + lock (this) + { + m_scene.EventManager.OnOarFileLoaded += LoadCompleted; + m_archiverModule.DearchiveRegion(archiveReadStream); + } + + Assert.That(m_lastErrorMessage, Is.Null); + + SceneObjectPart part2 = m_scene.GetSceneObjectPart("obj1-Part2"); + Assert.That(part2.LinkNum, Is.EqualTo(2)); + + SceneObjectPart part3 = m_scene.GetSceneObjectPart("obj1-Part3"); + Assert.That(part3.LinkNum, Is.EqualTo(3)); + } + + /// /// Test loading an OpenSim Region Archive. /// [Test] diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index f911ef8..1a940aa 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -932,7 +932,18 @@ namespace OpenSim.Region.Framework.Scenes public int LinkNum { get { return m_linkNum; } - set { m_linkNum = value; } + set + { +// if (ParentGroup != null) +// { +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Setting linknum of {0}@{1} to {2} from {3}", +// Name, AbsolutePosition, value, m_linkNum); +// Util.PrintCallStack(); +// } + + m_linkNum = value; + } } public byte ClickAction diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index 78f9434..59829d9 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs @@ -624,7 +624,7 @@ namespace OpenSim.Tests.Common /// /// /// The prefix to be given to part names. This will be suffixed with "Part" - /// (e.g. mynamePart0 for the root part) + /// (e.g. mynamePart1 for the root part) /// /// /// The hexadecimal last part of the UUID for parts created. A UUID of the form "00000000-0000-0000-0000-{0:XD12}" @@ -637,14 +637,14 @@ namespace OpenSim.Tests.Common SceneObjectGroup sog = new SceneObjectGroup( - CreateSceneObjectPart(string.Format("{0}Part0", partNamePrefix), new UUID(rawSogId), ownerId)); + CreateSceneObjectPart(string.Format("{0}Part1", partNamePrefix), new UUID(rawSogId), ownerId)); if (parts > 1) - for (int i = 1; i < parts; i++) + for (int i = 2; i <= parts; i++) sog.AddPart( CreateSceneObjectPart( string.Format("{0}Part{1}", partNamePrefix, i), - new UUID(string.Format("00000000-0000-0000-0000-{0:X12}", uuidTail + i)), + new UUID(string.Format("00000000-0000-0000-0000-{0:X12}", uuidTail + i - 1)), ownerId)); return sog; -- cgit v1.1 From 23ae24b4061f7c1e1bc1c0d5428374ccf4e25891 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 16 May 2012 00:10:42 +0100 Subject: Route OAR SOG loading through the common SceneObjectSerializer.FromXml2Format() rather than the functionally identical but buggy Xml2ToSOG(). Remove buggy Xml2ToSOG(). --- .../World/Archiver/ArchiveReadRequest.cs | 3 +- .../Scenes/Serialization/SceneObjectSerializer.cs | 45 -------------- .../Scenes/Serialization/SceneXmlLoader.cs | 72 ++-------------------- 3 files changed, 5 insertions(+), 115 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 11eca12..2b61800 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -267,8 +267,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver } */ - SceneObjectGroup sceneObject = SceneObjectSerializer.FromXml2Format(serialisedSceneObject); -// SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); + SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); bool isTelehub = (sceneObject.UUID == oldTelehubUUID); diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index a11dc49..0b34156 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -1424,51 +1424,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization } } - //////// Read ///////// - public static bool Xml2ToSOG(XmlTextReader reader, SceneObjectGroup sog) - { - reader.Read(); - reader.ReadStartElement("SceneObjectGroup"); - SceneObjectPart root = Xml2ToSOP(reader); - if (root != null) - sog.SetRootPart(root); - else - { - return false; - } - - if (sog.UUID == UUID.Zero) - sog.UUID = sog.RootPart.UUID; - - reader.Read(); // OtherParts - - while (!reader.EOF) - { - switch (reader.NodeType) - { - case XmlNodeType.Element: - if (reader.Name == "SceneObjectPart") - { - SceneObjectPart child = Xml2ToSOP(reader); - if (child != null) - sog.AddPart(child); - } - else - { - //Logger.Log("Found unexpected prim XML element " + reader.Name, Helpers.LogLevel.Debug); - reader.Read(); - } - break; - case XmlNodeType.EndElement: - default: - reader.Read(); - break; - } - - } - return true; - } - public static SceneObjectPart Xml2ToSOP(XmlTextReader reader) { SceneObjectPart obj = new SceneObjectPart(); diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs index d214eba..a3485d2 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs @@ -223,50 +223,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization public static SceneObjectGroup DeserializeGroupFromXml2(string xmlString) { - XmlDocument doc = new XmlDocument(); - XmlNode rootNode; - - XmlTextReader reader = new XmlTextReader(new StringReader(xmlString)); - reader.WhitespaceHandling = WhitespaceHandling.None; - doc.Load(reader); - reader.Close(); - rootNode = doc.FirstChild; - - // This is to deal with neighbouring regions that are still surrounding the group xml with the - // tag. It should be possible to remove the first part of this if statement once we go past 0.5.9 (or - // when some other changes forces all regions to upgrade). - // This might seem rather pointless since prim crossing from this revision to an earlier revision remains - // broken. But it isn't much work to accomodate the old format here. - if (rootNode.LocalName.Equals("scene")) - { - foreach (XmlNode aPrimNode in rootNode.ChildNodes) - { - // There is only ever one prim. This oddity should be removeable post 0.5.9 - //return SceneObjectSerializer.FromXml2Format(aPrimNode.OuterXml); - using (reader = new XmlTextReader(new StringReader(aPrimNode.OuterXml))) - { - SceneObjectGroup obj = new SceneObjectGroup(); - if (SceneObjectSerializer.Xml2ToSOG(reader, obj)) - return obj; - - return null; - } - } - - return null; - } - else - { - //return SceneObjectSerializer.FromXml2Format(rootNode.OuterXml); - using (reader = new XmlTextReader(new StringReader(rootNode.OuterXml))) - { - SceneObjectGroup obj = new SceneObjectGroup(); - if (SceneObjectSerializer.Xml2ToSOG(reader, obj)) - return obj; - - return null; - } - } + return SceneObjectSerializer.FromXml2Format(xmlString); } /// @@ -307,8 +264,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization ICollection sceneObjects = new List(); foreach (XmlNode aPrimNode in rootNode.ChildNodes) { - SceneObjectGroup obj = CreatePrimFromXml2(scene, aPrimNode.OuterXml); - if (obj != null && startScripts) + SceneObjectGroup obj = DeserializeGroupFromXml2(aPrimNode.OuterXml); + if (startScripts) sceneObjects.Add(obj); } @@ -319,27 +276,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization } } - /// - /// Create a prim from the xml2 representation. - /// - /// - /// - /// The scene object created. null if the scene object already existed - protected static SceneObjectGroup CreatePrimFromXml2(Scene scene, string xmlData) - { - //SceneObjectGroup obj = SceneObjectSerializer.FromXml2Format(xmlData); - using (XmlTextReader reader = new XmlTextReader(new StringReader(xmlData))) - { - SceneObjectGroup obj = new SceneObjectGroup(); - SceneObjectSerializer.Xml2ToSOG(reader, obj); - - if (scene.AddRestoredSceneObject(obj, true, false)) - return obj; - else - return null; - } - } - #endregion } -} +} \ No newline at end of file -- cgit v1.1 From e444cb9da4fd112733634dbda8b2844e69097ec4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 17 May 2012 00:33:04 +0100 Subject: Remove redundant "Teleport failed:" from reason when QueryAccess fails for the destination simulator. This part of the string is already provided by the viewer. Also adds more reason logging for diagnostics when teleports are refused/fail. --- .../Framework/EntityTransfer/EntityTransferModule.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index d0aead5..5dbe5e4 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -432,11 +432,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer string reason; string version; - if (!m_aScene.SimulationService.QueryAccess(finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) + if (!m_aScene.SimulationService.QueryAccess( + finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) { - sp.ControllingClient.SendTeleportFailed("Teleport failed: " + reason); + sp.ControllingClient.SendTeleportFailed(reason); ResetFromTransit(sp.UUID); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", + sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); + return; } @@ -479,10 +484,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer bool logout = false; if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) { - sp.ControllingClient.SendTeleportFailed( - String.Format("Teleport refused: {0}", reason)); + sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); ResetFromTransit(sp.UUID); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", + sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); + return; } -- cgit v1.1 From bdcf2d1348c6770a42a91ca5b3c7d74d2307b0c1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 17 May 2012 01:27:59 +0100 Subject: Add regression TestSameSimulatorSeparatedRegionsQueryAccessFails() --- .../Scenes/Tests/ScenePresenceTeleportTests.cs | 76 ++++++++++++++++++++++ OpenSim/Tests/Common/TestHelpers.cs | 2 +- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index ea4fb66..7c76bed 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -37,6 +37,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.CoreModules.Framework; using OpenSim.Region.CoreModules.Framework.EntityTransfer; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; +using OpenSim.Region.CoreModules.World.Permissions; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; using System.IO; @@ -161,6 +162,81 @@ namespace OpenSim.Region.Framework.Scenes.Tests // Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); } + /// + /// Test teleport procedures when the target simulator returns false when queried about access. + /// + [Test] + public void TestSameSimulatorSeparatedRegionsQueryAccessFails() + { + TestHelpers.InMethod(); + TestHelpers.EnableLogging(); + + UUID userId = TestHelpers.ParseTail(0x1); + Vector3 preTeleportPosition = new Vector3(30, 31, 32); + + EntityTransferModule etm = new EntityTransferModule(); + LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); + + IConfigSource config = new IniConfigSource(); + config.AddConfig("Modules"); + config.Configs["Modules"].Set("EntityTransferModule", etm.Name); + config.Configs["Modules"].Set("SimulationServices", lscm.Name); + + config.AddConfig("EntityTransfer"); + + // In order to run a single threaded regression test we do not want the entity transfer module waiting + // for a callback from the destination scene before removing its avatar data. + config.Configs["EntityTransfer"].Set("wait_for_callback", false); + + config.AddConfig("Startup"); + config.Configs["Startup"].Set("serverside_object_permissions", true); + + SceneHelpers sh = new SceneHelpers(); + TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); + TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000); + + // We need to set up the permisions module on scene B so that our later use of agent limit to deny + // QueryAccess won't succeed anyway because administrators are always allowed in and the default + // IsAdministrator if no permissions module is present is true. + SceneHelpers.SetupSceneModules(sceneB, config, new object[] { new PermissionsModule() }); + + // Shared scene modules + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); + + Vector3 teleportPosition = new Vector3(10, 11, 12); + Vector3 teleportLookAt = new Vector3(20, 21, 22); + + ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager); + sp.AbsolutePosition = preTeleportPosition; + + // Make sceneB return false on query access + sceneB.RegionInfo.RegionSettings.AgentLimit = 0; + + sceneA.RequestTeleportLocation( + sp.ControllingClient, + sceneB.RegionInfo.RegionHandle, + teleportPosition, + teleportLookAt, + (uint)TeleportFlags.ViaLocation); + +// ((TestClient)sp.ControllingClient).CompleteTeleportClientSide(); + + Assert.That(sceneB.GetScenePresence(userId), Is.Null); + + ScenePresence sceneASp = sceneA.GetScenePresence(userId); + Assert.That(sceneASp, Is.Not.Null); + Assert.That(sceneASp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneA.RegionInfo.RegionName)); + Assert.That(sceneASp.AbsolutePosition, Is.EqualTo(preTeleportPosition)); + + // TODO: Add assertions to check correct circuit details in both scenes. + + // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera + // position instead). +// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); + + TestHelpers.DisableLogging(); + } + [Test] public void TestSameSimulatorNeighbouringRegionsTeleport() { diff --git a/OpenSim/Tests/Common/TestHelpers.cs b/OpenSim/Tests/Common/TestHelpers.cs index 6744fca..a241a3c 100644 --- a/OpenSim/Tests/Common/TestHelpers.cs +++ b/OpenSim/Tests/Common/TestHelpers.cs @@ -61,7 +61,7 @@ namespace OpenSim.Tests.Common private static Stream DisableLoggingConfigStream = new MemoryStream( Encoding.UTF8.GetBytes( - // ""))); +// "")); //""))); // "")); // ""))); -- cgit v1.1 From 6b6a00a3d593ce164d23135cb3fe570a511e1793 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 17 May 2012 01:30:50 +0100 Subject: minor: Remove redundant EstateOwner != UUID.Zero check in IsAdministrator because checking EstateOwner == user Due to an earlier check we already know that user != UUID.Zero so if EstateOwner == UUID.Zero, EstateOwner == user can never be true --- .../CoreModules/World/Permissions/PermissionsModule.cs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 7d75fad..555509c 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -450,19 +450,17 @@ namespace OpenSim.Region.CoreModules.World.Permissions } /// - /// Is the given user an administrator (in other words, a god)? + /// Is the user regarded as an administrator? /// /// /// protected bool IsAdministrator(UUID user) { - if (user == UUID.Zero) return false; - - if (m_scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero) - { - if (m_scene.RegionInfo.EstateSettings.EstateOwner == user && m_RegionOwnerIsGod) - return true; - } + if (user == UUID.Zero) + return false; + + if (m_scene.RegionInfo.EstateSettings.EstateOwner == user && m_RegionOwnerIsGod) + return true; if (IsEstateManager(user) && m_RegionManagerIsGod) return true; -- cgit v1.1 From f0c9cb8dc0eeccf2c686ff8ceacc7e1acceb543d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 17 May 2012 01:34:04 +0100 Subject: Comment out TestSameSimulatorSeparatedRegionsQueryAccessFails() regression test logging accidentally left in --- OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs | 4 ++-- OpenSim/Tests/Common/TestHelpers.cs | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index 7c76bed..a351271 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -169,7 +169,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests public void TestSameSimulatorSeparatedRegionsQueryAccessFails() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); UUID userId = TestHelpers.ParseTail(0x1); Vector3 preTeleportPosition = new Vector3(30, 31, 32); @@ -234,7 +234,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests // position instead). // Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); - TestHelpers.DisableLogging(); +// TestHelpers.DisableLogging(); } [Test] diff --git a/OpenSim/Tests/Common/TestHelpers.cs b/OpenSim/Tests/Common/TestHelpers.cs index a241a3c..d38d692 100644 --- a/OpenSim/Tests/Common/TestHelpers.cs +++ b/OpenSim/Tests/Common/TestHelpers.cs @@ -100,6 +100,12 @@ namespace OpenSim.Tests.Common /// /// Disable logging whilst running the tests. /// + /// + /// Remember, if a regression test throws an exception before completing this will not be invoked if it's at + /// the end of the test. + /// TODO: Always invoke this after every test - probably need to make all test cases inherit from a common + /// TestCase class where this can be done. + /// public static void DisableLogging() { log4net.Config.XmlConfigurator.Configure(DisableLoggingConfigStream); -- cgit v1.1 From d19fb6fb0c7983126e327b80686c25c9d7f0fcfc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 17 May 2012 03:12:31 +0100 Subject: Add regression TestSameSimulatorSeparatedRegionsCreateAgentFails() --- .../Scenes/Tests/ScenePresenceTeleportTests.cs | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index a351271..7839394 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -237,6 +237,73 @@ namespace OpenSim.Region.Framework.Scenes.Tests // TestHelpers.DisableLogging(); } + /// + /// Test teleport procedures when the target simulator returns false when queried about access. + /// + [Test] + public void TestSameSimulatorSeparatedRegionsCreateAgentFails() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID userId = TestHelpers.ParseTail(0x1); + Vector3 preTeleportPosition = new Vector3(30, 31, 32); + + EntityTransferModule etm = new EntityTransferModule(); + LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); + + IConfigSource config = new IniConfigSource(); + config.AddConfig("Modules"); + config.Configs["Modules"].Set("EntityTransferModule", etm.Name); + config.Configs["Modules"].Set("SimulationServices", lscm.Name); + + config.AddConfig("EntityTransfer"); + + // In order to run a single threaded regression test we do not want the entity transfer module waiting + // for a callback from the destination scene before removing its avatar data. + config.Configs["EntityTransfer"].Set("wait_for_callback", false); + + SceneHelpers sh = new SceneHelpers(); + TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); + TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000); + + // Shared scene modules + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); + + Vector3 teleportPosition = new Vector3(10, 11, 12); + Vector3 teleportLookAt = new Vector3(20, 21, 22); + + ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager); + sp.AbsolutePosition = preTeleportPosition; + + // Make sceneB refuse CreateAgent + sceneB.LoginsDisabled = true; + + sceneA.RequestTeleportLocation( + sp.ControllingClient, + sceneB.RegionInfo.RegionHandle, + teleportPosition, + teleportLookAt, + (uint)TeleportFlags.ViaLocation); + +// ((TestClient)sp.ControllingClient).CompleteTeleportClientSide(); + + Assert.That(sceneB.GetScenePresence(userId), Is.Null); + + ScenePresence sceneASp = sceneA.GetScenePresence(userId); + Assert.That(sceneASp, Is.Not.Null); + Assert.That(sceneASp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneA.RegionInfo.RegionName)); + Assert.That(sceneASp.AbsolutePosition, Is.EqualTo(preTeleportPosition)); + + // TODO: Add assertions to check correct circuit details in both scenes. + + // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera + // position instead). +// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); + +// TestHelpers.DisableLogging(); + } + [Test] public void TestSameSimulatorNeighbouringRegionsTeleport() { -- cgit v1.1 From c45b5a3d1cffe506b8f3d3002e186942a0d6b1b4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 17 May 2012 03:27:05 +0100 Subject: minor: improve method doc for TestSameSimulatorSeparatedRegionsCreateAgentFails() --- OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index 7839394..41bff7f 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -238,7 +238,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests } /// - /// Test teleport procedures when the target simulator returns false when queried about access. + /// Test teleport procedures when the target simulator create agent step is refused. /// [Test] public void TestSameSimulatorSeparatedRegionsCreateAgentFails() -- cgit v1.1 From 0aa7baf49a9defdd7d7355198b95abe57639bc26 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Wed, 16 May 2012 23:17:42 -0400 Subject: Fix boo-boo in OpenSim.ini.example affecting telehub sequential routing Configuration value should be "sequence" instead of "sequential" --- bin/OpenSim.ini.example | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 9b88816..9f418a4 100755 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -241,12 +241,12 @@ ;; server to send mail through. ; emailmodule = DefaultEmailModule - ;# {SpawnPointRouting} {} {Set routing method for Telehub Spawnpoints} {closest random sequential} closest + ;# {SpawnPointRouting} {} {Set routing method for Telehub Spawnpoints} {closest random sequence} closest ;; SpawnPointRouting adjusts the landing for incoming avatars. ;; "closest" will place the avatar at the SpawnPoint located in the closest ;; available spot to the destination (typically map click/landmark). ;; "random" will place the avatar on a randomly selected spawnpoint; - ;; "sequential" will place the avatar on the next sequential SpawnPoint + ;; "sequence" will place the avatar on the next sequential SpawnPoint ; SpawnPointRouting = closest [Estates] -- cgit v1.1 From 295bb3227d0c7d108d73ef7be4fd1dd59f7afc21 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Thu, 17 May 2012 00:47:19 -0400 Subject: Force the default Telehub router if no matches are found in the config. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 57 ++++++++++++------------ 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index bdcef71..0d5c218 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3939,35 +3939,6 @@ namespace OpenSim.Region.Framework.Scenes switch (m_scene.SpawnPointRouting) { - case "closest": - - float distance = 9999; - int closest = -1; - - for (int i = 0; i < spawnPoints.Length; i++) - { - Vector3 spawnPosition = spawnPoints[i].GetLocation( - telehub.AbsolutePosition, - telehub.GroupRotation - ); - Vector3 offset = spawnPosition - pos; - float d = Vector3.Mag(offset); - if (d >= distance) - continue; - ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); - if (land == null) - continue; - if (land.IsEitherBannedOrRestricted(UUID)) - continue; - distance = d; - closest = i; - } - if (closest == -1) - return; - - pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); - return; - case "random": do @@ -4019,7 +3990,35 @@ namespace OpenSim.Region.Framework.Scenes return; default: + case "closest": + + float distance = 9999; + int closest = -1; + + for (int i = 0; i < spawnPoints.Length; i++) + { + Vector3 spawnPosition = spawnPoints[i].GetLocation( + telehub.AbsolutePosition, + telehub.GroupRotation + ); + Vector3 offset = spawnPosition - pos; + float d = Vector3.Mag(offset); + if (d >= distance) + continue; + ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); + if (land == null) + continue; + if (land.IsEitherBannedOrRestricted(UUID)) + continue; + distance = d; + closest = i; + } + if (closest == -1) + return; + + pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); return; + } } } -- cgit v1.1 From 4d34763f8c90dfe87a8a5930bf05fe36b86d15df Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 17 May 2012 23:33:26 +0100 Subject: Check agent limit against root agent count rather than both root and child agents From sl docs such as http://community.secondlife.com/t5/English-Knowledge-Base/Managing-Private-Regions/ta-p/700115 agent should apply to avatars only. This makes sense from a user perspective, and also from a code perspective since child agents with no physics or actions take up a fraction of root agent resources. As such, the check is now only performed in Scene.QueryAccess() - cross and teleport check this before allowing an agent to translocate. This also removes an off-by-one error that could occur in certain circumstances on teleport when a new child agent was double counted when a pre-teleport agent update was performed. This does not affect an existing bug where limits or other QueryAccess() checks are not applied to avatars logging directly into a region. --- OpenSim/Region/Framework/Scenes/Scene.cs | 47 ++++++++++++++++-------- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 5 --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 13 ++++++- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2bf3638..3cce370 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2646,7 +2646,8 @@ namespace OpenSim.Region.Framework.Scenes if (sp == null) { m_log.DebugFormat( - "[SCENE]: Adding new child scene presence {0} to scene {1} at pos {2}", client.Name, RegionInfo.RegionName, client.StartPos); + "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", + client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); m_clientManager.Add(client); SubscribeToClientEvents(client); @@ -3905,8 +3906,7 @@ namespace OpenSim.Region.Framework.Scenes // XPTO: if this agent is not allowed here as root, always return false - // We have to wait until the viewer contacts this region after receiving EAC. - // That calls AddNewClient, which finally creates the ScenePresence + // TODO: This check should probably be in QueryAccess(). ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); if (nearestParcel == null) { @@ -3917,14 +3917,8 @@ namespace OpenSim.Region.Framework.Scenes return false; } - int num = m_sceneGraph.GetNumberOfScenePresences(); - - if (num >= RegionInfo.RegionSettings.AgentLimit) - { - if (!Permissions.IsAdministrator(cAgentData.AgentID)) - return false; - } - + // We have to wait until the viewer contacts this region after receiving EAC. + // That calls AddNewClient, which finally creates the ScenePresence ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); if (childAgentUpdate != null) @@ -3968,14 +3962,28 @@ namespace OpenSim.Region.Framework.Scenes return false; } + /// + /// Poll until the requested ScenePresence appears or we timeout. + /// + /// The scene presence is found, else null. + /// protected virtual ScenePresence WaitGetScenePresence(UUID agentID) { int ntimes = 10; - ScenePresence childAgentUpdate = null; - while ((childAgentUpdate = GetScenePresence(agentID)) == null && (ntimes-- > 0)) + ScenePresence sp = null; + while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0)) Thread.Sleep(1000); - return childAgentUpdate; + if (sp == null) + m_log.WarnFormat( + "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout", + agentID, RegionInfo.RegionName); +// else +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Found presence {0} {1} {2} in {3} after {4} waits", +// sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 10 - ntimes); + + return sp; } public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent) @@ -5177,13 +5185,22 @@ namespace OpenSim.Region.Framework.Scenes // child agent creation, thereby emulating the SL behavior. public bool QueryAccess(UUID agentID, Vector3 position, out string reason) { - int num = m_sceneGraph.GetNumberOfScenePresences(); + // FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check. + // However, the long term fix is to make sure root agent count is always accurate. + m_sceneGraph.RecalculateStats(); + + int num = m_sceneGraph.GetRootAgentCount(); if (num >= RegionInfo.RegionSettings.AgentLimit) { if (!Permissions.IsAdministrator(agentID)) { reason = "The region is full"; + + m_log.DebugFormat( + "[SCENE]: Denying presence with id {0} entry into {1} since region is at agent limit of {2}", + agentID, RegionInfo.RegionName, RegionInfo.RegionSettings.AgentLimit); + return false; } } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 4815922..ddf1550 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -779,11 +779,6 @@ namespace OpenSim.Region.Framework.Scenes return m_scenePresenceArray; } - public int GetNumberOfScenePresences() - { - return m_scenePresenceArray.Count; - } - /// /// Request a scene presence by UUID. Fast, indexed lookup. /// diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index bdcef71..558fd9c 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1169,6 +1169,12 @@ namespace OpenSim.Region.Framework.Scenes Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); m_callbackURI = null; } +// else +// { +// m_log.DebugFormat( +// "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}", +// client.Name, client.AgentId, m_scene.RegionInfo.RegionName); +// } ValidateAndSendAppearanceAndAgentData(); @@ -2508,7 +2514,7 @@ namespace OpenSim.Region.Framework.Scenes // If we are using the the cached appearance then send it out to everyone if (cachedappearance) { - m_log.DebugFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); + m_log.DebugFormat("[SCENE PRESENCE]: baked textures are in the cache for {0}", Name); // If the avatars baked textures are all in the cache, then we have a // complete appearance... send it out, if not, then we'll send it when @@ -2970,7 +2976,7 @@ namespace OpenSim.Region.Framework.Scenes public void ChildAgentDataUpdate(AgentData cAgentData) { - //m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); +// m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); if (!IsChildAgent) return; @@ -3110,6 +3116,9 @@ namespace OpenSim.Region.Framework.Scenes m_originRegionID = cAgent.RegionID; m_callbackURI = cAgent.CallbackURI; +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()", +// Name, m_scene.RegionInfo.RegionName, m_callbackURI); m_pos = cAgent.Position; m_velocity = cAgent.Velocity; -- cgit v1.1 From b18c8c8e78172abebb82491700a0b5f9f40c1d66 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 17 May 2012 23:59:43 +0100 Subject: Don't eagerly clear frame collision events when physics actors subscribe and unsubscribe from collisions, in order to avoid a race condition. Since this is done directly from ScenePresence, it can lead to a race condition with the simulator loop. There's no real point doing it anyway since the clear will be done very shortly afterwards by the simulate loop and either there are no events (for a new avatar) or events don't matter (for a departing avatar). This matches existing behaviour in OdePrim --- OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 8397eb4..1b1c44a 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -1261,14 +1261,20 @@ namespace OpenSim.Region.Physics.OdePlugin { m_requestedUpdateFrequency = ms; m_eventsubscription = ms; - CollisionEventsThisFrame.Clear(); + + // Don't clear collision event reporting here. This is called directly from scene code and so can lead + // to a race condition with the simulate loop + _parent_scene.AddCollisionEventReporting(this); } public override void UnSubscribeEvents() { CollisionEventsThisFrame.Clear(); - _parent_scene.RemoveCollisionEventReporting(this); + + // Don't clear collision event reporting here. This is called directly from scene code and so can lead + // to a race condition with the simulate loop + m_requestedUpdateFrequency = 0; m_eventsubscription = 0; } -- cgit v1.1 From 6501b1b1bb297eb5ed8a44447f771c7b73b0e905 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 18 May 2012 00:38:29 +0100 Subject: refactor: move EventQueueGet path generation into common method. Rename some local variables in line with code conventions. Add commented out EQG log lines for future use. --- .../Linden/Caps/EventQueue/EventQueueGetModule.cs | 53 ++++++++++++++-------- OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 2 +- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 1a35d22..0054619 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -235,19 +235,19 @@ namespace OpenSim.Region.ClientStack.Linden // ClientClosed(client.AgentId); // } - private void ClientClosed(UUID AgentID, Scene scene) + private void ClientClosed(UUID agentID, Scene scene) { -// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName); +// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); int count = 0; - while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5) + while (queues.ContainsKey(agentID) && queues[agentID].Count > 0 && count++ < 5) { Thread.Sleep(1000); } lock (queues) { - queues.Remove(AgentID); + queues.Remove(agentID); } List removeitems = new List(); @@ -256,7 +256,7 @@ namespace OpenSim.Region.ClientStack.Linden foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys) { // m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID); - if (ky == AgentID) + if (ky == agentID) { removeitems.Add(ky); } @@ -267,7 +267,10 @@ namespace OpenSim.Region.ClientStack.Linden UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky]; m_AvatarQueueUUIDMapping.Remove(ky); - MainServer.Instance.RemovePollServiceHTTPHandler("","/CAPS/EQG/" + eventQueueGetUuid.ToString() + "/"); + string eqgPath = GenerateEqgCapPath(eventQueueGetUuid); + MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath); + +// m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1}", eqgPath, agentID); } } @@ -281,7 +284,7 @@ namespace OpenSim.Region.ClientStack.Linden { searchval = m_QueueUUIDAvatarMapping[ky]; - if (searchval == AgentID) + if (searchval == agentID) { removeitems.Add(ky); } @@ -305,6 +308,15 @@ namespace OpenSim.Region.ClientStack.Linden //} } + /// + /// Generate an Event Queue Get handler path for the given eqg uuid. + /// + /// + private string GenerateEqgCapPath(UUID eqgUuid) + { + return string.Format("/CAPS/EQG/{0}/", eqgUuid); + } + public void OnRegisterCaps(UUID agentID, Caps caps) { // Register an event queue for the client @@ -316,8 +328,7 @@ namespace OpenSim.Region.ClientStack.Linden // Let's instantiate a Queue for this agent right now TryGetQueue(agentID); - string capsBase = "/CAPS/EQG/"; - UUID EventQueueGetUUID = UUID.Zero; + UUID eventQueueGetUUID; lock (m_AvatarQueueUUIDMapping) { @@ -325,37 +336,35 @@ namespace OpenSim.Region.ClientStack.Linden if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) { //m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); - EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; + eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; } else { - EventQueueGetUUID = UUID.Random(); + eventQueueGetUUID = UUID.Random(); //m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); } } lock (m_QueueUUIDAvatarMapping) { - if (!m_QueueUUIDAvatarMapping.ContainsKey(EventQueueGetUUID)) - m_QueueUUIDAvatarMapping.Add(EventQueueGetUUID, agentID); + if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID)) + m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID); } lock (m_AvatarQueueUUIDMapping) { if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID)) - m_AvatarQueueUUIDMapping.Add(agentID, EventQueueGetUUID); + m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); } + string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID); + // Register this as a caps handler // FIXME: Confusingly, we need to register separate as a capability so that the client is told about // EventQueueGet when it receive capability information, but then we replace the rest handler immediately // afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but // really it should be possible to directly register the poll handler as a capability. - caps.RegisterHandler( - "EventQueueGet", - new RestHTTPHandler( - "POST", capsBase + EventQueueGetUUID.ToString() + "/", null)); - + caps.RegisterHandler("EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null)); // delegate(Hashtable m_dhttpMethod) // { // return ProcessQueue(m_dhttpMethod, agentID, caps); @@ -364,9 +373,13 @@ namespace OpenSim.Region.ClientStack.Linden // This will persist this beyond the expiry of the caps handlers // TODO: Add EventQueueGet name/description for diagnostics MainServer.Instance.AddPollServiceHTTPHandler( - capsBase + EventQueueGetUUID.ToString() + "/", + eventQueueGetPath, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); +// m_log.DebugFormat( +// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", +// eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName); + Random rnd = new Random(Environment.TickCount); lock (m_ids) { diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 1b1c44a..54b69a2 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -1274,7 +1274,7 @@ namespace OpenSim.Region.Physics.OdePlugin // Don't clear collision event reporting here. This is called directly from scene code and so can lead // to a race condition with the simulate loop - + m_requestedUpdateFrequency = 0; m_eventsubscription = 0; } -- cgit v1.1 From 565c73751cd1ac9b09393a0801591ced04d7e635 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 18 May 2012 00:49:39 +0100 Subject: Invoke log4net configurator in pCampBot.exe in order to get OpenSim sylte logging --- OpenSim/Tools/pCampBot/pCampBot.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenSim/Tools/pCampBot/pCampBot.cs b/OpenSim/Tools/pCampBot/pCampBot.cs index 52e7501..9e82577 100644 --- a/OpenSim/Tools/pCampBot/pCampBot.cs +++ b/OpenSim/Tools/pCampBot/pCampBot.cs @@ -29,6 +29,7 @@ using System; using System.Reflection; using System.Threading; using log4net; +using log4net.Config; using Nini.Config; using OpenSim.Framework; using OpenSim.Framework.Console; @@ -52,6 +53,8 @@ namespace pCampBot [STAThread] public static void Main(string[] args) { + XmlConfigurator.Configure(); + IConfig config = ParseConfig(args); if (config.Get("help") != null || config.Get("loginuri") == null) { -- cgit v1.1 From 45af29291acd22700d9fc4c442655d2e3f19a0b0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 18 May 2012 03:43:36 +0100 Subject: Add level 2 debug eq logging which logs event queue polls. Refactor: eq message logging into common method. --- .../Linden/Caps/EventQueue/EventQueueGetModule.cs | 55 +++++++++++++--------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 0054619..6ac19cc 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -109,10 +109,11 @@ namespace OpenSim.Region.ClientStack.Linden "Comms", false, "debug eq", - "debug eq [0|1]", - "Turn on event queue debugging", - "debug eq 1 will turn on event queue debugging. This will log all outgoing event queue messages to clients.\n" - + "debug eq 0 will turn off event queue debugging.", + "debug eq [0|1|2]", + "Turn on event queue debugging", + "<= 0 - turns off all event queue logging", + ">= 1 - turns on outgoing event logging", + ">= 2 - turns on poll notification", HandleDebugEq); } else @@ -270,7 +271,9 @@ namespace OpenSim.Region.ClientStack.Linden string eqgPath = GenerateEqgCapPath(eventQueueGetUuid); MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath); -// m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1}", eqgPath, agentID); + m_log.DebugFormat( + "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}", + eqgPath, agentID, m_scene.RegionInfo.RegionName); } } @@ -376,9 +379,9 @@ namespace OpenSim.Region.ClientStack.Linden eventQueueGetPath, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); -// m_log.DebugFormat( -// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", -// eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName); + m_log.DebugFormat( + "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", + eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName); Random rnd = new Random(Environment.TickCount); lock (m_ids) @@ -401,9 +404,25 @@ namespace OpenSim.Region.ClientStack.Linden return false; } + /// + /// Logs a debug line for an outbound event queue message if appropriate. + /// + /// Element containing message + private void LogOutboundDebugMessage(OSD element, UUID agentId) + { + if (element is OSDMap) + { + OSDMap ev = (OSDMap)element; + m_log.DebugFormat( + "Eq OUT {0,-30} to {1,-20} {2,-20}", + ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.RegionInfo.RegionName); + } + } + public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request) { -// m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Invoked GetEvents() for {0}", pAgentId); + if (DebugLevel >= 2) + m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName); Queue queue = TryGetQueue(pAgentId); OSD element; @@ -427,13 +446,8 @@ namespace OpenSim.Region.ClientStack.Linden } else { - if (DebugLevel > 0 && element is OSDMap) - { - OSDMap ev = (OSDMap)element; - m_log.DebugFormat( - "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}", - ev["message"], m_scene.GetScenePresence(pAgentId).Name); - } + if (DebugLevel > 0) + LogOutboundDebugMessage(element, pAgentId); array.Add(element); @@ -443,13 +457,8 @@ namespace OpenSim.Region.ClientStack.Linden { element = queue.Dequeue(); - if (DebugLevel > 0 && element is OSDMap) - { - OSDMap ev = (OSDMap)element; - m_log.DebugFormat( - "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}", - ev["message"], m_scene.GetScenePresence(pAgentId).Name); - } + if (DebugLevel > 0) + LogOutboundDebugMessage(element, pAgentId); array.Add(element); thisID++; -- cgit v1.1 From 90722875e8518a6679441b0225ae2f11245bcfe0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 18 May 2012 03:44:31 +0100 Subject: Add millisecond logging to pCampBot for debugging purposes --- bin/pCampBot.exe.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/pCampBot.exe.config b/bin/pCampBot.exe.config index 3f19ee8..9cfb7e9 100644 --- a/bin/pCampBot.exe.config +++ b/bin/pCampBot.exe.config @@ -8,7 +8,7 @@ - + -- cgit v1.1 From 0147dc63028e2d77a568c6d9d5af1c9f05286f62 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 18 May 2012 03:50:23 +0100 Subject: Fix build break. Comment out EQG deregister/register logging. --- .../Linden/Caps/EventQueue/EventQueueGetModule.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 6ac19cc..ae759ca 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -110,10 +110,10 @@ namespace OpenSim.Region.ClientStack.Linden false, "debug eq", "debug eq [0|1|2]", - "Turn on event queue debugging", - "<= 0 - turns off all event queue logging", - ">= 1 - turns on outgoing event logging", - ">= 2 - turns on poll notification", + "Turn on event queue debugging" + + "<= 0 - turns off all event queue logging" + + ">= 1 - turns on outgoing event logging" + + ">= 2 - turns on poll notification", HandleDebugEq); } else @@ -271,9 +271,9 @@ namespace OpenSim.Region.ClientStack.Linden string eqgPath = GenerateEqgCapPath(eventQueueGetUuid); MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath); - m_log.DebugFormat( - "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}", - eqgPath, agentID, m_scene.RegionInfo.RegionName); +// m_log.DebugFormat( +// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}", +// eqgPath, agentID, m_scene.RegionInfo.RegionName); } } @@ -379,9 +379,9 @@ namespace OpenSim.Region.ClientStack.Linden eventQueueGetPath, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); - m_log.DebugFormat( - "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", - eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName); +// m_log.DebugFormat( +// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", +// eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName); Random rnd = new Random(Environment.TickCount); lock (m_ids) -- cgit v1.1 From c05f87b50c32c08818c291c76e46cb558083d35d Mon Sep 17 00:00:00 2001 From: BlueWall Date: Fri, 18 May 2012 17:47:00 -0400 Subject: Provide Telehub setting to allow use of landmarks Setting to allow use of landmarks to override telehub routing. Default is off. --- OpenSim/Region/Framework/Scenes/Scene.cs | 7 +++++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3 ++- bin/OpenSim.ini.example | 5 +++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 3cce370..d09b895 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -577,6 +577,12 @@ namespace OpenSim.Region.Framework.Scenes { get { return m_SpawnPointRouting; } } + // allow landmarks to pass + private bool m_TelehubAllowLandmarks; + public bool TelehubAllowLandmarks + { + get { return m_TelehubAllowLandmarks; } + } #endregion Properties @@ -733,6 +739,7 @@ namespace OpenSim.Region.Framework.Scenes m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); m_SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); + m_TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); IConfig packetConfig = m_config.Configs["PacketPool"]; if (packetConfig != null) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0c66e49..6022175 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3929,7 +3929,8 @@ namespace OpenSim.Region.Framework.Scenes { if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) || - (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 || + // (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 || + (m_scene.TelehubAllowLandmarks == true ? false : ((m_teleportFlags & TeleportFlags.ViaLandmark) != 0 )) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0) { diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 9f418a4..aa29c07 100755 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -249,6 +249,11 @@ ;; "sequence" will place the avatar on the next sequential SpawnPoint ; SpawnPointRouting = closest + ;# {TelehubAllowLandmark} {} {Allow users with landmarks to override telehub routing} {true false} false + ;; TelehubAllowLandmark allows users with landmarks to override telehub routing and land at the landmark coordinates when set to true + ;; default is false + ; TelehubAllowLandmark = false + [Estates] ; If these values are commented out then the user will be asked for estate details when required (this is the normal case). ; If these values are uncommented then they will be used to create a default estate as necessary. -- cgit v1.1 From 896cd459391809d2fb140fe345c78f8b952232d8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 18 May 2012 23:55:18 +0100 Subject: Fix issue where a new outfit folder is not created when a new outfit is saved if there are no previous outfits This was because AddFolder() was disallowing these though they are legal. --- OpenSim/Services/InventoryService/XInventoryService.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 15156d0..eed88bd 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -307,14 +307,20 @@ namespace OpenSim.Services.InventoryService if (check != null) return false; - if (folder.Type == (short)AssetType.Folder || folder.Type == (short)AssetType.Unknown || - GetFolderForType(folder.Owner, (AssetType)(folder.Type)) == null) + if (folder.Type == (short)AssetType.Folder + || folder.Type == (short)AssetType.Unknown + || folder.Type == (short)AssetType.OutfitFolder + || GetFolderForType(folder.Owner, (AssetType)(folder.Type)) == null) { XInventoryFolder xFolder = ConvertFromOpenSim(folder); return m_Database.StoreFolder(xFolder); } else - m_log.DebugFormat("[XINVENTORY]: Folder {0} of type {1} already exists", folder.Name, folder.Type); + { + m_log.WarnFormat( + "[XINVENTORY]: Folder of type {0} already exists when tried to add {1} to {2} for {3}", + folder.Type, folder.Name, folder.ParentID, folder.Owner); + } return false; } -- cgit v1.1 From 9fa0577c7e4e710a5751c01b568b6453d513558e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 19 May 2012 00:00:52 +0100 Subject: Enable FetchInventoryDescendents2 and FetchInventory2 caps by default. This appears to be required now for LL 3.3.1 to work properly. Without this, LL 3.3.1 continually pushes LLInventoryModelFetchDescendentsResponder::error 499 to its log. This cap will be ignored by older viewers - UDP inventory will work normally. --- bin/OpenSimDefaults.ini | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index cb9ef22..7962ef8 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -601,13 +601,12 @@ Cap_ViewerStartAuction = "" Cap_ViewerStats = "" - ; The various fetch inventory caps are supported by OpenSim, but may - ; lead to poor sim performance if served by the simulators, - ; so they are currently disabled by default. + ; Capabilities for fetching inventory over HTTP rather than UDP ; FetchInventoryDescendents2 and FetchInventory2 are the ones used in the latest Linden Lab viewers (from some point in the v2 series and above) + ; It appears that Linden Lab viewer 3.3.1 onwards will not work properly if FetchInventoryDescendents2 and FetchInventory2 are not enabled Cap_WebFetchInventoryDescendents = "" - Cap_FetchInventoryDescendents2 = "" - Cap_FetchInventory2 = "" + Cap_FetchInventoryDescendents2 = "localhost" + Cap_FetchInventory2 = "localhost" [Chat] -- cgit v1.1 From 895dadbdbdc0468fd1a0a9e146e1bf65279a2de7 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Fri, 18 May 2012 19:32:26 -0400 Subject: Cleanup + change properties to set fields with private set : Thanks Justin for the tip. --- OpenSim/Region/Framework/Scenes/Scene.cs | 6 ++++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d09b895..29eed67 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -576,12 +576,14 @@ namespace OpenSim.Region.Framework.Scenes public string SpawnPointRouting { get { return m_SpawnPointRouting; } + private set { m_SpawnPointRouting = value; } } // allow landmarks to pass private bool m_TelehubAllowLandmarks; public bool TelehubAllowLandmarks { get { return m_TelehubAllowLandmarks; } + private set { m_TelehubAllowLandmarks = value; } } #endregion Properties @@ -738,8 +740,8 @@ namespace OpenSim.Region.Framework.Scenes m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); - m_SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); - m_TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); + SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); + TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); IConfig packetConfig = m_config.Configs["PacketPool"]; if (packetConfig != null) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 6022175..3adafc1 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3929,7 +3929,6 @@ namespace OpenSim.Region.Framework.Scenes { if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) || - // (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 || (m_scene.TelehubAllowLandmarks == true ? false : ((m_teleportFlags & TeleportFlags.ViaLandmark) != 0 )) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0) -- cgit v1.1 From 247a56593fe132e6412612248ceaacaf324c50d8 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Fri, 18 May 2012 19:56:46 -0400 Subject: Further refinement on properties --- OpenSim/Region/Framework/Scenes/Scene.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 29eed67..5a0f564 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -569,21 +569,18 @@ namespace OpenSim.Region.Framework.Scenes get { return m_sceneGraph.Entities; } } - // can be closest/random/sequence - private string m_SpawnPointRouting = "closest"; + // used in sequence see: SpawnPoint() private int m_SpawnPoint; + // can be closest/random/sequence public string SpawnPointRouting { - get { return m_SpawnPointRouting; } - private set { m_SpawnPointRouting = value; } + get; private set; } // allow landmarks to pass - private bool m_TelehubAllowLandmarks; public bool TelehubAllowLandmarks { - get { return m_TelehubAllowLandmarks; } - private set { m_TelehubAllowLandmarks = value; } + get; private set; } #endregion Properties -- cgit v1.1 From 2b60a5c5d64f38caf243119105416c1101c6eb6c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 19 May 2012 02:45:17 +0100 Subject: Add is_megaregion flag into oar control file. Not currently read - for future use. Please do not rely on this remaining here. An adaptation of part of Garmin's patch from http://opensimulator.org/mantis/view.php?id=5975, thanks! Flag only written if the SW corner OAR is saved - this is the only one that captures object data presently (though not land or terrain data). This adds an IRegionCombinerModule interface and the necessary methods on RegionCombinerModule --- .../Archiver/ArchiveWriteRequestPreparation.cs | 95 ++++++++++++++-------- .../CoreModules/World/Archiver/ArchiverModule.cs | 20 +++-- .../Framework/Interfaces/IRegionCombinerModule.cs | 51 ++++++++++++ .../RegionCombinerModule/RegionCombinerModule.cs | 22 ++++- 4 files changed, 145 insertions(+), 43 deletions(-) create mode 100644 OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index 5679ad5..838b741 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -67,7 +67,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// Determine whether this archive will save assets. Default is true. /// public bool SaveAssets { get; set; } - + + protected ArchiverModule m_module; protected Scene m_scene; protected Stream m_saveStream; protected Guid m_requestId; @@ -75,13 +76,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// /// Constructor /// - /// + /// Calling module /// The path to which to save data. /// The id associated with this request /// /// If there was a problem opening a stream for the file specified by the savePath /// - public ArchiveWriteRequestPreparation(Scene scene, string savePath, Guid requestId) : this(scene, requestId) + public ArchiveWriteRequestPreparation(ArchiverModule module, string savePath, Guid requestId) : this(module, requestId) { try { @@ -99,17 +100,23 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// /// Constructor. /// - /// + /// Calling module /// The stream to which to save data. /// The id associated with this request - public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, Guid requestId) : this(scene, requestId) + public ArchiveWriteRequestPreparation(ArchiverModule module, Stream saveStream, Guid requestId) : this(module, requestId) { m_saveStream = saveStream; } - protected ArchiveWriteRequestPreparation(Scene scene, Guid requestId) + protected ArchiveWriteRequestPreparation(ArchiverModule module, Guid requestId) { - m_scene = scene; + m_module = module; + + // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix + // this. + if (m_module != null) + m_scene = m_module.Scene; + m_requestId = requestId; SaveAssets = true; @@ -364,32 +371,56 @@ namespace OpenSim.Region.CoreModules.World.Archiver //if (majorVersion == 1) //{ // m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR"); - //} + //} + + String s; - StringWriter sw = new StringWriter(); - XmlTextWriter xtw = new XmlTextWriter(sw); - xtw.Formatting = Formatting.Indented; - xtw.WriteStartDocument(); - xtw.WriteStartElement("archive"); - xtw.WriteAttributeString("major_version", majorVersion.ToString()); - xtw.WriteAttributeString("minor_version", minorVersion.ToString()); - - xtw.WriteStartElement("creation_info"); - DateTime now = DateTime.UtcNow; - TimeSpan t = now - new DateTime(1970, 1, 1); - xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString()); - xtw.WriteElementString("id", UUID.Random().ToString()); - xtw.WriteEndElement(); - - xtw.WriteElementString("assets_included", SaveAssets.ToString()); - - xtw.WriteEndElement(); - - xtw.Flush(); - xtw.Close(); - - String s = sw.ToString(); - sw.Close(); + using (StringWriter sw = new StringWriter()) + { + using (XmlTextWriter xtw = new XmlTextWriter(sw)) + { + xtw.Formatting = Formatting.Indented; + xtw.WriteStartDocument(); + xtw.WriteStartElement("archive"); + xtw.WriteAttributeString("major_version", majorVersion.ToString()); + xtw.WriteAttributeString("minor_version", minorVersion.ToString()); + + xtw.WriteStartElement("creation_info"); + DateTime now = DateTime.UtcNow; + TimeSpan t = now - new DateTime(1970, 1, 1); + xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString()); + xtw.WriteElementString("id", UUID.Random().ToString()); + xtw.WriteEndElement(); + + xtw.WriteElementString("assets_included", SaveAssets.ToString()); + + bool isMegaregion; + + // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix + // this, possibly by doing control file creation somewhere else. + if (m_module != null && m_module.RegionCombinerModule != null) + { + IRegionCombinerModule mod = m_module.RegionCombinerModule; + isMegaregion = mod.IsMegaregion && mod.IsRootRegion(m_scene.RegionInfo.RegionID); + } + else + { + isMegaregion = false; + } + + xtw.WriteElementString("is_megaregion", isMegaregion.ToString()); + + xtw.WriteEndElement(); + + xtw.Flush(); + xtw.Close(); + } + + s = sw.ToString(); + } + +// Console.WriteLine( +// "[ARCHIVE WRITE REQUEST PREPARATION]: Control file for {0} is: {1}", m_scene.RegionInfo.RegionName, s); return s; } diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs index f5a5a8d..bf3b124 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs @@ -45,7 +45,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private Scene m_scene; + public Scene Scene { get; private set; } + public IRegionCombinerModule RegionCombinerModule { get; private set; } /// /// The file used to load and save an opensimulator archive if no filename has been specified @@ -70,13 +71,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void AddRegion(Scene scene) { - m_scene = scene; - m_scene.RegisterModuleInterface(this); + Scene = scene; + Scene.RegisterModuleInterface(this); //m_log.DebugFormat("[ARCHIVER]: Enabled for region {0}", scene.RegionInfo.RegionName); } public void RegionLoaded(Scene scene) { + RegionCombinerModule = scene.RequestModuleInterface(); } public void RemoveRegion(Scene scene) @@ -165,9 +167,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void ArchiveRegion(string savePath, Guid requestId, Dictionary options) { m_log.InfoFormat( - "[ARCHIVER]: Writing archive for region {0} to {1}", m_scene.RegionInfo.RegionName, savePath); + "[ARCHIVER]: Writing archive for region {0} to {1}", Scene.RegionInfo.RegionName, savePath); - new ArchiveWriteRequestPreparation(m_scene, savePath, requestId).ArchiveRegion(options); + new ArchiveWriteRequestPreparation(this, savePath, requestId).ArchiveRegion(options); } public void ArchiveRegion(Stream saveStream) @@ -182,7 +184,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary options) { - new ArchiveWriteRequestPreparation(m_scene, saveStream, requestId).ArchiveRegion(options); + new ArchiveWriteRequestPreparation(this, saveStream, requestId).ArchiveRegion(options); } public void DearchiveRegion(string loadPath) @@ -193,9 +195,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void DearchiveRegion(string loadPath, bool merge, bool skipAssets, Guid requestId) { m_log.InfoFormat( - "[ARCHIVER]: Loading archive to region {0} from {1}", m_scene.RegionInfo.RegionName, loadPath); + "[ARCHIVER]: Loading archive to region {0} from {1}", Scene.RegionInfo.RegionName, loadPath); - new ArchiveReadRequest(m_scene, loadPath, merge, skipAssets, requestId).DearchiveRegion(); + new ArchiveReadRequest(Scene, loadPath, merge, skipAssets, requestId).DearchiveRegion(); } public void DearchiveRegion(Stream loadStream) @@ -205,7 +207,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void DearchiveRegion(Stream loadStream, bool merge, bool skipAssets, Guid requestId) { - new ArchiveReadRequest(m_scene, loadStream, merge, skipAssets, requestId).DearchiveRegion(); + new ArchiveReadRequest(Scene, loadStream, merge, skipAssets, requestId).DearchiveRegion(); } } } diff --git a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs new file mode 100644 index 0000000..30e49b1 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs @@ -0,0 +1,51 @@ +/* + * 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.Linq; +using System.Text; +using OpenSim.Region.Framework.Scenes; +using System.IO; +using OpenMetaverse; + +namespace OpenSim.Region.Framework.Interfaces +{ + public interface IRegionCombinerModule + { + /// + /// Is this simulator hosting a megaregion? + /// + /// + bool IsMegaregion { get; } + + /// + /// Does the given id belong to the root region of the megaregion? + /// + bool IsRootRegion(UUID sceneId); + } +} \ No newline at end of file diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index a142f26..37b3037 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -43,9 +43,8 @@ using Mono.Addins; [assembly: AddinDependency("OpenSim", "0.5")] namespace OpenSim.Region.RegionCombinerModule { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class RegionCombinerModule : ISharedRegionModule + public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -59,6 +58,15 @@ namespace OpenSim.Region.RegionCombinerModule get { return null; } } + public bool IsMegaregion + { + get + { + lock (m_startingScenes) + return m_startingScenes.Count > 1; + } + } + private Dictionary m_regions = new Dictionary(); private bool enabledYN = false; private Dictionary m_startingScenes = new Dictionary(); @@ -69,9 +77,11 @@ namespace OpenSim.Region.RegionCombinerModule enabledYN = myConfig.GetBoolean("CombineContiguousRegions", false); if (enabledYN) + { MainConsole.Instance.Commands.AddCommand( "RegionCombinerModule", false, "fix-phantoms", "fix-phantoms", "Fixes phantom objects after an import to megaregions", FixPhantoms); + } } public void Close() @@ -80,6 +90,8 @@ namespace OpenSim.Region.RegionCombinerModule public void AddRegion(Scene scene) { + if (enabledYN) + scene.RegisterModuleInterface(this); } public void RemoveRegion(Scene scene) @@ -96,6 +108,12 @@ namespace OpenSim.Region.RegionCombinerModule } } + public bool IsRootRegion(UUID sceneId) + { + lock (m_regions) + return m_regions.ContainsKey(sceneId); + } + private void NewPresence(ScenePresence presence) { if (presence.IsChildAgent) -- cgit v1.1 From 26dfcf5395474041e6719da20d7ecb847dd0ee38 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 19 May 2012 03:07:24 +0100 Subject: Add some method doc to RegionCombinerModule. Clean up log messages. --- .../RegionCombinerModule/RegionCombinerModule.cs | 39 ++++++++++++++++------ 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 37b3037..3af5cc2 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -67,8 +67,22 @@ namespace OpenSim.Region.RegionCombinerModule } } + /// + /// This holds the root regions for the megaregions. + /// + /// + /// At this point we can actually assume there is only ever one megaregion (and hence only one entry here). + /// private Dictionary m_regions = new Dictionary(); + + /// + /// Is this module enabled? + /// private bool enabledYN = false; + + /// + /// The scenes that comprise the megaregion. + /// private Dictionary m_startingScenes = new Dictionary(); public void Initialise(IConfigSource source) @@ -448,9 +462,9 @@ namespace OpenSim.Region.RegionCombinerModule if (!connectedYN) { DoWorkForRootRegion(regionConnections, scene); - } } + // Set up infinite borders around the entire AABB of the combined ConnectedRegions AdjustLargeRegionBounds(); } @@ -469,9 +483,10 @@ namespace OpenSim.Region.RegionCombinerModule conn.UpdateExtents(extents); - m_log.DebugFormat("Scene: {0} to the west of Scene{1} Offset: {2}. Extents:{3}", - conn.RegionScene.RegionInfo.RegionName, - regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); + m_log.DebugFormat( + "[REGION COMBINER MODULE]: Scene {0} to the west of Scene {1}, Offset: {2}, Extents: {3}", + conn.RegionScene.RegionInfo.RegionName, + regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); scene.BordersLocked = true; conn.RegionScene.BordersLocked = true; @@ -547,9 +562,10 @@ namespace OpenSim.Region.RegionCombinerModule ConnectedRegion.RegionScene = scene; conn.ConnectedRegions.Add(ConnectedRegion); - m_log.DebugFormat("Scene: {0} to the northeast of Scene{1} Offset: {2}. Extents:{3}", - conn.RegionScene.RegionInfo.RegionName, - regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); + m_log.DebugFormat( + "[REGION COMBINER MODULE]: Scene: {0} to the northeast of Scene {1}, Offset: {2}, Extents: {3}", + conn.RegionScene.RegionInfo.RegionName, + regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); @@ -602,9 +618,10 @@ namespace OpenSim.Region.RegionCombinerModule conn.ConnectedRegions.Add(ConnectedRegion); - m_log.DebugFormat("Scene: {0} to the NorthEast of Scene{1} Offset: {2}. Extents:{3}", - conn.RegionScene.RegionInfo.RegionName, - regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); + m_log.DebugFormat( + "[REGION COMBINER MODULE]: Scene: {0} to the NorthEast of Scene {1}, Offset: {2}, Extents: {3}", + conn.RegionScene.RegionInfo.RegionName, + regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); @@ -681,6 +698,8 @@ namespace OpenSim.Region.RegionCombinerModule private void DoWorkForRootRegion(RegionConnections regionConnections, Scene scene) { + m_log.DebugFormat("[REGION COMBINER MODULE]: Adding root region {0}", scene.RegionInfo.RegionName); + RegionData rdata = new RegionData(); rdata.Offset = Vector3.Zero; rdata.RegionId = scene.RegionInfo.originRegionID; -- cgit v1.1 From 3f2a727b6d6b0cf6c2e2c7ef11ebd0f3f1fefa83 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 19 May 2012 03:17:21 +0100 Subject: Remove recent IRegionCombinerModule.IsMegaregion(). In theory, there can be more than one megaregion in a simulator, separated by water. Rename IsRootRegion() to IsRootForMegaregion() --- .../World/Archiver/ArchiveWriteRequestPreparation.cs | 2 +- .../Region/Framework/Interfaces/IRegionCombinerModule.cs | 10 ++-------- OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs | 13 ++----------- 3 files changed, 5 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index 838b741..e54774b 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -401,7 +401,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver if (m_module != null && m_module.RegionCombinerModule != null) { IRegionCombinerModule mod = m_module.RegionCombinerModule; - isMegaregion = mod.IsMegaregion && mod.IsRootRegion(m_scene.RegionInfo.RegionID); + isMegaregion = mod.IsRootForMegaregion(m_scene.RegionInfo.RegionID); } else { diff --git a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs index 30e49b1..ca4ed5c 100644 --- a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs @@ -38,14 +38,8 @@ namespace OpenSim.Region.Framework.Interfaces public interface IRegionCombinerModule { /// - /// Is this simulator hosting a megaregion? + /// Does the given id belong to the root region of a megaregion? /// - /// - bool IsMegaregion { get; } - - /// - /// Does the given id belong to the root region of the megaregion? - /// - bool IsRootRegion(UUID sceneId); + bool IsRootForMegaregion(UUID sceneId); } } \ No newline at end of file diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 3af5cc2..fadc30d 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -58,20 +58,11 @@ namespace OpenSim.Region.RegionCombinerModule get { return null; } } - public bool IsMegaregion - { - get - { - lock (m_startingScenes) - return m_startingScenes.Count > 1; - } - } - /// /// This holds the root regions for the megaregions. /// /// - /// At this point we can actually assume there is only ever one megaregion (and hence only one entry here). + /// Usually there is only ever one megaregion (and hence only one entry here). /// private Dictionary m_regions = new Dictionary(); @@ -122,7 +113,7 @@ namespace OpenSim.Region.RegionCombinerModule } } - public bool IsRootRegion(UUID sceneId) + public bool IsRootForMegaregion(UUID sceneId) { lock (m_regions) return m_regions.ContainsKey(sceneId); -- cgit v1.1 From 4e5ac27928f0bdcb5bd7c772dbdcdd049d6ab4c4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 19 May 2012 03:45:58 +0100 Subject: Make the megaregion total area given to the physics module accurate instead of over-inflated. This was previously over-inflated because adding a region to the NE of the root region resulted in double counting of regions already added. An accurate extent will also be necessary for other purposes. --- OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index fadc30d..a2050b2 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -595,9 +595,15 @@ namespace OpenSim.Region.RegionCombinerModule ((conn.Y * (int)Constants.RegionSize))); Vector3 extents = Vector3.Zero; - extents.Y = regionConnections.YEnd + conn.YEnd; - extents.X = regionConnections.XEnd + conn.XEnd; - conn.UpdateExtents(extents); + + // We do not want to inflate the extents for regions strictly to the NE of the root region, since this + // would double count regions strictly to the north and east that have already been added. +// extents.Y = regionConnections.YEnd + conn.YEnd; +// extents.X = regionConnections.XEnd + conn.XEnd; +// conn.UpdateExtents(extents); + + extents.Y = conn.YEnd; + extents.X = conn.XEnd; scene.BordersLocked = true; conn.RegionScene.BordersLocked = true; -- cgit v1.1 From d7f90dee1ce0bd84200f327ce3f62697c876ef5b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 19 May 2012 03:56:25 +0100 Subject: Correct some log messages in RegionCombinerModule about the position of the root region of a megaregion relative to an added region --- OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index a2050b2..95db22b 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -229,8 +229,6 @@ namespace OpenSim.Region.RegionCombinerModule westBorder.CrossDirection = Cardinals.W; scene.WestBorders[0] = westBorder; - - RegionConnections regionConnections = new RegionConnections(); regionConnections.ConnectedRegions = new List(); regionConnections.RegionScene = scene; @@ -475,7 +473,7 @@ namespace OpenSim.Region.RegionCombinerModule conn.UpdateExtents(extents); m_log.DebugFormat( - "[REGION COMBINER MODULE]: Scene {0} to the west of Scene {1}, Offset: {2}, Extents: {3}", + "[REGION COMBINER MODULE]: Root region {0} is to the west of region {1}, Offset: {2}, Extents: {3}", conn.RegionScene.RegionInfo.RegionName, regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); @@ -554,7 +552,7 @@ namespace OpenSim.Region.RegionCombinerModule conn.ConnectedRegions.Add(ConnectedRegion); m_log.DebugFormat( - "[REGION COMBINER MODULE]: Scene: {0} to the northeast of Scene {1}, Offset: {2}, Extents: {3}", + "[REGION COMBINER MODULE]: Root region {0} is to the south of region {1}, Offset: {2}, Extents: {3}", conn.RegionScene.RegionInfo.RegionName, regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); @@ -616,7 +614,7 @@ namespace OpenSim.Region.RegionCombinerModule conn.ConnectedRegions.Add(ConnectedRegion); m_log.DebugFormat( - "[REGION COMBINER MODULE]: Scene: {0} to the NorthEast of Scene {1}, Offset: {2}, Extents: {3}", + "[REGION COMBINER MODULE]: Region {0} is to the southwest of Scene {1}, Offset: {2}, Extents: {3}", conn.RegionScene.RegionInfo.RegionName, regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); -- cgit v1.1 From fb8705dd4de2dc28b283b105f21c56e2ca9d89ff Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 19 May 2012 04:01:05 +0100 Subject: refactor: Rename connection paramaters from "conn" and "regionConnections" so that it's easy to tell whether they refer to the root region connection or a new region connection --- .../RegionCombinerModule/RegionCombinerModule.cs | 260 +++++++++++---------- 1 file changed, 133 insertions(+), 127 deletions(-) diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 95db22b..b3750ca 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -229,22 +229,21 @@ namespace OpenSim.Region.RegionCombinerModule westBorder.CrossDirection = Cardinals.W; scene.WestBorders[0] = westBorder; - RegionConnections regionConnections = new RegionConnections(); - regionConnections.ConnectedRegions = new List(); - regionConnections.RegionScene = scene; - regionConnections.RegionLandChannel = scene.LandChannel; - regionConnections.RegionId = scene.RegionInfo.originRegionID; - regionConnections.X = scene.RegionInfo.RegionLocX; - regionConnections.Y = scene.RegionInfo.RegionLocY; - regionConnections.XEnd = (int)Constants.RegionSize; - regionConnections.YEnd = (int)Constants.RegionSize; - + RegionConnections newConn = new RegionConnections(); + newConn.ConnectedRegions = new List(); + newConn.RegionScene = scene; + newConn.RegionLandChannel = scene.LandChannel; + newConn.RegionId = scene.RegionInfo.originRegionID; + newConn.X = scene.RegionInfo.RegionLocX; + newConn.Y = scene.RegionInfo.RegionLocY; + newConn.XEnd = (int)Constants.RegionSize; + newConn.YEnd = (int)Constants.RegionSize; lock (m_regions) { bool connectedYN = false; - foreach (RegionConnections conn in m_regions.Values) + foreach (RegionConnections rootConn in m_regions.Values) { #region commented /* @@ -410,12 +409,12 @@ namespace OpenSim.Region.RegionCombinerModule //xxx - if ((((int)conn.X * (int)Constants.RegionSize) + conn.XEnd - >= (regionConnections.X * (int)Constants.RegionSize)) - && (((int)conn.Y * (int)Constants.RegionSize) - >= (regionConnections.Y * (int)Constants.RegionSize))) + if ((((int)rootConn.X * (int)Constants.RegionSize) + rootConn.XEnd + >= (newConn.X * (int)Constants.RegionSize)) + && (((int)rootConn.Y * (int)Constants.RegionSize) + >= (newConn.Y * (int)Constants.RegionSize))) { - connectedYN = DoWorkForOneRegionOverPlusXY(conn, regionConnections, scene); + connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene); break; } @@ -423,12 +422,12 @@ namespace OpenSim.Region.RegionCombinerModule //xyx //xxx //xxx - if ((((int)conn.X * (int)Constants.RegionSize) - >= (regionConnections.X * (int)Constants.RegionSize)) - && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd - >= (regionConnections.Y * (int)Constants.RegionSize))) + if ((((int)rootConn.X * (int)Constants.RegionSize) + >= (newConn.X * (int)Constants.RegionSize)) + && (((int)rootConn.Y * (int)Constants.RegionSize) + rootConn.YEnd + >= (newConn.Y * (int)Constants.RegionSize))) { - connectedYN = DoWorkForOneRegionOverXPlusY(conn, regionConnections, scene); + connectedYN = DoWorkForOneRegionOverXPlusY(rootConn, newConn, scene); break; } @@ -436,12 +435,12 @@ namespace OpenSim.Region.RegionCombinerModule //xxy //xxx //xxx - if ((((int)conn.X * (int)Constants.RegionSize) + conn.XEnd - >= (regionConnections.X * (int)Constants.RegionSize)) - && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd - >= (regionConnections.Y * (int)Constants.RegionSize))) + if ((((int)rootConn.X * (int)Constants.RegionSize) + rootConn.XEnd + >= (newConn.X * (int)Constants.RegionSize)) + && (((int)rootConn.Y * (int)Constants.RegionSize) + rootConn.YEnd + >= (newConn.Y * (int)Constants.RegionSize))) { - connectedYN = DoWorkForOneRegionOverPlusXPlusY(conn, regionConnections, scene); + connectedYN = DoWorkForOneRegionOverPlusXPlusY(rootConn, newConn, scene); break; } @@ -450,7 +449,7 @@ namespace OpenSim.Region.RegionCombinerModule // If !connectYN means that this region is a root region if (!connectedYN) { - DoWorkForRootRegion(regionConnections, scene); + DoWorkForRootRegion(newConn, scene); } } @@ -458,59 +457,57 @@ namespace OpenSim.Region.RegionCombinerModule AdjustLargeRegionBounds(); } - private bool DoWorkForOneRegionOverPlusXY(RegionConnections conn, RegionConnections regionConnections, Scene scene) + private bool DoWorkForOneRegionOverPlusXY(RegionConnections rootConn, RegionConnections newConn, Scene scene) { Vector3 offset = Vector3.Zero; - offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - - ((conn.X * (int)Constants.RegionSize))); - offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) - - ((conn.Y * (int)Constants.RegionSize))); + offset.X = (((newConn.X * (int)Constants.RegionSize)) - + ((rootConn.X * (int)Constants.RegionSize))); + offset.Y = (((newConn.Y * (int)Constants.RegionSize)) - + ((rootConn.Y * (int)Constants.RegionSize))); Vector3 extents = Vector3.Zero; - extents.Y = conn.YEnd; - extents.X = conn.XEnd + regionConnections.XEnd; + extents.Y = rootConn.YEnd; + extents.X = rootConn.XEnd + newConn.XEnd; - conn.UpdateExtents(extents); + rootConn.UpdateExtents(extents); m_log.DebugFormat( "[REGION COMBINER MODULE]: Root region {0} is to the west of region {1}, Offset: {2}, Extents: {3}", - conn.RegionScene.RegionInfo.RegionName, - regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); + rootConn.RegionScene.RegionInfo.RegionName, + newConn.RegionScene.RegionInfo.RegionName, offset, extents); scene.BordersLocked = true; - conn.RegionScene.BordersLocked = true; + rootConn.RegionScene.BordersLocked = true; RegionData ConnectedRegion = new RegionData(); ConnectedRegion.Offset = offset; ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; ConnectedRegion.RegionScene = scene; - conn.ConnectedRegions.Add(ConnectedRegion); + rootConn.ConnectedRegions.Add(ConnectedRegion); // Inform root region Physics about the extents of this region - conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); + rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); // Inform Child region that it needs to forward it's terrain to the root region - scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); + scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); // Extend the borders as appropriate - lock (conn.RegionScene.EastBorders) - conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; + lock (rootConn.RegionScene.EastBorders) + rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; - lock (conn.RegionScene.NorthBorders) - conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; + lock (rootConn.RegionScene.NorthBorders) + rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; - lock (conn.RegionScene.SouthBorders) - conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; + lock (rootConn.RegionScene.SouthBorders) + rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; lock (scene.WestBorders) { - - - scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - conn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West + scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West // Trigger auto teleport to root region - scene.WestBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; - scene.WestBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; + scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; + scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; } // Reset Terrain.. since terrain loads before we get here, we need to load @@ -519,57 +516,60 @@ namespace OpenSim.Region.RegionCombinerModule scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); // Unlock borders - conn.RegionScene.BordersLocked = false; + rootConn.RegionScene.BordersLocked = false; scene.BordersLocked = false; // Create a client event forwarder and add this region's events to the root region. - if (conn.ClientEventForwarder != null) - conn.ClientEventForwarder.AddSceneToEventForwarding(scene); + if (rootConn.ClientEventForwarder != null) + rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); return true; } - private bool DoWorkForOneRegionOverXPlusY(RegionConnections conn, RegionConnections regionConnections, Scene scene) + private bool DoWorkForOneRegionOverXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene) { Vector3 offset = Vector3.Zero; - offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - - ((conn.X * (int)Constants.RegionSize))); - offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) - - ((conn.Y * (int)Constants.RegionSize))); + offset.X = (((newConn.X * (int)Constants.RegionSize)) - + ((rootConn.X * (int)Constants.RegionSize))); + offset.Y = (((newConn.Y * (int)Constants.RegionSize)) - + ((rootConn.Y * (int)Constants.RegionSize))); Vector3 extents = Vector3.Zero; - extents.Y = regionConnections.YEnd + conn.YEnd; - extents.X = conn.XEnd; - conn.UpdateExtents(extents); + extents.Y = newConn.YEnd + rootConn.YEnd; + extents.X = rootConn.XEnd; + rootConn.UpdateExtents(extents); scene.BordersLocked = true; - conn.RegionScene.BordersLocked = true; + rootConn.RegionScene.BordersLocked = true; RegionData ConnectedRegion = new RegionData(); ConnectedRegion.Offset = offset; ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; ConnectedRegion.RegionScene = scene; - conn.ConnectedRegions.Add(ConnectedRegion); + rootConn.ConnectedRegions.Add(ConnectedRegion); m_log.DebugFormat( "[REGION COMBINER MODULE]: Root region {0} is to the south of region {1}, Offset: {2}, Extents: {3}", - conn.RegionScene.RegionInfo.RegionName, - regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); - - conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); - scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); - - lock (conn.RegionScene.NorthBorders) - conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; - lock (conn.RegionScene.EastBorders) - conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; - lock (conn.RegionScene.WestBorders) - conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; + rootConn.RegionScene.RegionInfo.RegionName, + newConn.RegionScene.RegionInfo.RegionName, offset, extents); + + rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); + scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); + + lock (rootConn.RegionScene.NorthBorders) + rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; + + lock (rootConn.RegionScene.EastBorders) + rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; + + lock (rootConn.RegionScene.WestBorders) + rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; + lock (scene.SouthBorders) { - scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - conn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south - scene.SouthBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; - scene.SouthBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; + scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south + scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; + scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; } // Reset Terrain.. since terrain normally loads first. @@ -578,19 +578,21 @@ namespace OpenSim.Region.RegionCombinerModule //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); scene.BordersLocked = false; - conn.RegionScene.BordersLocked = false; - if (conn.ClientEventForwarder != null) - conn.ClientEventForwarder.AddSceneToEventForwarding(scene); + rootConn.RegionScene.BordersLocked = false; + + if (rootConn.ClientEventForwarder != null) + rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); + return true; } - private bool DoWorkForOneRegionOverPlusXPlusY(RegionConnections conn, RegionConnections regionConnections, Scene scene) + private bool DoWorkForOneRegionOverPlusXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene) { Vector3 offset = Vector3.Zero; - offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - - ((conn.X * (int)Constants.RegionSize))); - offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) - - ((conn.Y * (int)Constants.RegionSize))); + offset.X = (((newConn.X * (int)Constants.RegionSize)) - + ((rootConn.X * (int)Constants.RegionSize))); + offset.Y = (((newConn.Y * (int)Constants.RegionSize)) - + ((rootConn.Y * (int)Constants.RegionSize))); Vector3 extents = Vector3.Zero; @@ -600,68 +602,70 @@ namespace OpenSim.Region.RegionCombinerModule // extents.X = regionConnections.XEnd + conn.XEnd; // conn.UpdateExtents(extents); - extents.Y = conn.YEnd; - extents.X = conn.XEnd; + extents.Y = rootConn.YEnd; + extents.X = rootConn.XEnd; scene.BordersLocked = true; - conn.RegionScene.BordersLocked = true; + rootConn.RegionScene.BordersLocked = true; RegionData ConnectedRegion = new RegionData(); ConnectedRegion.Offset = offset; ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; ConnectedRegion.RegionScene = scene; - conn.ConnectedRegions.Add(ConnectedRegion); + rootConn.ConnectedRegions.Add(ConnectedRegion); m_log.DebugFormat( "[REGION COMBINER MODULE]: Region {0} is to the southwest of Scene {1}, Offset: {2}, Extents: {3}", - conn.RegionScene.RegionInfo.RegionName, - regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); + rootConn.RegionScene.RegionInfo.RegionName, + newConn.RegionScene.RegionInfo.RegionName, offset, extents); - conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); - scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); - lock (conn.RegionScene.NorthBorders) + rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); + scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); + + lock (rootConn.RegionScene.NorthBorders) { - if (conn.RegionScene.NorthBorders.Count == 1)// && 2) + if (rootConn.RegionScene.NorthBorders.Count == 1)// && 2) { //compound border // already locked above - conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; + rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; + + lock (rootConn.RegionScene.EastBorders) + rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; - lock (conn.RegionScene.EastBorders) - conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; - lock (conn.RegionScene.WestBorders) - conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; + lock (rootConn.RegionScene.WestBorders) + rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; } } lock (scene.SouthBorders) { - scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - conn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south - scene.SouthBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; - scene.SouthBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; + scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south + scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; + scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; } - lock (conn.RegionScene.EastBorders) + lock (rootConn.RegionScene.EastBorders) { - if (conn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2) + if (rootConn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2) { - conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; - lock (conn.RegionScene.NorthBorders) - conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; - lock (conn.RegionScene.SouthBorders) - conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; + rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; + lock (rootConn.RegionScene.NorthBorders) + rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; + lock (rootConn.RegionScene.SouthBorders) + rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; } } lock (scene.WestBorders) { - scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - conn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West - scene.WestBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; - scene.WestBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; + scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West + scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; + scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; } /* @@ -680,18 +684,17 @@ namespace OpenSim.Region.RegionCombinerModule scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); scene.BordersLocked = false; - conn.RegionScene.BordersLocked = false; + rootConn.RegionScene.BordersLocked = false; - if (conn.ClientEventForwarder != null) - conn.ClientEventForwarder.AddSceneToEventForwarding(scene); + if (rootConn.ClientEventForwarder != null) + rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); return true; //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents); - } - private void DoWorkForRootRegion(RegionConnections regionConnections, Scene scene) + private void DoWorkForRootRegion(RegionConnections rootConn, Scene scene) { m_log.DebugFormat("[REGION COMBINER MODULE]: Adding root region {0}", scene.RegionInfo.RegionName); @@ -700,28 +703,31 @@ namespace OpenSim.Region.RegionCombinerModule rdata.RegionId = scene.RegionInfo.originRegionID; rdata.RegionScene = scene; // save it's land channel - regionConnections.RegionLandChannel = scene.LandChannel; + rootConn.RegionLandChannel = scene.LandChannel; // Substitue our landchannel RegionCombinerLargeLandChannel lnd = new RegionCombinerLargeLandChannel(rdata, scene.LandChannel, - regionConnections.ConnectedRegions); + rootConn.ConnectedRegions); + scene.LandChannel = lnd; + // Forward the permissions modules of each of the connected regions to the root region lock (m_regions) { - foreach (RegionData r in regionConnections.ConnectedRegions) + foreach (RegionData r in rootConn.ConnectedRegions) { - ForwardPermissionRequests(regionConnections, r.RegionScene); + ForwardPermissionRequests(rootConn, r.RegionScene); } } + // Create the root region's Client Event Forwarder - regionConnections.ClientEventForwarder = new RegionCombinerClientEventForwarder(regionConnections); + rootConn.ClientEventForwarder = new RegionCombinerClientEventForwarder(rootConn); // Sets up the CoarseLocationUpdate forwarder for this root region scene.EventManager.OnNewPresence += SetCourseLocationDelegate; // Adds this root region to a dictionary of regions that are connectable - m_regions.Add(scene.RegionInfo.originRegionID, regionConnections); + m_regions.Add(scene.RegionInfo.originRegionID, rootConn); } private void SetCourseLocationDelegate(ScenePresence presence) -- cgit v1.1 From 824a3a114b1142325f523e2039ed070cce9ea850 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 19 May 2012 04:22:30 +0100 Subject: refactor: Add RegionConnection.PosX and PosY to return position in meters rather than copy/pasting the necessary calculations in lots of places. --- .../RegionCombinerModule/RegionCombinerModule.cs | 36 ++++++--------------- .../RegionCombinerModule/RegionConnections.cs | 37 +++++++++++++++++++--- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index b3750ca..81ed339 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -408,11 +408,7 @@ namespace OpenSim.Region.RegionCombinerModule //xxy //xxx - - if ((((int)rootConn.X * (int)Constants.RegionSize) + rootConn.XEnd - >= (newConn.X * (int)Constants.RegionSize)) - && (((int)rootConn.Y * (int)Constants.RegionSize) - >= (newConn.Y * (int)Constants.RegionSize))) + if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY >= newConn.PosY) { connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene); break; @@ -422,10 +418,7 @@ namespace OpenSim.Region.RegionCombinerModule //xyx //xxx //xxx - if ((((int)rootConn.X * (int)Constants.RegionSize) - >= (newConn.X * (int)Constants.RegionSize)) - && (((int)rootConn.Y * (int)Constants.RegionSize) + rootConn.YEnd - >= (newConn.Y * (int)Constants.RegionSize))) + if (rootConn.PosX >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) { connectedYN = DoWorkForOneRegionOverXPlusY(rootConn, newConn, scene); break; @@ -435,10 +428,7 @@ namespace OpenSim.Region.RegionCombinerModule //xxy //xxx //xxx - if ((((int)rootConn.X * (int)Constants.RegionSize) + rootConn.XEnd - >= (newConn.X * (int)Constants.RegionSize)) - && (((int)rootConn.Y * (int)Constants.RegionSize) + rootConn.YEnd - >= (newConn.Y * (int)Constants.RegionSize))) + if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) { connectedYN = DoWorkForOneRegionOverPlusXPlusY(rootConn, newConn, scene); break; @@ -460,10 +450,8 @@ namespace OpenSim.Region.RegionCombinerModule private bool DoWorkForOneRegionOverPlusXY(RegionConnections rootConn, RegionConnections newConn, Scene scene) { Vector3 offset = Vector3.Zero; - offset.X = (((newConn.X * (int)Constants.RegionSize)) - - ((rootConn.X * (int)Constants.RegionSize))); - offset.Y = (((newConn.Y * (int)Constants.RegionSize)) - - ((rootConn.Y * (int)Constants.RegionSize))); + offset.X = newConn.PosX - rootConn.PosX; + offset.Y = newConn.PosY - rootConn.PosY; Vector3 extents = Vector3.Zero; extents.Y = rootConn.YEnd; @@ -529,10 +517,8 @@ namespace OpenSim.Region.RegionCombinerModule private bool DoWorkForOneRegionOverXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene) { Vector3 offset = Vector3.Zero; - offset.X = (((newConn.X * (int)Constants.RegionSize)) - - ((rootConn.X * (int)Constants.RegionSize))); - offset.Y = (((newConn.Y * (int)Constants.RegionSize)) - - ((rootConn.Y * (int)Constants.RegionSize))); + offset.X = newConn.PosX - rootConn.PosX; + offset.Y = newConn.PosY - rootConn.PosY; Vector3 extents = Vector3.Zero; extents.Y = newConn.YEnd + rootConn.YEnd; @@ -589,10 +575,8 @@ namespace OpenSim.Region.RegionCombinerModule private bool DoWorkForOneRegionOverPlusXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene) { Vector3 offset = Vector3.Zero; - offset.X = (((newConn.X * (int)Constants.RegionSize)) - - ((rootConn.X * (int)Constants.RegionSize))); - offset.Y = (((newConn.Y * (int)Constants.RegionSize)) - - ((rootConn.Y * (int)Constants.RegionSize))); + offset.X = newConn.PosX - rootConn.PosX; + offset.Y = newConn.PosY - rootConn.PosY; Vector3 extents = Vector3.Zero; @@ -622,7 +606,7 @@ namespace OpenSim.Region.RegionCombinerModule rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); - + lock (rootConn.RegionScene.NorthBorders) { if (rootConn.RegionScene.NorthBorders.Count == 1)// && 2) diff --git a/OpenSim/Region/RegionCombinerModule/RegionConnections.cs b/OpenSim/Region/RegionCombinerModule/RegionConnections.cs index 3aa9f20..fba51d2 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionConnections.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionConnections.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using OpenMetaverse; +using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -49,17 +50,45 @@ namespace OpenSim.Region.RegionCombinerModule /// LargeLandChannel for combined region /// public ILandChannel RegionLandChannel; + + /// + /// The x map co-ordinate for this region (where each co-ordinate is a Constants.RegionSize block). + /// public uint X; + + /// + /// The y co-ordinate for this region (where each cor-odinate is a Constants.RegionSize block). + /// public uint Y; - public int XEnd; - public int YEnd; + + /// + /// The X meters position of this connection. + /// + public uint PosX { get { return X * Constants.RegionSize; } } + + /// + /// The Y meters co-ordinate of this connection. + /// + public uint PosY { get { return Y * Constants.RegionSize; } } + + /// + /// The size of the megaregion in meters. + /// + public uint XEnd; + + /// + /// The size of the megaregion in meters. + /// + public uint YEnd; + public List ConnectedRegions; public RegionCombinerPermissionModule PermissionModule; public RegionCombinerClientEventForwarder ClientEventForwarder; + public void UpdateExtents(Vector3 extents) { - XEnd = (int)extents.X; - YEnd = (int)extents.Y; + XEnd = (uint)extents.X; + YEnd = (uint)extents.Y; } } } \ No newline at end of file -- cgit v1.1 From 5759313f7f3ff121d20e5eb44013e2bbb4bc2eee Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 19 May 2012 04:56:47 +0100 Subject: Add size of region to OAR control file. Megaregions (sw root OARs when saved) will have a size larger than 256x256 Not yet read. Do not rely on this information yet, it may change. --- .../Archiver/ArchiveWriteRequestPreparation.cs | 38 ++++++++++++++-------- .../Framework/Interfaces/IRegionCombinerModule.cs | 16 ++++++++- .../RegionCombinerModule/RegionCombinerModule.cs | 19 +++++++++-- 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index e54774b..504f09b 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -391,36 +391,46 @@ namespace OpenSim.Region.CoreModules.World.Archiver xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString()); xtw.WriteElementString("id", UUID.Random().ToString()); xtw.WriteEndElement(); - - xtw.WriteElementString("assets_included", SaveAssets.ToString()); - + + xtw.WriteStartElement("region_info"); + bool isMegaregion; + Vector2 size; + IRegionCombinerModule rcMod = null; // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix // this, possibly by doing control file creation somewhere else. - if (m_module != null && m_module.RegionCombinerModule != null) - { - IRegionCombinerModule mod = m_module.RegionCombinerModule; - isMegaregion = mod.IsRootForMegaregion(m_scene.RegionInfo.RegionID); - } + if (m_module != null) + rcMod = m_module.RegionCombinerModule; + + if (rcMod != null) + isMegaregion = rcMod.IsRootForMegaregion(m_scene.RegionInfo.RegionID); else - { isMegaregion = false; - } - + + if (isMegaregion) + size = rcMod.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID); + else + size = new Vector2((float)Constants.RegionSize, (float)Constants.RegionSize); + xtw.WriteElementString("is_megaregion", isMegaregion.ToString()); + xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y)); + + xtw.WriteEndElement(); + xtw.WriteElementString("assets_included", SaveAssets.ToString()); + xtw.WriteEndElement(); xtw.Flush(); - xtw.Close(); } s = sw.ToString(); } -// Console.WriteLine( -// "[ARCHIVE WRITE REQUEST PREPARATION]: Control file for {0} is: {1}", m_scene.RegionInfo.RegionName, s); + if (m_scene != null) + Console.WriteLine( + "[ARCHIVE WRITE REQUEST PREPARATION]: Control file for {0} is: {1}", m_scene.RegionInfo.RegionName, s); return s; } diff --git a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs index ca4ed5c..e03ac5a 100644 --- a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs @@ -40,6 +40,20 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Does the given id belong to the root region of a megaregion? /// - bool IsRootForMegaregion(UUID sceneId); + bool IsRootForMegaregion(UUID regionId); + + /// + /// Gets the size of megaregion. + /// + /// + /// Returns size in meters. + /// Do not rely on this method remaining the same - this area is actively under development. + /// + /// + /// The id of the root region for a megaregion. + /// This may change in the future to allow any region id that makes up a megaregion. + /// Currently, will throw an exception if this does not match a root region. + /// + Vector2 GetSizeOfMegaregion(UUID regionId); } } \ No newline at end of file diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 81ed339..98becce 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -113,10 +113,25 @@ namespace OpenSim.Region.RegionCombinerModule } } - public bool IsRootForMegaregion(UUID sceneId) + public bool IsRootForMegaregion(UUID regionId) { lock (m_regions) - return m_regions.ContainsKey(sceneId); + return m_regions.ContainsKey(regionId); + } + + public Vector2 GetSizeOfMegaregion(UUID regionId) + { + lock (m_regions) + { + if (m_regions.ContainsKey(regionId)) + { + RegionConnections rootConn = m_regions[regionId]; + + return new Vector2((float)rootConn.XEnd, (float)rootConn.YEnd); + } + } + + throw new Exception(string.Format("Region with id {0} not found", regionId)); } private void NewPresence(ScenePresence presence) -- cgit v1.1 From 0db60eea85f16b0b428190590b8e8ca1392a2e35 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 19 May 2012 04:59:36 +0100 Subject: Improve locking of RegionCombinerModule.m_regions --- .../RegionCombinerModule/RegionCombinerModule.cs | 53 ++++++++++++---------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 98becce..40daf13 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -59,6 +59,11 @@ namespace OpenSim.Region.RegionCombinerModule } /// + /// Is this module enabled? + /// + private bool enabledYN = false; + + /// /// This holds the root regions for the megaregions. /// /// @@ -67,11 +72,6 @@ namespace OpenSim.Region.RegionCombinerModule private Dictionary m_regions = new Dictionary(); /// - /// Is this module enabled? - /// - private bool enabledYN = false; - - /// /// The scenes that comprise the megaregion. /// private Dictionary m_startingScenes = new Dictionary(); @@ -717,16 +717,16 @@ namespace OpenSim.Region.RegionCombinerModule { ForwardPermissionRequests(rootConn, r.RegionScene); } - } - - // Create the root region's Client Event Forwarder - rootConn.ClientEventForwarder = new RegionCombinerClientEventForwarder(rootConn); - - // Sets up the CoarseLocationUpdate forwarder for this root region - scene.EventManager.OnNewPresence += SetCourseLocationDelegate; - // Adds this root region to a dictionary of regions that are connectable - m_regions.Add(scene.RegionInfo.originRegionID, rootConn); + // Create the root region's Client Event Forwarder + rootConn.ClientEventForwarder = new RegionCombinerClientEventForwarder(rootConn); + + // Sets up the CoarseLocationUpdate forwarder for this root region + scene.EventManager.OnNewPresence += SetCourseLocationDelegate; + + // Adds this root region to a dictionary of regions that are connectable + m_regions.Add(scene.RegionInfo.originRegionID, rootConn); + } } private void SetCourseLocationDelegate(ScenePresence presence) @@ -983,6 +983,7 @@ namespace OpenSim.Region.RegionCombinerModule return true; } } + oborder = null; return false; } @@ -992,14 +993,19 @@ namespace OpenSim.Region.RegionCombinerModule pPosition = pPosition/(int) Constants.RegionSize; int OffsetX = (int) pPosition.X; int OffsetY = (int) pPosition.Y; - foreach (RegionConnections regConn in m_regions.Values) + + lock (m_regions) { - foreach (RegionData reg in regConn.ConnectedRegions) + foreach (RegionConnections regConn in m_regions.Values) { - if (reg.Offset.X == OffsetX && reg.Offset.Y == OffsetY) - return reg; + foreach (RegionData reg in regConn.ConnectedRegions) + { + if (reg.Offset.X == OffsetX && reg.Offset.Y == OffsetY) + return reg; + } } } + return new RegionData(); } @@ -1055,18 +1061,17 @@ namespace OpenSim.Region.RegionCombinerModule } #region console commands + public void FixPhantoms(string module, string[] cmdparams) { - List scenes = new List(m_startingScenes.Values); + List scenes = new List(m_startingScenes.Values); + foreach (Scene s in scenes) { - s.ForEachSOG(delegate(SceneObjectGroup e) - { - e.AbsolutePosition = e.AbsolutePosition; - } - ); + s.ForEachSOG(so => so.AbsolutePosition = so.AbsolutePosition); } } + #endregion } } -- cgit v1.1 From 16d303f7cd631d05cba24c95546da0f7d0d6c774 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 21 May 2012 19:38:43 +0100 Subject: Fix bug where outfit folders could not be renamed. Outfit folders are a type of system folder whose details are allowed to change. --- OpenSim/Services/InventoryService/XInventoryService.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index eed88bd..2ce1bab 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -327,27 +327,36 @@ namespace OpenSim.Services.InventoryService public virtual bool UpdateFolder(InventoryFolderBase folder) { - //m_log.DebugFormat("[XINVENTORY]: Update folder {0} {1} ({2})", folder.Name, folder.Type, folder.ID); +// m_log.DebugFormat("[XINVENTORY]: Update folder {0} {1} ({2})", folder.Name, folder.Type, folder.ID); + XInventoryFolder xFolder = ConvertFromOpenSim(folder); InventoryFolderBase check = GetFolder(folder); + if (check == null) return AddFolder(folder); - if (check.Type != -1 || xFolder.type != -1) + if ((check.Type != (short)AssetType.Unknown || xFolder.type != (short)AssetType.Unknown) + && (check.Type != (short)AssetType.OutfitFolder || xFolder.type != (short)AssetType.OutfitFolder)) { if (xFolder.version < check.Version) { - //m_log.DebugFormat("[XINVENTORY]: {0} < {1} can't do", xFolder.version, check.Version); +// m_log.DebugFormat("[XINVENTORY]: {0} < {1} can't do", xFolder.version, check.Version); return false; } + check.Version = (ushort)xFolder.version; xFolder = ConvertFromOpenSim(check); - //m_log.DebugFormat("[XINVENTORY]: Storing {0} {1} {2}", xFolder.folderName, xFolder.version, xFolder.type); + +// m_log.DebugFormat( +// "[XINVENTORY]: Storing version only update to system folder {0} {1} {2}", +// xFolder.folderName, xFolder.version, xFolder.type); + return m_Database.StoreFolder(xFolder); } if (xFolder.version < check.Version) xFolder.version = check.Version; + xFolder.folderID = check.ID; return m_Database.StoreFolder(xFolder); -- cgit v1.1 From 7e97f0e8989ff1bc7fab80c726dfef23dffc5cca Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 21 May 2012 21:00:22 +0100 Subject: minor: extend commented out LinkInventoryItem log message for future use --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 10 +++++----- OpenSim/Services/InventoryService/XInventoryService.cs | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 8a26df1..79c9309 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -939,8 +939,8 @@ namespace OpenSim.Region.Framework.Scenes sbyte invType, sbyte type, UUID olditemID) { // m_log.DebugFormat( -// "[AGENT INVENTORY]: Received request from {0} to create inventory item link {1} in folder {2} pointing to {3}", -// remoteClient.Name, name, folderID, olditemID); +// "[AGENT INVENTORY]: Received request from {0} to create inventory item link {1} in folder {2} pointing to {3}, assetType {4}, inventoryType {5}", +// remoteClient.Name, name, folderID, olditemID, (AssetType)type, (InventoryType)invType); if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) return; @@ -973,10 +973,10 @@ namespace OpenSim.Region.Framework.Scenes asset.Type = type; asset.Name = name; asset.Description = description; - + CreateNewInventoryItem( - remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, name, 0, callbackID, asset, invType, - (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, + remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, name, 0, callbackID, asset, invType, + (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch()); } else diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 2ce1bab..3355428 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -302,7 +302,8 @@ namespace OpenSim.Services.InventoryService public virtual bool AddFolder(InventoryFolderBase folder) { - //m_log.DebugFormat("[XINVENTORY]: Add folder {0} type {1} in parent {2}", folder.Name, folder.Type, folder.ParentID); +// m_log.DebugFormat("[XINVENTORY]: Add folder {0} type {1} in parent {2}", folder.Name, folder.Type, folder.ParentID); + InventoryFolderBase check = GetFolder(folder); if (check != null) return false; @@ -346,7 +347,7 @@ namespace OpenSim.Services.InventoryService check.Version = (ushort)xFolder.version; xFolder = ConvertFromOpenSim(check); - + // m_log.DebugFormat( // "[XINVENTORY]: Storing version only update to system folder {0} {1} {2}", // xFolder.folderName, xFolder.version, xFolder.type); @@ -442,7 +443,6 @@ namespace OpenSim.Services.InventoryService public virtual bool UpdateItem(InventoryItemBase item) { -// throw new Exception("urrgh"); if (!m_AllowDelete) if (item.AssetType == (sbyte)AssetType.Link || item.AssetType == (sbyte)AssetType.LinkFolder) return false; -- cgit v1.1 From 9ab0c81c1dfb95e423d73599bd1fc66778749f0d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 21 May 2012 21:33:59 +0100 Subject: Setting 'in transit' on a local teleport as well as inter-region teleports. This is to eliminate possible race conditions if two teleport calls are made concurrently, where at least one is a local teleport. This is pretty much impossible on a manual user teleport but can happen on script-invoked teleports. --- .../CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 5dbe5e4..36e9da6 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -230,6 +230,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", sp.Name, position, sp.Scene.RegionInfo.RegionName); + if (!SetInTransit(sp.UUID)) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Ignoring within region teleport request of {0} {1} to {2} - agent is already in transit.", + sp.Name, sp.UUID, position); + } + // Teleport within the same region if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) { @@ -268,6 +275,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); } + + ResetFromTransit(sp.UUID); } /// -- cgit v1.1 From ff429a259b41f1205a6b153bb6da383d9a9f5daf Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 01:58:10 +0100 Subject: Fix bug where an avatar that had an object they owned attached through llAttachToAvatar() or osForceAttachToAvatar() would wrongly have next permissions come into play when they detached that object and rezzed it in scene. This is because the attachments module code was setting the 'object slam' bit by using PermissionMask.All Solution here is to route the attachment item creation call through the existing inventory code in BasicInventoryAccessModule rather than copy/pasted code in AttachmentsModule itself. --- .../Avatar/Attachments/AttachmentsModule.cs | 206 +++++++-------------- .../Attachments/Tests/AttachmentsModuleTests.cs | 13 +- .../InventoryAccess/InventoryAccessModule.cs | 59 +++--- .../Framework/Interfaces/IInventoryAccessModule.cs | 10 +- .../Scenes/AsyncSceneObjectGroupDeleter.cs | 2 +- .../Framework/Scenes/SceneObjectPartInventory.cs | 7 + .../CoalescedSceneObjectsSerializer.cs | 20 +- OpenSim/Tests/Common/Helpers/SceneHelpers.cs | 7 +- 8 files changed, 155 insertions(+), 169 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 2e1948d..d099511 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -49,6 +49,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments private Scene m_scene; private IDialogModule m_dialogModule; + private IInventoryAccessModule m_invAccessModule; /// /// Are attachments enabled? @@ -87,7 +88,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.EventManager.OnNewClient -= SubscribeToClientEvents; } - public void RegionLoaded(Scene scene) {} + public void RegionLoaded(Scene scene) + { + m_invAccessModule = m_scene.RequestModuleInterface(); + } public void Close() { @@ -578,90 +582,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// The user inventory item created that holds the attachment. private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IScenePresence sp, SceneObjectGroup grp) { + if (m_invAccessModule == null) + return null; + // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", // grp.Name, grp.LocalId, remoteClient.Name); - Vector3 inventoryStoredPosition = new Vector3 - (((grp.AbsolutePosition.X > (int)Constants.RegionSize) - ? Constants.RegionSize - 6 - : grp.AbsolutePosition.X) - , - (grp.AbsolutePosition.Y > (int)Constants.RegionSize) - ? Constants.RegionSize - 6 - : grp.AbsolutePosition.Y, - grp.AbsolutePosition.Z); - - Vector3 originalPosition = grp.AbsolutePosition; - - grp.AbsolutePosition = inventoryStoredPosition; - - // If we're being called from a script, then trying to serialize that same script's state will not complete - // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if - // the client/server crashes rather than logging out normally, the attachment's scripts will resume - // without state on relog. Arguably, this is what we want anyway. - string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false); - - grp.AbsolutePosition = originalPosition; - - AssetBase asset = m_scene.CreateAsset( - grp.GetPartName(grp.LocalId), - grp.GetPartDescription(grp.LocalId), - (sbyte)AssetType.Object, - Utils.StringToBytes(sceneObjectXml), - sp.UUID); - - m_scene.AssetService.Store(asset); - - InventoryItemBase item = new InventoryItemBase(); - item.CreatorId = grp.RootPart.CreatorID.ToString(); - item.CreatorData = grp.RootPart.CreatorData; - item.Owner = sp.UUID; - item.ID = UUID.Random(); - item.AssetID = asset.FullID; - item.Description = asset.Description; - item.Name = asset.Name; - item.AssetType = asset.Type; - item.InvType = (int)InventoryType.Object; - - InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); - if (folder != null) - item.Folder = folder.ID; - else // oopsies - item.Folder = UUID.Zero; - - if ((sp.UUID != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions()) - { - item.BasePermissions = grp.RootPart.NextOwnerMask; - item.CurrentPermissions = grp.RootPart.NextOwnerMask; - item.NextPermissions = grp.RootPart.NextOwnerMask; - item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask; - item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask; - } - else - { - item.BasePermissions = grp.RootPart.BaseMask; - item.CurrentPermissions = grp.RootPart.OwnerMask; - item.NextPermissions = grp.RootPart.NextOwnerMask; - item.EveryOnePermissions = grp.RootPart.EveryoneMask; - item.GroupPermissions = grp.RootPart.GroupMask; - } - item.CreationDate = Util.UnixTimeSinceEpoch(); + InventoryItemBase newItem = m_invAccessModule.CopyToInventory( + DeRezAction.TakeCopy, + m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID, + new List { grp }, + sp.ControllingClient, true)[0]; // sets itemID so client can show item as 'attached' in inventory - grp.FromItemID = item.ID; + grp.FromItemID = newItem.ID; - if (m_scene.AddInventoryItem(item)) - { - sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0); - } - else - { - if (m_dialogModule != null) - m_dialogModule.SendAlertToUser(sp.ControllingClient, "Operation failed"); - } - - return item; + return newItem; } // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. @@ -709,70 +646,69 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) { - IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); - if (invAccess != null) + if (m_invAccessModule == null) + return null; + + lock (sp.AttachmentsSyncLock) { - lock (sp.AttachmentsSyncLock) + SceneObjectGroup objatt; + + if (itemID != UUID.Zero) + objatt = m_invAccessModule.RezObject(sp.ControllingClient, + itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, + false, false, sp.UUID, true); + else + objatt = m_invAccessModule.RezObject(sp.ControllingClient, + null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, + false, false, sp.UUID, true); + + // m_log.DebugFormat( + // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", + // objatt.Name, remoteClient.Name, AttachmentPt); + + if (objatt != null) { - SceneObjectGroup objatt; - - if (itemID != UUID.Zero) - objatt = invAccess.RezObject(sp.ControllingClient, - itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, - false, false, sp.UUID, true); - else - objatt = invAccess.RezObject(sp.ControllingClient, - null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, - false, false, sp.UUID, true); - - // m_log.DebugFormat( - // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", - // objatt.Name, remoteClient.Name, AttachmentPt); - - if (objatt != null) + // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. + objatt.HasGroupChanged = false; + bool tainted = false; + if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) + tainted = true; + + // This will throw if the attachment fails + try { - // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. - objatt.HasGroupChanged = false; - bool tainted = false; - if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) - tainted = true; - - // This will throw if the attachment fails - try - { - AttachObject(sp, objatt, attachmentPt, false); - } - catch (Exception e) - { - m_log.ErrorFormat( - "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", - objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); - - // Make sure the object doesn't stick around and bail - sp.RemoveAttachment(objatt); - m_scene.DeleteSceneObject(objatt, false); - return null; - } + AttachObject(sp, objatt, attachmentPt, false); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", + objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); + + // Make sure the object doesn't stick around and bail + sp.RemoveAttachment(objatt); + m_scene.DeleteSceneObject(objatt, false); + return null; + } - if (tainted) - objatt.HasGroupChanged = true; + if (tainted) + objatt.HasGroupChanged = true; - // Fire after attach, so we don't get messy perms dialogs - // 4 == AttachedRez - objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); - objatt.ResumeScripts(); + // Fire after attach, so we don't get messy perms dialogs + // 4 == AttachedRez + objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); + objatt.ResumeScripts(); - // Do this last so that event listeners have access to all the effects of the attachment - m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); + // Do this last so that event listeners have access to all the effects of the attachment + m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); - return objatt; - } - else - { - m_log.WarnFormat( - "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", - itemID, sp.Name, attachmentPt); - } + return objatt; + } + else + { + m_log.WarnFormat( + "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", + itemID, sp.Name, attachmentPt); } } diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 42d07fd..5e89eec 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -99,12 +99,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests public void TestAddAttachmentFromGround() { TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); +// TestHelpers.EnableLogging(); AddPresence(); string attName = "att"; - SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup; + SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, m_presence.UUID).ParentGroup; m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false); @@ -123,6 +123,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That( m_presence.Appearance.GetAttachpoint(attSo.FromItemID), Is.EqualTo((int)AttachmentPoint.Chest)); + + InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); + Assert.That(attachmentItem, Is.Not.Null); + Assert.That(attachmentItem.Name, Is.EqualTo(attName)); + + InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(m_presence.UUID, AssetType.Object); + Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); + +// TestHelpers.DisableLogging(); } [Test] diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 8171487..f219d4c 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -295,9 +295,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess return UUID.Zero; } - public virtual UUID CopyToInventory(DeRezAction action, UUID folderID, - List objectGroups, IClientAPI remoteClient) + public virtual List CopyToInventory( + DeRezAction action, UUID folderID, + List objectGroups, IClientAPI remoteClient, bool asAttachment) { + List copiedItems = new List(); + Dictionary> bundlesToCopy = new Dictionary>(); if (CoalesceMultipleObjectsToInventory) @@ -324,16 +327,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } } - // This is method scoped and will be returned. It will be the - // last created asset id - UUID assetID = UUID.Zero; +// m_log.DebugFormat( +// "[INVENTORY ACCESS MODULE]: Copying {0} object bundles to folder {1} action {2} for {3}", +// bundlesToCopy.Count, folderID, action, remoteClient.Name); // Each iteration is really a separate asset being created, // with distinct destinations as well. foreach (List bundle in bundlesToCopy.Values) - assetID = CopyBundleToInventory(action, folderID, bundle, remoteClient); + copiedItems.Add(CopyBundleToInventory(action, folderID, bundle, remoteClient, asAttachment)); - return assetID; + return copiedItems; } /// @@ -344,12 +347,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess /// /// /// - /// - protected UUID CopyBundleToInventory( - DeRezAction action, UUID folderID, List objlist, IClientAPI remoteClient) + /// Should be true if the bundle is being copied as an attachment. This prevents + /// attempted serialization of any script state which would abort any operating scripts. + /// The inventory item created by the copy + protected InventoryItemBase CopyBundleToInventory( + DeRezAction action, UUID folderID, List objlist, IClientAPI remoteClient, + bool asAttachment) { - UUID assetID = UUID.Zero; - CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); Dictionary originalPositions = new Dictionary(); @@ -385,18 +389,27 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess string itemXml; + // If we're being called from a script, then trying to serialize that same script's state will not complete + // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if + // the client/server crashes rather than logging out normally, the attachment's scripts will resume + // without state on relog. Arguably, this is what we want anyway. if (objlist.Count > 1) - itemXml = CoalescedSceneObjectsSerializer.ToXml(coa); + itemXml = CoalescedSceneObjectsSerializer.ToXml(coa, !asAttachment); else - itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0]); + itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment); // Restore the position of each group now that it has been stored to inventory. foreach (SceneObjectGroup objectGroup in objlist) objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID); + +// m_log.DebugFormat( +// "[INVENTORY ACCESS MODULE]: Created item is {0}", +// item != null ? item.ID.ToString() : "NULL"); + if (item == null) - return UUID.Zero; + return null; // Can't know creator is the same, so null it in inventory if (objlist.Count > 1) @@ -406,7 +419,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } else { - item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); + item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); + item.CreatorData = objlist[0].RootPart.CreatorData; item.SaleType = objlist[0].RootPart.ObjectSaleType; item.SalePrice = objlist[0].RootPart.SalePrice; } @@ -419,8 +433,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess objlist[0].OwnerID.ToString()); m_Scene.AssetService.Store(asset); - item.AssetID = asset.FullID; - assetID = asset.FullID; + item.AssetID = asset.FullID; if (DeRezAction.SaveToExistingUserInventoryItem == action) { @@ -453,9 +466,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // This is a hook to do some per-asset post-processing for subclasses that need that if (remoteClient != null) - ExportAsset(remoteClient.AgentId, assetID); + ExportAsset(remoteClient.AgentId, asset.FullID); - return assetID; + return item; } protected virtual void ExportAsset(UUID agentID, UUID assetID) @@ -643,7 +656,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { // Catch all. Use lost & found // - folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); } } @@ -964,8 +976,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess so.FromFolderID = item.Folder; -// Console.WriteLine("rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}", -// rootPart.OwnerID, item.Owner, item.CurrentPermissions); +// m_log.DebugFormat( +// "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}", +// rootPart.OwnerID, item.Owner, item.CurrentPermissions); if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) diff --git a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs index 1904011..3576e35 100644 --- a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs @@ -49,11 +49,15 @@ namespace OpenSim.Region.Framework.Interfaces /// /// /// + /// + /// Should be true if the object(s) are begin taken as attachments. False otherwise. + /// /// - /// Returns the UUID of the newly created item asset (not the item itself). - /// FIXME: This is not very useful. It would be far more useful to return a list of items instead. + /// A list of the items created. If there was more than one object and objects are not being coaleseced in + /// inventory, then the order of items is in the same order as the input objects. /// - UUID CopyToInventory(DeRezAction action, UUID folderID, List objectGroups, IClientAPI remoteClient); + List CopyToInventory( + DeRezAction action, UUID folderID, List objectGroups, IClientAPI remoteClient, bool asAttachment); /// /// Rez an object into the scene from the user's inventory diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index 834464b..f555b49 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs @@ -155,7 +155,7 @@ namespace OpenSim.Region.Framework.Scenes { IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); if (invAccess != null) - invAccess.CopyToInventory(x.action, x.folderID, x.objectGroups, x.remoteClient); + invAccess.CopyToInventory(x.action, x.folderID, x.objectGroups, x.remoteClient, false); if (x.permissionToDelete) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 3734e03..d27d9e1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -1027,10 +1027,16 @@ namespace OpenSim.Region.Framework.Scenes public void ApplyNextOwnerPermissions() { + Util.PrintCallStack(); + lock (m_items) { foreach (TaskInventoryItem item in m_items.Values) { +// m_log.DebugFormat ( +// "[SCENE OBJECT PART INVENTORY]: Applying next permissions {0} to {1} in {2} with current {3}, base {4}, everyone {5}", +// item.NextPermissions, item.Name, m_part.Name, item.CurrentPermissions, item.BasePermissions, item.EveryonePermissions); + if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) { if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) @@ -1040,6 +1046,7 @@ namespace OpenSim.Region.Framework.Scenes if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) item.CurrentPermissions &= ~(uint)PermissionMask.Modify; } + item.CurrentPermissions &= item.NextPermissions; item.BasePermissions &= item.NextPermissions; item.EveryonePermissions &= item.NextPermissions; diff --git a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs index 55455cc..a4f730d 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs @@ -47,14 +47,30 @@ namespace OpenSim.Region.Framework.Scenes.Serialization /// public class CoalescedSceneObjectsSerializer { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// /// Serialize coalesced objects to Xml /// /// + /// + /// If true then serialize script states. This will halt any running scripts + /// /// public static string ToXml(CoalescedSceneObjects coa) + { + return ToXml(coa, true); + } + + /// + /// Serialize coalesced objects to Xml + /// + /// + /// + /// If true then serialize script states. This will halt any running scripts + /// + /// + public static string ToXml(CoalescedSceneObjects coa, bool doScriptStates) { using (StringWriter sw = new StringWriter()) { @@ -91,7 +107,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteAttributeString("offsety", offsets[i].Y.ToString()); writer.WriteAttributeString("offsetz", offsets[i].Z.ToString()); - SceneObjectSerializer.ToOriginalXmlFormat(obj, writer, true); + SceneObjectSerializer.ToOriginalXmlFormat(obj, writer, doScriptStates); writer.WriteEndElement(); // SceneObjectGroup } diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index 59829d9..239afc0 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs @@ -566,7 +566,7 @@ namespace OpenSim.Tests.Common /// public static SceneObjectPart AddSceneObject(Scene scene) { - return AddSceneObject(scene, "Test Object"); + return AddSceneObject(scene, "Test Object", UUID.Zero); } /// @@ -574,10 +574,11 @@ namespace OpenSim.Tests.Common /// /// /// + /// /// - public static SceneObjectPart AddSceneObject(Scene scene, string name) + public static SceneObjectPart AddSceneObject(Scene scene, string name, UUID ownerId) { - SceneObjectPart part = CreateSceneObjectPart(name, UUID.Random(), UUID.Zero); + SceneObjectPart part = CreateSceneObjectPart(name, UUID.Random(), ownerId); //part.UpdatePrimFlags(false, false, true); //part.ObjectFlags |= (uint)PrimFlags.Phantom; -- cgit v1.1 From ec8745cf511de3a452a882a44034c55baf2350a1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 02:05:48 +0100 Subject: minor: Make log class names in InventoryAccessModule uniform --- .../InventoryAccess/InventoryAccessModule.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index f219d4c..69767c1 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -175,7 +175,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess sbyte assetType, byte wearableType, uint nextOwnerMask, int creationDate) { - m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID); + m_log.DebugFormat("[INVENTORY ACCESS MODULE]: Received request to create inventory item {0} in folder {1}", name, folderID); if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) return; @@ -210,7 +210,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess else { m_log.ErrorFormat( - "ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", + "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", remoteClient.AgentId); } } @@ -288,7 +288,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess else { m_log.ErrorFormat( - "[AGENT INVENTORY]: Could not find item {0} for caps inventory update", + "[INVENTORY ACCESS MODULE]: Could not find item {0} for caps inventory update", itemID); } @@ -605,7 +605,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (null == item) { m_log.DebugFormat( - "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", + "[INVENTORY ACCESS MODULE]: Object {0} {1} scheduled for save to inventory has already been deleted.", so.Name, so.UUID); return null; @@ -706,7 +706,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (item == null) { m_log.WarnFormat( - "[InventoryAccessModule]: Could not find item {0} for {1} in RezObject()", + "[INVENTORY ACCESS MODULE]: Could not find item {0} for {1} in RezObject()", itemID, remoteClient.Name); return null; @@ -738,7 +738,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess else { m_log.WarnFormat( - "[InventoryAccessModule]: Could not find asset {0} for {1} in RezObject()", + "[INVENTORY ACCESS MODULE]: Could not find asset {0} for {1} in RezObject()", assetID, remoteClient.Name); } @@ -815,7 +815,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess group = objlist[i]; // m_log.DebugFormat( -// "[InventoryAccessModule]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", +// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", // group.Name, group.LocalId, group.UUID, // group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask, // remoteClient.Name); @@ -823,7 +823,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // Vector3 storedPosition = group.AbsolutePosition; if (group.UUID == UUID.Zero) { - m_log.Debug("[InventoryAccessModule]: Object has UUID.Zero! Position 3"); + m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3"); } foreach (SceneObjectPart part in group.Parts) @@ -886,7 +886,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } // m_log.DebugFormat( -// "[InventoryAccessModule]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", +// "[INVENTORY ACCESS MODULE]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", // group.Name, group.LocalId, group.UUID, // group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask, // remoteClient.Name); @@ -1101,7 +1101,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (assetRequestItem.AssetID != requestID) { m_log.WarnFormat( - "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", + "[INVENTORY ACCESS MODULE]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", Name, requestID, itemID, assetRequestItem.AssetID); return false; -- cgit v1.1 From 68918d632f0521941f67fe2c7b9c87ed048e2b92 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 02:09:31 +0100 Subject: Fetch the dialog module reference in AttachmentsModule in RegionLoaded() not AddRegion() The reference is not guaranteed to be there when AddRegion() is called but will definitely be present at RegionLoaded() if it's going to be present at all. --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index d099511..510b483 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -71,7 +71,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public void AddRegion(Scene scene) { m_scene = scene; - m_dialogModule = m_scene.RequestModuleInterface(); m_scene.RegisterModuleInterface(this); if (Enabled) @@ -90,6 +89,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public void RegionLoaded(Scene scene) { + m_dialogModule = m_scene.RequestModuleInterface(); m_invAccessModule = m_scene.RequestModuleInterface(); } -- cgit v1.1 From 050007b44da97bf155fca95cadc32cb27924e263 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 02:30:16 +0100 Subject: Lay out "show region" information in an easier to read line by line format --- OpenSim/Services/GridService/GridService.cs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index 3dc87bc..b17fca7 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -509,19 +509,21 @@ namespace OpenSim.Services.GridService return; } - MainConsole.Instance.Output("Region Name Region UUID"); - MainConsole.Instance.Output("Location URI"); - MainConsole.Instance.Output("Owner ID Flags"); - MainConsole.Instance.Output("-------------------------------------------------------------------------------"); + ICommandConsole con = MainConsole.Instance; + foreach (RegionData r in regions) { OpenSim.Data.RegionFlags flags = (OpenSim.Data.RegionFlags)Convert.ToInt32(r.Data["flags"]); - MainConsole.Instance.Output(String.Format("{0,-20} {1}\n{2,-20} {3}\n{4,-39} {5}\n\n", - r.RegionName, r.RegionID, - String.Format("{0},{1}", r.posX / Constants.RegionSize, r.posY / Constants.RegionSize), - r.Data["serverURI"], - r.Data["owner_uuid"], flags)); + + con.OutputFormat("{0,-11}: {1}", "Region Name", r.RegionName); + con.OutputFormat("{0,-11}: {1}", "Region ID", r.RegionID); + con.OutputFormat("{0,-11}: {1}", "Location", r.coordX, r.coordY); + con.OutputFormat("{0,-11}: {1}", "URI", r.Data["serverURI"]); + con.OutputFormat("{0,-11}: {1}", "Owner ID", r.Data["owner_uuid"]); + con.OutputFormat("{0,-11}: {1}", "Flags", flags); + con.Output("\n"); } + return; } -- cgit v1.1 From c6ce41bfbab310eae2366ad494a0dbb42cebc070 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 02:31:53 +0100 Subject: Add missing Y co-ord in "show region" console command information --- OpenSim/Services/GridService/GridService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index b17fca7..9d81eb5 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -517,7 +517,7 @@ namespace OpenSim.Services.GridService con.OutputFormat("{0,-11}: {1}", "Region Name", r.RegionName); con.OutputFormat("{0,-11}: {1}", "Region ID", r.RegionID); - con.OutputFormat("{0,-11}: {1}", "Location", r.coordX, r.coordY); + con.OutputFormat("{0,-11}: {1},{2}", "Location", r.coordX, r.coordY); con.OutputFormat("{0,-11}: {1}", "URI", r.Data["serverURI"]); con.OutputFormat("{0,-11}: {1}", "Owner ID", r.Data["owner_uuid"]); con.OutputFormat("{0,-11}: {1}", "Flags", flags); -- cgit v1.1 From 2222d979cc723ee2f3bad92ffe4991d074b2403a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 02:37:38 +0100 Subject: refactor: rename ConsoleTable -> ConsoleDisplayTable for clarity --- OpenSim/Framework/Console/ConsoleDisplayTable.cs | 139 +++++++++++++++++++++ OpenSim/Framework/Console/ConsoleTable.cs | 139 --------------------- .../Avatar/Attachments/AttachmentsCommandModule.cs | 2 +- 3 files changed, 140 insertions(+), 140 deletions(-) create mode 100644 OpenSim/Framework/Console/ConsoleDisplayTable.cs delete mode 100644 OpenSim/Framework/Console/ConsoleTable.cs diff --git a/OpenSim/Framework/Console/ConsoleDisplayTable.cs b/OpenSim/Framework/Console/ConsoleDisplayTable.cs new file mode 100644 index 0000000..49d5a17 --- /dev/null +++ b/OpenSim/Framework/Console/ConsoleDisplayTable.cs @@ -0,0 +1,139 @@ +/* + * 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.Linq; +using System.Text; + +namespace OpenSim.Framework.Console +{ + /// + /// Used to generated a formatted table for the console. + /// + /// + /// Currently subject to change. If you use this, be prepared to change your code when this class changes. + /// + public class ConsoleDisplayTable + { + /// + /// Default number of spaces between table columns. + /// + public const int DefaultTableSpacing = 2; + + /// + /// Table columns. + /// + public List Columns { get; private set; } + + /// + /// Table rows + /// + public List Rows { get; private set; } + + /// + /// Number of spaces to indent the table. + /// + public int Indent { get; set; } + + /// + /// Spacing between table columns + /// + public int TableSpacing { get; set; } + + public ConsoleDisplayTable() + { + TableSpacing = DefaultTableSpacing; + Columns = new List(); + Rows = new List(); + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + AddToStringBuilder(sb); + return sb.ToString(); + } + + public void AddToStringBuilder(StringBuilder sb) + { + string formatString = GetFormatString(); +// System.Console.WriteLine("FORMAT STRING [{0}]", formatString); + + // columns + sb.AppendFormat(formatString, Columns.ConvertAll(c => c.Header).ToArray()); + + // rows + foreach (ConsoleTableRow row in Rows) + sb.AppendFormat(formatString, row.Cells.ToArray()); + } + + /// + /// Gets the format string for the table. + /// + private string GetFormatString() + { + StringBuilder formatSb = new StringBuilder(); + + formatSb.Append(' ', Indent); + + for (int i = 0; i < Columns.Count; i++) + { + formatSb.Append(' ', TableSpacing); + + // Can only do left formatting for now + formatSb.AppendFormat("{{{0},-{1}}}", i, Columns[i].Width); + } + + formatSb.Append('\n'); + + return formatSb.ToString(); + } + } + + public struct ConsoleTableColumn + { + public string Header { get; set; } + public int Width { get; set; } + + public ConsoleTableColumn(string header, int width) : this() + { + Header = header; + Width = width; + } + } + + public struct ConsoleTableRow + { + public List Cells { get; private set; } + + public ConsoleTableRow(List cells) : this() + { + Cells = cells; + } + } +} \ No newline at end of file diff --git a/OpenSim/Framework/Console/ConsoleTable.cs b/OpenSim/Framework/Console/ConsoleTable.cs deleted file mode 100644 index be3025b..0000000 --- a/OpenSim/Framework/Console/ConsoleTable.cs +++ /dev/null @@ -1,139 +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.Linq; -using System.Text; - -namespace OpenSim.Framework.Console -{ - /// - /// Used to generated a formatted table for the console. - /// - /// - /// Currently subject to change. If you use this, be prepared to change your code when this class changes. - /// - public class ConsoleTable - { - /// - /// Default number of spaces between table columns. - /// - public const int DefaultTableSpacing = 2; - - /// - /// Table columns. - /// - public List Columns { get; private set; } - - /// - /// Table rows - /// - public List Rows { get; private set; } - - /// - /// Number of spaces to indent the table. - /// - public int Indent { get; set; } - - /// - /// Spacing between table columns - /// - public int TableSpacing { get; set; } - - public ConsoleTable() - { - TableSpacing = DefaultTableSpacing; - Columns = new List(); - Rows = new List(); - } - - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - AddToStringBuilder(sb); - return sb.ToString(); - } - - public void AddToStringBuilder(StringBuilder sb) - { - string formatString = GetFormatString(); -// System.Console.WriteLine("FORMAT STRING [{0}]", formatString); - - // columns - sb.AppendFormat(formatString, Columns.ConvertAll(c => c.Header).ToArray()); - - // rows - foreach (ConsoleTableRow row in Rows) - sb.AppendFormat(formatString, row.Cells.ToArray()); - } - - /// - /// Gets the format string for the table. - /// - private string GetFormatString() - { - StringBuilder formatSb = new StringBuilder(); - - formatSb.Append(' ', Indent); - - for (int i = 0; i < Columns.Count; i++) - { - formatSb.Append(' ', TableSpacing); - - // Can only do left formatting for now - formatSb.AppendFormat("{{{0},-{1}}}", i, Columns[i].Width); - } - - formatSb.Append('\n'); - - return formatSb.ToString(); - } - } - - public struct ConsoleTableColumn - { - public string Header { get; set; } - public int Width { get; set; } - - public ConsoleTableColumn(string header, int width) : this() - { - Header = header; - Width = width; - } - } - - public struct ConsoleTableRow - { - public List Cells { get; private set; } - - public ConsoleTableRow(List cells) : this() - { - Cells = cells; - } - } -} \ No newline at end of file diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs index a95514c..df32a1d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs @@ -145,7 +145,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments { sb.AppendFormat("Attachments for {0}\n", sp.Name); - ConsoleTable ct = new ConsoleTable() { Indent = 2 }; + ConsoleDisplayTable ct = new ConsoleDisplayTable() { Indent = 2 }; ct.Columns.Add(new ConsoleTableColumn("Attachment Name", 36)); ct.Columns.Add(new ConsoleTableColumn("Local ID", 10)); ct.Columns.Add(new ConsoleTableColumn("Item ID", 36)); -- cgit v1.1 From 059a1e90b92c3c1ca027c0ec59f3628d87a954a6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 03:19:25 +0100 Subject: Add ConsoleDisplayList for more consistent formatting of console output in list form. Convert "show region" to use this structure rather than hand-constructing --- OpenSim/Framework/Console/ConsoleDisplayList.cs | 112 ++++++++++++++++++++++++ OpenSim/Services/GridService/GridService.cs | 18 ++-- 2 files changed, 121 insertions(+), 9 deletions(-) create mode 100644 OpenSim/Framework/Console/ConsoleDisplayList.cs diff --git a/OpenSim/Framework/Console/ConsoleDisplayList.cs b/OpenSim/Framework/Console/ConsoleDisplayList.cs new file mode 100644 index 0000000..6885509 --- /dev/null +++ b/OpenSim/Framework/Console/ConsoleDisplayList.cs @@ -0,0 +1,112 @@ +/* + * 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.Linq; +using System.Text; + +namespace OpenSim.Framework.Console +{ + /// + /// Used to generated a formatted table for the console. + /// + /// + /// Currently subject to change. If you use this, be prepared to change your code when this class changes. + /// + public class ConsoleDisplayList + { + /// + /// The default divider between key and value for a list item. + /// + public const string DefaultKeyValueDivider = " : "; + + /// + /// The divider used between key and value for a list item. + /// + public string KeyValueDivider { get; set; } + + /// + /// Table rows + /// + public List> Rows { get; private set; } + + /// + /// Number of spaces to indent the list. + /// + public int Indent { get; set; } + + public ConsoleDisplayList() + { + Rows = new List>(); + KeyValueDivider = DefaultKeyValueDivider; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + AddToStringBuilder(sb); + return sb.ToString(); + } + + public void AddToStringBuilder(StringBuilder sb) + { + string formatString = GetFormatString(); +// System.Console.WriteLine("FORMAT STRING [{0}]", formatString); + + // rows + foreach (KeyValuePair row in Rows) + sb.AppendFormat(formatString, row.Key, row.Value); + } + + /// + /// Gets the format string for the table. + /// + private string GetFormatString() + { + StringBuilder formatSb = new StringBuilder(); + + int longestKey = -1; + + foreach (KeyValuePair row in Rows) + if (row.Key.Length > longestKey) + longestKey = row.Key.Length; + + formatSb.Append(' ', Indent); + + // Can only do left formatting for now + formatSb.AppendFormat("{{0,-{0}}}{1}{{1}}\n", longestKey, KeyValueDivider); + + return formatSb.ToString(); + } + + public void AddRow(object key, object value) + { + Rows.Add(new KeyValuePair(key.ToString(), value.ToString())); + } + } +} \ No newline at end of file diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index 9d81eb5..8a60ca5 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -509,19 +509,19 @@ namespace OpenSim.Services.GridService return; } - ICommandConsole con = MainConsole.Instance; - foreach (RegionData r in regions) { OpenSim.Data.RegionFlags flags = (OpenSim.Data.RegionFlags)Convert.ToInt32(r.Data["flags"]); - con.OutputFormat("{0,-11}: {1}", "Region Name", r.RegionName); - con.OutputFormat("{0,-11}: {1}", "Region ID", r.RegionID); - con.OutputFormat("{0,-11}: {1},{2}", "Location", r.coordX, r.coordY); - con.OutputFormat("{0,-11}: {1}", "URI", r.Data["serverURI"]); - con.OutputFormat("{0,-11}: {1}", "Owner ID", r.Data["owner_uuid"]); - con.OutputFormat("{0,-11}: {1}", "Flags", flags); - con.Output("\n"); + ConsoleDisplayList dispList = new ConsoleDisplayList(); + dispList.AddRow("Region Name", r.RegionName); + dispList.AddRow("Region ID", r.RegionID); + dispList.AddRow("Location", string.Format("{0},{1}", r.coordX, r.coordY)); + dispList.AddRow("URI", r.Data["serverURI"]); + dispList.AddRow("Owner ID", r.Data["owner_uuid"]); + dispList.AddRow("Flags", flags); + + MainConsole.Instance.Output(dispList.ToString()); } return; -- cgit v1.1 From 8f88c17df969b1fd3e4a93747201e9436c9a1fcd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 03:23:37 +0100 Subject: refactor: Rename ConsoleTableRow and ConsoleTableColumn to ConsoleDisplayTableRow and ConsoleDisplayTableColumn --- OpenSim/Framework/Console/ConsoleDisplayTable.cs | 18 +++++++++--------- .../Avatar/Attachments/AttachmentsCommandModule.cs | 12 ++++++------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/OpenSim/Framework/Console/ConsoleDisplayTable.cs b/OpenSim/Framework/Console/ConsoleDisplayTable.cs index 49d5a17..e9d1628 100644 --- a/OpenSim/Framework/Console/ConsoleDisplayTable.cs +++ b/OpenSim/Framework/Console/ConsoleDisplayTable.cs @@ -48,12 +48,12 @@ namespace OpenSim.Framework.Console /// /// Table columns. /// - public List Columns { get; private set; } + public List Columns { get; private set; } /// /// Table rows /// - public List Rows { get; private set; } + public List Rows { get; private set; } /// /// Number of spaces to indent the table. @@ -68,8 +68,8 @@ namespace OpenSim.Framework.Console public ConsoleDisplayTable() { TableSpacing = DefaultTableSpacing; - Columns = new List(); - Rows = new List(); + Columns = new List(); + Rows = new List(); } public override string ToString() @@ -88,7 +88,7 @@ namespace OpenSim.Framework.Console sb.AppendFormat(formatString, Columns.ConvertAll(c => c.Header).ToArray()); // rows - foreach (ConsoleTableRow row in Rows) + foreach (ConsoleDisplayTableRow row in Rows) sb.AppendFormat(formatString, row.Cells.ToArray()); } @@ -115,23 +115,23 @@ namespace OpenSim.Framework.Console } } - public struct ConsoleTableColumn + public struct ConsoleDisplayTableColumn { public string Header { get; set; } public int Width { get; set; } - public ConsoleTableColumn(string header, int width) : this() + public ConsoleDisplayTableColumn(string header, int width) : this() { Header = header; Width = width; } } - public struct ConsoleTableRow + public struct ConsoleDisplayTableRow { public List Cells { get; private set; } - public ConsoleTableRow(List cells) : this() + public ConsoleDisplayTableRow(List cells) : this() { Cells = cells; } diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs index df32a1d..1b9e3ac 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs @@ -146,11 +146,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments sb.AppendFormat("Attachments for {0}\n", sp.Name); ConsoleDisplayTable ct = new ConsoleDisplayTable() { Indent = 2 }; - ct.Columns.Add(new ConsoleTableColumn("Attachment Name", 36)); - ct.Columns.Add(new ConsoleTableColumn("Local ID", 10)); - ct.Columns.Add(new ConsoleTableColumn("Item ID", 36)); - ct.Columns.Add(new ConsoleTableColumn("Attach Point", 14)); - ct.Columns.Add(new ConsoleTableColumn("Position", 15)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Attachment Name", 36)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Local ID", 10)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Item ID", 36)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Attach Point", 14)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Position", 15)); // sb.AppendFormat( // " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", @@ -176,7 +176,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments // attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, // (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); ct.Rows.Add( - new ConsoleTableRow( + new ConsoleDisplayTableRow( new List() { attachmentObject.Name, -- cgit v1.1 From ee98b9c394900f55684e33829be1c182e84b2cab Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 04:10:45 +0100 Subject: Add "show scene" command which lists stats for the currently selected console scene(s) This includes prim count, script count, avatar count, etc. Information is currently the same as "show stats", though show stats can only show one scene at a time because it listens for the latest outgoing stats packet (a bad approach that needs to change). Might be better to tie this module into the other stats module to display arbitrary stats rather than fetching directly from scene.SimStatsReporter. Console command is "show scene" because "show region" already exists for the grid service, which is unfortunate. Might need to make a distinction between "scene" relating to a live scene and "region" relating to more static region data (url, coords, etc.) --- .../World/Region/RegionCommandsModule.cs | 155 +++++++++++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 7 +- 2 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs diff --git a/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs b/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs new file mode 100644 index 0000000..be4f497 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs @@ -0,0 +1,155 @@ +/* + * 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 System.Text; +using System.Text.RegularExpressions; +using log4net; +using Mono.Addins; +using NDesk.Options; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Statistics; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.World.Objects.Commands +{ + /// + /// A module that holds commands for manipulating objects in the scene. + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RegionCommandsModule")] + public class RegionCommandsModule : INonSharedRegionModule + { + private Scene m_scene; + private ICommandConsole m_console; + + public string Name { get { return "Region Commands Module"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { +// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: INITIALIZED MODULE"); + } + + public void PostInitialise() + { +// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: POST INITIALIZED MODULE"); + } + + public void Close() + { +// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: CLOSED MODULE"); + } + + public void AddRegion(Scene scene) + { +// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); + + m_scene = scene; + m_console = MainConsole.Instance; + + m_console.Commands.AddCommand( + "Regions", false, "show scene", + "show scene", + "Show live scene information for the currently selected region.", HandleShowScene); + } + + public void RemoveRegion(Scene scene) + { +// m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); + } + + public void RegionLoaded(Scene scene) + { +// m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); + } + + private void HandleShowScene(string module, string[] cmd) + { + if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene)) + return; + + SimStatsReporter r = m_scene.StatsReporter; + float[] stats = r.LastReportedSimStats; + + float timeDilation = stats[0]; + float simFps = stats[1]; + float physicsFps = stats[2]; + float agentUpdates = stats[3]; + float rootAgents = stats[4]; + float childAgents = stats[5]; + float totalPrims = stats[6]; + float activePrims = stats[7]; + float totalFrameTime = stats[8]; +// float netFrameTime = stats.StatsBlock[9].StatValue; // Ignored - not used by OpenSimulator + float physicsFrameTime = stats[10]; + float otherFrameTime = stats[11]; +// float imageFrameTime = stats.StatsBlock[12].StatValue; // Ignored + float inPacketsPerSecond = stats[13]; + float outPacketsPerSecond = stats[14]; + float unackedBytes = stats[15]; +// float agentFrameTime = stats.StatsBlock[16].StatValue; // Not really used + float pendingDownloads = stats[17]; + float pendingUploads = stats[18]; + float activeScripts = stats[19]; + float scriptLinesPerSecond = stats[20]; + + StringBuilder sb = new StringBuilder(); + sb.AppendFormat("Scene statistics for {0}\n", m_scene.RegionInfo.RegionName); + + ConsoleDisplayList dispList = new ConsoleDisplayList(); + dispList.AddRow("Time Dilation", timeDilation); + dispList.AddRow("Sim FPS", simFps); + dispList.AddRow("Physics FPS", physicsFps); + dispList.AddRow("Avatars", rootAgents); + dispList.AddRow("Child agents", childAgents); + dispList.AddRow("Total prims", totalPrims); + dispList.AddRow("Scripts", activeScripts); + dispList.AddRow("Script lines processed per second", scriptLinesPerSecond); + dispList.AddRow("Physics enabled prims", activePrims); + dispList.AddRow("Total frame time", totalFrameTime); + dispList.AddRow("Physics frame time", physicsFrameTime); + dispList.AddRow("Other frame time", otherFrameTime); + dispList.AddRow("Agent Updates per second", agentUpdates); + dispList.AddRow("Packets processed from clients per second", inPacketsPerSecond); + dispList.AddRow("Packets sent to clients per second", outPacketsPerSecond); + dispList.AddRow("Bytes unacknowledged by clients", unackedBytes); + dispList.AddRow("Pending asset downloads to clients", pendingDownloads); + dispList.AddRow("Pending asset uploads from clients", pendingUploads); + + dispList.AddToStringBuilder(sb); + + MainConsole.Instance.Output(sb.ToString()); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 5a0f564..fbe56f6 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -77,7 +77,12 @@ namespace OpenSim.Region.Framework.Scenes public bool DebugUpdates { get; private set; } public SynchronizeSceneHandler SynchronizeScene; - public SimStatsReporter StatsReporter; + + /// + /// Statistical information for this scene. + /// + public SimStatsReporter StatsReporter { get; private set; } + public List NorthBorders = new List(); public List EastBorders = new List(); public List SouthBorders = new List(); -- cgit v1.1 From 4d1986c0e480466383fa0a79a1305fe108430d68 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 04:20:54 +0100 Subject: minor: Change [OBJECT COMMANDS MODULE] log strings to [REGION COMMANDS MODULE] strings, though all these are currently commented out anyway --- .../Region/CoreModules/World/Region/RegionCommandsModule.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs b/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs index be4f497..2838e0c 100644 --- a/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs @@ -58,22 +58,22 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands public void Initialise(IConfigSource source) { -// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: INITIALIZED MODULE"); +// m_log.DebugFormat("[REGION COMMANDS MODULE]: INITIALIZED MODULE"); } public void PostInitialise() { -// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: POST INITIALIZED MODULE"); +// m_log.DebugFormat("[REGION COMMANDS MODULE]: POST INITIALIZED MODULE"); } public void Close() { -// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: CLOSED MODULE"); +// m_log.DebugFormat("[REGION COMMANDS MODULE]: CLOSED MODULE"); } public void AddRegion(Scene scene) { -// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); +// m_log.DebugFormat("[REGION COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); m_scene = scene; m_console = MainConsole.Instance; @@ -86,12 +86,12 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands public void RemoveRegion(Scene scene) { -// m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); +// m_log.DebugFormat("[REGION COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); } public void RegionLoaded(Scene scene) { -// m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); +// m_log.DebugFormat("[REGION COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); } private void HandleShowScene(string module, string[] cmd) -- cgit v1.1 From 682d4075e3fe7c52d4c29d00ba9dc0456b7322f3 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Wed, 23 May 2012 15:07:03 -0400 Subject: Fix llGetSimulatorHostname to return configured hostname --- OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | 4 ++++ OpenSim/Region/Framework/Interfaces/IUrlModule.cs | 1 + OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 3 ++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index d58fc0f..d2cd163 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -84,6 +84,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp private IHttpServer m_HttpsServer = null; private string m_ExternalHostNameForLSL = ""; + public string ExternalHostNameForLSL + { + get { return m_ExternalHostNameForLSL; } + } public Type ReplaceableInterface { diff --git a/OpenSim/Region/Framework/Interfaces/IUrlModule.cs b/OpenSim/Region/Framework/Interfaces/IUrlModule.cs index 1b91166..457444c 100644 --- a/OpenSim/Region/Framework/Interfaces/IUrlModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IUrlModule.cs @@ -34,6 +34,7 @@ namespace OpenSim.Region.Framework.Interfaces { public interface IUrlModule { + string ExternalHostNameForLSL { get; } UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID); UUID RequestSecureURL(IScriptModule engine, SceneObjectPart host, UUID itemID); void ReleaseURL(string url); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d213c35..4b28808 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -8743,7 +8743,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String llGetSimulatorHostname() { m_host.AddScriptLPS(1); - return System.Environment.MachineName; + IUrlModule UrlModule = World.RequestModuleInterface(); + return UrlModule.ExternalHostNameForLSL; } // -- cgit v1.1 From b490050165571bb9da87c3457db1a4b0b5c96dee Mon Sep 17 00:00:00 2001 From: BlueWall Date: Wed, 23 May 2012 16:58:04 -0400 Subject: Format cleanup --- OpenSim/Data/Null/NullSimulationData.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Data/Null/NullSimulationData.cs b/OpenSim/Data/Null/NullSimulationData.cs index b788976..18a4818 100644 --- a/OpenSim/Data/Null/NullSimulationData.cs +++ b/OpenSim/Data/Null/NullSimulationData.cs @@ -77,8 +77,8 @@ namespace OpenSim.Data.Null } public RegionSettings LoadRegionSettings(UUID regionUUID) - { - RegionSettings rs = new RegionSettings(); + { + RegionSettings rs = new RegionSettings(); rs.RegionUUID = regionUUID; return rs; } -- cgit v1.1 From bc543c1797c629a8584dd2e74d3c5f7a67de96c9 Mon Sep 17 00:00:00 2001 From: PixelTomsen Date: Wed, 23 May 2012 21:06:25 +0200 Subject: Environment Module - allows Environment settings for Viewer3 warning: includes database region store migrations for mssql, mysql, sqlite enable/disable this module: Cap_EnvironmentSettings = "localhost" (for enable) Cap_EnvironmentSettings = "" (for disable) at ClientStack.LindenCaps section (OpenSimDefaults.ini file) or owerwrite in OpenSim.ini mantis: http://opensimulator.org/mantis/view.php?id=5860 Signed-off-by: BlueWall --- OpenSim/Capabilities/LLSDEnvironmentSettings.cs | 68 +++++++ OpenSim/Data/MSSQL/MSSQLSimulationData.cs | 66 ++++++ .../Data/MSSQL/Resources/RegionStore.migrations | 14 ++ OpenSim/Data/MySQL/MySQLSimulationData.cs | 62 ++++++ .../Data/MySQL/Resources/RegionStore.migrations | 11 + OpenSim/Data/Null/NullSimulationData.cs | 18 ++ .../Data/SQLite/Resources/RegionStore.migrations | 11 + OpenSim/Data/SQLite/SQLiteSimulationData.cs | 101 +++++++++- .../CoreModules/LightShare/EnvironmentModule.cs | 224 +++++++++++++++++++++ .../Framework/Interfaces/IEnvironmentModule.cs | 36 ++++ .../Framework/Interfaces/ISimulationDataService.cs | 21 ++ .../Framework/Interfaces/ISimulationDataStore.cs | 20 ++ .../Connectors/Simulation/SimulationDataService.cs | 16 ++ OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs | 35 +++- bin/OpenSimDefaults.ini | 3 +- 15 files changed, 703 insertions(+), 3 deletions(-) create mode 100644 OpenSim/Capabilities/LLSDEnvironmentSettings.cs create mode 100644 OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs create mode 100644 OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs diff --git a/OpenSim/Capabilities/LLSDEnvironmentSettings.cs b/OpenSim/Capabilities/LLSDEnvironmentSettings.cs new file mode 100644 index 0000000..39019af --- /dev/null +++ b/OpenSim/Capabilities/LLSDEnvironmentSettings.cs @@ -0,0 +1,68 @@ +/* + * 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 OpenMetaverse; + +namespace OpenSim.Framework.Capabilities +{ + [OSDMap] + public class LLSDEnvironmentRequest + { + public UUID messageID; + public UUID regionID; + } + + [OSDMap] + public class LLSDEnvironmentSetResponse + { + public UUID regionID; + public UUID messageID; + public Boolean success; + public String fail_reason; + } + + public class EnvironmentSettings + { + /// + /// generates a empty llsd settings response for viewer + /// + /// the message UUID + /// the region UUID + public static string EmptySettings(UUID messageID, UUID regionID) + { + OSDArray arr = new OSDArray(); + LLSDEnvironmentRequest msg = new LLSDEnvironmentRequest(); + msg.messageID = messageID; + msg.regionID = regionID; + arr.Array.Add(msg); + return LLSDHelpers.SerialiseLLSDReply(arr); + } + } + +} diff --git a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs index d9dfe86..3f29f5b 100644 --- a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs +++ b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs @@ -1181,6 +1181,72 @@ VALUES // } #endregion } + + #region Environment Settings + public string LoadRegionEnvironmentSettings(UUID regionUUID) + { + string sql = "select * from [regionenvironment] where region_id = @region_id"; + using (SqlConnection conn = new SqlConnection(m_connectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionUUID)); + conn.Open(); + using (SqlDataReader result = cmd.ExecuteReader()) + { + if (!result.Read()) + { + return String.Empty; + } + else + { + return Convert.ToString(result["llsd_settings"]); + } + } + } + } + + public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) + { + { + string sql = "DELETE FROM [regionenvironment] WHERE region_id = @region_id"; + using (SqlConnection conn = new SqlConnection(m_connectionString)) + + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionUUID)); + conn.Open(); + cmd.ExecuteNonQuery(); + } + + sql = "INSERT INTO [regionenvironment] (region_id, llsd_settings) VALUES (@region_id, @llsd_settings)"; + + using (SqlConnection conn = new SqlConnection(m_connectionString)) + + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionUUID)); + cmd.Parameters.Add(_Database.CreateParameter("@llsd_settings", settings)); + + conn.Open(); + cmd.ExecuteNonQuery(); + } + } + } + + public void RemoveRegionEnvironmentSettings(UUID regionUUID) + { + string sql = "delete from [regionenvironment] where region_id = @region_id"; + using (SqlConnection conn = new SqlConnection(m_connectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionUUID)); + + conn.Open(); + cmd.ExecuteNonQuery(); + } + } + #endregion + /// /// Loads the settings of a region. /// diff --git a/OpenSim/Data/MSSQL/Resources/RegionStore.migrations b/OpenSim/Data/MSSQL/Resources/RegionStore.migrations index d6a3be9..350e548 100644 --- a/OpenSim/Data/MSSQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/MSSQL/Resources/RegionStore.migrations @@ -1134,3 +1134,17 @@ ALTER TABLE landaccesslist ADD Expires integer NOT NULL DEFAULT 0; COMMIT +:VERSION 37 #---------------- Environment Settings + +BEGIN TRANSACTION + +CREATE TABLE [dbo].[regionenvironment]( + [region_id] [uniqueidentifier] NOT NULL, + [llsd_settings] [varchar](max) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, + PRIMARY KEY CLUSTERED +( + [region_id] ASC +)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] +) ON [PRIMARY] + +COMMIT diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index b2a1481..1a2e113 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -969,6 +969,68 @@ namespace OpenSim.Data.MySQL } } + #region RegionEnvironmentSettings + public string LoadRegionEnvironmentSettings(UUID regionUUID) + { + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + string command = "select * from `regionenvironment` where region_id = ?region_id"; + + using (MySqlCommand cmd = new MySqlCommand(command)) + { + cmd.Connection = dbcon; + + cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); + + IDataReader result = ExecuteReader(cmd); + if (!result.Read()) + { + return String.Empty; + } + else + { + return Convert.ToString(result["llsd_settings"]); + } + } + } + } + + public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) + { + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)"; + + cmd.Parameters.AddWithValue("region_id", regionUUID); + cmd.Parameters.AddWithValue("llsd_settings", settings); + + ExecuteNonQuery(cmd); + } + } + } + + public void RemoveRegionEnvironmentSettings(UUID regionUUID) + { + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id"; + cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); + ExecuteNonQuery(cmd); + } + } + } + #endregion + public void StoreRegionSettings(RegionSettings rs) { lock (m_dbLock) diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations index 099beaf..4a925fb 100644 --- a/OpenSim/Data/MySQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations @@ -883,4 +883,15 @@ ALTER TABLE `regionsettings` MODIFY COLUMN `TelehubObject` VARCHAR(36) NOT NULL COMMIT; +:VERSION 44 #--------------------- Environment Settings + +BEGIN; + +CREATE TABLE `regionenvironment` ( + `region_id` varchar(36) NOT NULL, + `llsd_settings` TEXT NOT NULL, + PRIMARY KEY (`region_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +COMMIT; diff --git a/OpenSim/Data/Null/NullSimulationData.cs b/OpenSim/Data/Null/NullSimulationData.cs index 18a4818..8f2314f 100644 --- a/OpenSim/Data/Null/NullSimulationData.cs +++ b/OpenSim/Data/Null/NullSimulationData.cs @@ -76,6 +76,24 @@ namespace OpenSim.Data.Null //This connector doesn't support the windlight module yet } + #region Environment Settings + public string LoadRegionEnvironmentSettings(UUID regionUUID) + { + //This connector doesn't support the Environment module yet + return string.Empty; + } + + public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) + { + //This connector doesn't support the Environment module yet + } + + public void RemoveRegionEnvironmentSettings(UUID regionUUID) + { + //This connector doesn't support the Environment module yet + } + #endregion + public RegionSettings LoadRegionSettings(UUID regionUUID) { RegionSettings rs = new RegionSettings(); diff --git a/OpenSim/Data/SQLite/Resources/RegionStore.migrations b/OpenSim/Data/SQLite/Resources/RegionStore.migrations index 1ceddf9..e872977 100644 --- a/OpenSim/Data/SQLite/Resources/RegionStore.migrations +++ b/OpenSim/Data/SQLite/Resources/RegionStore.migrations @@ -564,3 +564,14 @@ COMMIT; BEGIN; ALTER TABLE `regionsettings` ADD COLUMN `parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; COMMIT; + +:VERSION 26 + +BEGIN; + +CREATE TABLE `regionenvironment` ( + `region_id` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000' PRIMARY KEY, + `llsd_settings` TEXT NOT NULL +); + +COMMIT; diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index 7e7c08a..f40e866 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs @@ -61,6 +61,7 @@ namespace OpenSim.Data.SQLite private const string regionbanListSelect = "select * from regionban"; private const string regionSettingsSelect = "select * from regionsettings"; private const string regionWindlightSelect = "select * from regionwindlight"; + private const string regionEnvironmentSelect = "select * from regionenvironment"; private const string regionSpawnPointsSelect = "select * from spawn_points"; private DataSet ds; @@ -72,6 +73,7 @@ namespace OpenSim.Data.SQLite private SqliteDataAdapter landAccessListDa; private SqliteDataAdapter regionSettingsDa; private SqliteDataAdapter regionWindlightDa; + private SqliteDataAdapter regionEnvironmentDa; private SqliteDataAdapter regionSpawnPointsDa; private SqliteConnection m_conn; @@ -146,6 +148,9 @@ namespace OpenSim.Data.SQLite SqliteCommand regionWindlightSelectCmd = new SqliteCommand(regionWindlightSelect, m_conn); regionWindlightDa = new SqliteDataAdapter(regionWindlightSelectCmd); + SqliteCommand regionEnvironmentSelectCmd = new SqliteCommand(regionEnvironmentSelect, m_conn); + regionEnvironmentDa = new SqliteDataAdapter(regionEnvironmentSelectCmd); + SqliteCommand regionSpawnPointsSelectCmd = new SqliteCommand(regionSpawnPointsSelect, m_conn); regionSpawnPointsDa = new SqliteDataAdapter(regionSpawnPointsSelectCmd); @@ -179,6 +184,9 @@ namespace OpenSim.Data.SQLite ds.Tables.Add(createRegionWindlightTable()); setupRegionWindlightCommands(regionWindlightDa, m_conn); + ds.Tables.Add(createRegionEnvironmentTable()); + setupRegionEnvironmentCommands(regionEnvironmentDa, m_conn); + ds.Tables.Add(createRegionSpawnPointsTable()); setupRegionSpawnPointsCommands(regionSpawnPointsDa, m_conn); @@ -260,6 +268,15 @@ namespace OpenSim.Data.SQLite try { + regionEnvironmentDa.Fill(ds.Tables["regionenvironment"]); + } + catch (Exception e) + { + m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on regionenvironment table :{0}", e.Message); + } + + try + { regionSpawnPointsDa.Fill(ds.Tables["spawn_points"]); } catch (Exception e) @@ -278,12 +295,13 @@ namespace OpenSim.Data.SQLite CreateDataSetMapping(landAccessListDa, "landaccesslist"); CreateDataSetMapping(regionSettingsDa, "regionsettings"); CreateDataSetMapping(regionWindlightDa, "regionwindlight"); + CreateDataSetMapping(regionEnvironmentDa, "regionenvironment"); CreateDataSetMapping(regionSpawnPointsDa, "spawn_points"); } } catch (Exception e) { - m_log.ErrorFormat("[SQLITE REGION DB]: ", e); + m_log.ErrorFormat("[SQLITE REGION DB]: {0} - {1}", e.Message, e.StackTrace); Environment.Exit(23); } return; @@ -341,6 +359,11 @@ namespace OpenSim.Data.SQLite regionWindlightDa.Dispose(); regionWindlightDa = null; } + if (regionEnvironmentDa != null) + { + regionEnvironmentDa.Dispose(); + regionEnvironmentDa = null; + } if (regionSpawnPointsDa != null) { regionSpawnPointsDa.Dispose(); @@ -474,6 +497,63 @@ namespace OpenSim.Data.SQLite } } + #region Region Environment Settings + public string LoadRegionEnvironmentSettings(UUID regionUUID) + { + lock (ds) + { + DataTable environmentTable = ds.Tables["regionenvironment"]; + DataRow row = environmentTable.Rows.Find(regionUUID.ToString()); + if (row == null) + { + return String.Empty; + } + + return (String)row["llsd_settings"]; + } + } + + public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) + { + lock (ds) + { + DataTable environmentTable = ds.Tables["regionenvironment"]; + DataRow row = environmentTable.Rows.Find(regionUUID.ToString()); + + if (row == null) + { + row = environmentTable.NewRow(); + row["region_id"] = regionUUID.ToString(); + row["llsd_settings"] = settings; + environmentTable.Rows.Add(row); + } + else + { + row["llsd_settings"] = settings; + } + + regionEnvironmentDa.Update(ds, "regionenvironment"); + } + } + + public void RemoveRegionEnvironmentSettings(UUID regionUUID) + { + lock (ds) + { + DataTable environmentTable = ds.Tables["regionenvironment"]; + DataRow row = environmentTable.Rows.Find(regionUUID.ToString()); + + if (row != null) + { + row.Delete(); + } + + regionEnvironmentDa.Update(ds, "regionenvironment"); + } + } + + #endregion + public RegionSettings LoadRegionSettings(UUID regionUUID) { lock (ds) @@ -1430,6 +1510,17 @@ namespace OpenSim.Data.SQLite return regionwindlight; } + private static DataTable createRegionEnvironmentTable() + { + DataTable regionEnvironment = new DataTable("regionenvironment"); + createCol(regionEnvironment, "region_id", typeof(String)); + createCol(regionEnvironment, "llsd_settings", typeof(String)); + + regionEnvironment.PrimaryKey = new DataColumn[] { regionEnvironment.Columns["region_id"] }; + + return regionEnvironment; + } + private static DataTable createRegionSpawnPointsTable() { DataTable spawn_points = new DataTable("spawn_points"); @@ -2691,6 +2782,14 @@ namespace OpenSim.Data.SQLite da.UpdateCommand.Connection = conn; } + private void setupRegionEnvironmentCommands(SqliteDataAdapter da, SqliteConnection conn) + { + da.InsertCommand = createInsertCommand("regionenvironment", ds.Tables["regionenvironment"]); + da.InsertCommand.Connection = conn; + da.UpdateCommand = createUpdateCommand("regionenvironment", "region_id=:region_id", ds.Tables["regionenvironment"]); + da.UpdateCommand.Connection = conn; + } + private void setupRegionSpawnPointsCommands(SqliteDataAdapter da, SqliteConnection conn) { da.InsertCommand = createInsertCommand("spawn_points", ds.Tables["spawn_points"]); diff --git a/OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs b/OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs new file mode 100644 index 0000000..1526886 --- /dev/null +++ b/OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs @@ -0,0 +1,224 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Capabilities; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using log4net; +using Nini.Config; +using Mono.Addins; + +using Caps = OpenSim.Framework.Capabilities.Caps; + + +namespace OpenSim.Region.CoreModules.World.LightShare +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EnvironmentModule")] + + public class EnvironmentModule : INonSharedRegionModule, IEnvironmentModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_scene = null; + private UUID regionID = UUID.Zero; + private static bool Enabled = false; + + private static readonly string capsName = "EnvironmentSettings"; + private static readonly string capsBase = "/CAPS/0020/"; + + private LLSDEnvironmentSetResponse setResponse = null; + + #region INonSharedRegionModule + public void Initialise(IConfigSource source) + { + IConfig config = source.Configs["ClientStack.LindenCaps"]; + + if (null == config) + return; + + if (config.GetString("Cap_EnvironmentSettings", String.Empty) != "localhost") + { + m_log.InfoFormat("[{0}]: Module is disabled.", Name); + return; + } + + Enabled = true; + + m_log.InfoFormat("[{0}]: Module is enabled.", Name); + } + + public void Close() + { + } + + public string Name + { + get { return "EnvironmentModule"; } + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { + if (!Enabled) + return; + + scene.RegisterModuleInterface(this); + m_scene = scene; + regionID = scene.RegionInfo.RegionID; + } + + public void RegionLoaded(Scene scene) + { + if (!Enabled) + return; + + setResponse = new LLSDEnvironmentSetResponse(); + scene.EventManager.OnRegisterCaps += OnRegisterCaps; + } + + public void RemoveRegion(Scene scene) + { + if (Enabled) + return; + + scene.EventManager.OnRegisterCaps -= OnRegisterCaps; + m_scene = null; + } + #endregion + + #region IEnvironmentModule + public void ResetEnvironmentSettings(UUID regionUUID) + { + if (!Enabled) + return; + + m_scene.SimulationDataService.RemoveRegionEnvironmentSettings(regionUUID); + } + #endregion + + #region Events + private void OnRegisterCaps(UUID agentID, Caps caps) + { +// m_log.DebugFormat("[{0}]: Register capability for agentID {1} in region {2}", +// Name, agentID, caps.RegionName); + + string capsPath = capsBase + UUID.Random(); + + // Get handler + caps.RegisterHandler( + capsName, + new RestStreamHandler( + "GET", + capsPath, + (request, path, param, httpRequest, httpResponse) + => GetEnvironmentSettings(request, path, param, agentID, caps), + capsName, + agentID.ToString())); + + // Set handler + caps.HttpListener.AddStreamHandler( + new RestStreamHandler( + "POST", + capsPath, + (request, path, param, httpRequest, httpResponse) + => SetEnvironmentSettings(request, path, param, agentID, caps), + capsName, + agentID.ToString())); + } + #endregion + + private string GetEnvironmentSettings(string request, string path, string param, + UUID agentID, Caps caps) + { +// m_log.DebugFormat("[{0}]: Environment GET handle for agentID {1} in region {2}", +// Name, agentID, caps.RegionName); + + string env = String.Empty; + + try + { + env = m_scene.SimulationDataService.LoadRegionEnvironmentSettings(regionID); + } + catch (Exception e) + { + m_log.ErrorFormat("[{0}]: Unable to load environment settings for region {1}, Exception: {2} - {3}", + Name, caps.RegionName, e.Message, e.StackTrace); + } + + if (String.IsNullOrEmpty(env)) + env = EnvironmentSettings.EmptySettings(UUID.Zero, regionID); + + return env; + } + + private string SetEnvironmentSettings(string request, string path, string param, + UUID agentID, Caps caps) + { + +// m_log.DebugFormat("[{0}]: Environment SET handle from agentID {1} in region {2}", +// Name, agentID, caps.RegionName); + + setResponse.regionID = regionID; + setResponse.success = false; + + if (!m_scene.Permissions.CanIssueEstateCommand(agentID, false)) + { + setResponse.fail_reason = "Insufficient estate permissions, settings has not been saved."; + return LLSDHelpers.SerialiseLLSDReply(setResponse); + } + + try + { + m_scene.SimulationDataService.StoreRegionEnvironmentSettings(regionID, request); + setResponse.success = true; + + m_log.InfoFormat("[{0}]: New Environment settings has been saved from agentID {1} in region {2}", + Name, agentID, caps.RegionName); + } + catch (Exception e) + { + m_log.ErrorFormat("[{0}]: Environment settings has not been saved for region {1}, Exception: {2} - {3}", + Name, caps.RegionName, e.Message, e.StackTrace); + + setResponse.success = false; + setResponse.fail_reason = String.Format("Environment Set for region {0} has failed, settings has not been saved.", caps.RegionName); + } + + return LLSDHelpers.SerialiseLLSDReply(setResponse); + } + } +} + diff --git a/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs b/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs new file mode 100644 index 0000000..7a7b782 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs @@ -0,0 +1,36 @@ +/* + * 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 OpenMetaverse; + +namespace OpenSim.Region.Framework.Interfaces +{ + public interface IEnvironmentModule + { + void ResetEnvironmentSettings(UUID regionUUID); + } +} diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs index 5295a72..0fcafcc 100644 --- a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs +++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs @@ -95,5 +95,26 @@ namespace OpenSim.Region.Framework.Interfaces RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID); void StoreRegionWindlightSettings(RegionLightShareData wl); void RemoveRegionWindlightSettings(UUID regionID); + + /// + /// Load Environment settings from region storage + /// + /// the region UUID + /// LLSD string for viewer + string LoadRegionEnvironmentSettings(UUID regionUUID); + + /// + /// Store Environment settings into region storage + /// + /// the region UUID + /// LLSD string from viewer + void StoreRegionEnvironmentSettings(UUID regionUUID, string settings); + + /// + /// Delete Environment settings from region storage + /// + /// the region UUID + void RemoveRegionEnvironmentSettings(UUID regionUUID); + } } diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs index 615f377..e424976 100644 --- a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs +++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs @@ -107,6 +107,26 @@ namespace OpenSim.Region.Framework.Interfaces void StoreRegionWindlightSettings(RegionLightShareData wl); void RemoveRegionWindlightSettings(UUID regionID); + /// + /// Load Environment settings from region storage + /// + /// the region UUID + /// LLSD string for viewer + string LoadRegionEnvironmentSettings(UUID regionUUID); + + /// + /// Store Environment settings into region storage + /// + /// the region UUID + /// LLSD string from viewer + void StoreRegionEnvironmentSettings(UUID regionUUID, string settings); + + /// + /// Delete Environment settings from region storage + /// + /// the region UUID + void RemoveRegionEnvironmentSettings(UUID regionUUID); + void Shutdown(); } } diff --git a/OpenSim/Services/Connectors/Simulation/SimulationDataService.cs b/OpenSim/Services/Connectors/Simulation/SimulationDataService.cs index ccef50b..c9cbbfa 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationDataService.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationDataService.cs @@ -148,5 +148,21 @@ namespace OpenSim.Services.Connectors { m_database.RemoveRegionWindlightSettings(regionID); } + + public string LoadRegionEnvironmentSettings(UUID regionUUID) + { + return m_database.LoadRegionEnvironmentSettings(regionUUID); + } + + public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) + { + m_database.StoreRegionEnvironmentSettings(regionUUID, settings); + } + + public void RemoveRegionEnvironmentSettings(UUID regionUUID) + { + m_database.RemoveRegionEnvironmentSettings(regionUUID); + } + } } diff --git a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs index 579d41c..1845eb9 100644 --- a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs @@ -112,6 +112,21 @@ namespace OpenSim.Data.Null { m_store.StoreRegionWindlightSettings(wl); } + + public string LoadRegionEnvironmentSettings(UUID regionUUID) + { + return m_store.LoadRegionEnvironmentSettings(regionUUID); + } + + public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) + { + m_store.StoreRegionEnvironmentSettings(regionUUID, settings); + } + + public void RemoveRegionEnvironmentSettings(UUID regionUUID) + { + m_store.RemoveRegionEnvironmentSettings(regionUUID); + } } /// @@ -158,7 +173,25 @@ namespace OpenSim.Data.Null { //This connector doesn't support the windlight module yet } - + + #region Environment Settings + public string LoadRegionEnvironmentSettings(UUID regionUUID) + { + //This connector doesn't support the Environment module yet + return string.Empty; + } + + public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) + { + //This connector doesn't support the Environment module yet + } + + public void RemoveRegionEnvironmentSettings(UUID regionUUID) + { + //This connector doesn't support the Environment module yet + } + #endregion + public RegionSettings LoadRegionSettings(UUID regionUUID) { RegionSettings rs = null; diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 7962ef8..5da3ba2 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -534,7 +534,7 @@ ; silly vanity "Facelights" dead. Sorry, head mounted miner's lamps ; will also be affected. ; - ;DisableFacelights = "false(1815) + ;DisableFacelights = false [ClientStack.LindenCaps] ;; Long list of capabilities taken from @@ -549,6 +549,7 @@ Cap_CopyInventoryFromNotecard = "localhost" Cap_DispatchRegionInfo = "" Cap_EstateChangeInfo = "" + Cap_EnvironmentSettings = "localhost" Cap_EventQueueGet = "localhost" Cap_FetchInventory = "" Cap_ObjectMedia = "localhost" -- cgit v1.1 From 459c7635afdbc4002cacbf5780185645a4296f6a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 May 2012 00:31:14 +0100 Subject: If an agent is still registered as 'in transit' by the source region, don't allow an immediate teleport back. This is to help relieve a race condition when an agent teleports then immediately attempts to teleport back before the source region has properly cleaned up/demoted the old ScenePresence. This is rare in viewers but much more possible via scripting or region module. However, more needs to be done since virtually all clean up happens after the transit flag is cleared . Possibly need to add a 'cleaning up' state to in transit. This change required making the EntityTransferModule and HGEntityTransferModule per-region rather than shared, in order to allow separate transit lists. Changes were also required in LocalSimulationConnector. Tested in standalone, grid and with local and remote region crossings with attachments. --- .../EntityTransfer/EntityTransferModule.cs | 69 ++++---- .../EntityTransfer/HGEntityTransferModule.cs | 55 +++--- .../Simulation/LocalSimulationConnector.cs | 186 +++++++++++---------- .../Framework/Interfaces/IEntityTransferModule.cs | 7 + OpenSim/Region/Framework/Scenes/Scene.cs | 67 +++++--- .../Scenes/Tests/ScenePresenceTeleportTests.cs | 42 +++-- 6 files changed, 233 insertions(+), 193 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 36e9da6..408d63d 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -46,7 +46,7 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { - public class EntityTransferModule : ISharedRegionModule, IEntityTransferModule + public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -65,9 +65,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public bool EnableWaitForCallbackFromTeleportDest { get; set; } protected bool m_Enabled = false; - protected Scene m_aScene; - protected List m_Scenes = new List(); + + protected Scene m_scene; + protected List m_agentsInTransit; + private ExpiringCache> m_bannedRegions = new ExpiringCache>(); @@ -129,10 +131,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!m_Enabled) return; - if (m_aScene == null) - m_aScene = scene; + m_scene = scene; - m_Scenes.Add(scene); scene.RegisterModuleInterface(this); scene.EventManager.OnNewClient += OnNewClient; } @@ -143,27 +143,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer client.OnTeleportLandmarkRequest += RequestTeleportLandmark; } - public virtual void Close() - { - if (!m_Enabled) - return; - } + public virtual void Close() {} - public virtual void RemoveRegion(Scene scene) - { - if (!m_Enabled) - return; - if (scene == m_aScene) - m_aScene = null; + public virtual void RemoveRegion(Scene scene) {} - m_Scenes.Remove(scene); - } - - public virtual void RegionLoaded(Scene scene) - { - if (!m_Enabled) - return; - } + public virtual void RegionLoaded(Scene scene) {} #endregion @@ -294,7 +278,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { uint x = 0, y = 0; Utils.LongToUInts(regionHandle, out x, out y); - GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); + GridRegion reg = m_scene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); if (reg != null) { @@ -441,7 +425,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer string reason; string version; - if (!m_aScene.SimulationService.QueryAccess( + if (!m_scene.SimulationService.QueryAccess( finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) { sp.ControllingClient.SendTeleportFailed(reason); @@ -660,7 +644,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer EnableChildAgents(sp); // Finally, kill the agent we just created at the destination. - m_aScene.SimulationService.CloseAgent(finalDestination, sp.UUID); + m_scene.SimulationService.CloseAgent(finalDestination, sp.UUID); sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); } @@ -668,7 +652,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) { logout = false; - bool success = m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); + bool success = m_scene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); if (success) sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout); @@ -678,7 +662,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) { - return m_aScene.SimulationService.UpdateAgent(finalDestination, agent); + return m_scene.SimulationService.UpdateAgent(finalDestination, agent); } protected virtual void SetCallbackURL(AgentData agent, RegionInfo region) @@ -730,7 +714,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return false; } - #endregion #region Landmark Teleport @@ -742,7 +725,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm) { - GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); + GridRegion info = m_scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); if (info == null) { @@ -763,12 +746,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); - //OpenSim.Services.Interfaces.PresenceInfo pinfo = m_aScene.PresenceService.GetAgent(client.SessionId); - GridUserInfo uinfo = m_aScene.GridUserService.GetGridUserInfo(client.AgentId.ToString()); + //OpenSim.Services.Interfaces.PresenceInfo pinfo = m_scene.PresenceService.GetAgent(client.SessionId); + GridUserInfo uinfo = m_scene.GridUserService.GetGridUserInfo(client.AgentId.ToString()); if (uinfo != null) { - GridRegion regionInfo = m_aScene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); + GridRegion regionInfo = m_scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); if (regionInfo == null) { // can't find the Home region: Tell viewer and abort @@ -1625,7 +1608,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Agent Arrived public void AgentArrivedAtDestination(UUID id) { - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Agent {0} released", id); ResetFromTransit(id); } @@ -1896,8 +1878,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer //// And the new channel... //if (m_interregionCommsOut != null) // successYN = m_interregionCommsOut.SendCreateObject(newRegionHandle, grp, true); - if (m_aScene.SimulationService != null) - successYN = m_aScene.SimulationService.CreateObject(destination, newPosition, grp, true); + if (m_scene.SimulationService != null) + successYN = m_scene.SimulationService.CreateObject(destination, newPosition, grp, true); if (successYN) { @@ -2004,7 +1986,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// /// true if the agent is in the process of being teleported, false otherwise. /// The agent ID - protected bool IsInTransit(UUID id) + public bool IsInTransit(UUID id) { lock (m_agentsInTransit) return m_agentsInTransit.Contains(id); @@ -2024,10 +2006,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (m_agentsInTransit.Contains(id)) { m_agentsInTransit.Remove(id); + + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Agent {0} cleared from transit in {1}", + id, m_scene.RegionInfo.RegionName); + return true; } } + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: Agent {0} requested to clear from transit in {1} but was already cleared.", + id, m_scene.RegionInfo.RegionName); + return false; } diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index b578bcb..4124667 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -45,11 +45,11 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { - public class HGEntityTransferModule : EntityTransferModule, ISharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule + public class HGEntityTransferModule + : EntityTransferModule, INonSharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private bool m_Initialized = false; private int m_levelHGTeleport = 0; private GatekeeperServiceConnector m_GatekeeperConnector; @@ -64,6 +64,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public override void Initialise(IConfigSource source) { IConfig moduleConfig = source.Configs["Modules"]; + if (moduleConfig != null) { string name = moduleConfig.GetString("EntityTransferModule", ""); @@ -82,10 +83,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public override void AddRegion(Scene scene) { base.AddRegion(scene); + if (m_Enabled) - { scene.RegisterModuleInterface(this); - } } protected override void OnNewClient(IClientAPI client) @@ -98,33 +98,28 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public override void RegionLoaded(Scene scene) { base.RegionLoaded(scene); - if (m_Enabled) - if (!m_Initialized) - { - m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); - m_Initialized = true; - - } + if (m_Enabled) + m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); } + public override void RemoveRegion(Scene scene) { base.AddRegion(scene); + if (m_Enabled) - { scene.UnregisterModuleInterface(this); - } } - #endregion #region HG overrides of IEntiryTransferModule protected override GridRegion GetFinalDestination(GridRegion region) { - int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, region.RegionID); + int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, region.RegionID); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); + if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) { m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID); @@ -135,6 +130,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: GetHyperlinkRegion to Gatekeeper {0} failed", region.ServerURI); return real_destination; } + return region; } @@ -143,7 +139,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) return true; - int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); + int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, reg.RegionID); if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) return true; @@ -156,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (logout) { // Log them out of this grid - m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); + m_scene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); } } @@ -165,7 +161,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI); reason = string.Empty; logout = false; - int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); + int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, reg.RegionID); if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) { // this user is going to another grid @@ -205,7 +201,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); // Let's find out if this is a foreign user or a local user - IUserManagement uMan = m_aScene.RequestModuleInterface(); + IUserManagement uMan = m_scene.RequestModuleInterface(); if (uMan != null && uMan.IsLocalGridUser(id)) { // local grid user @@ -262,19 +258,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}", (lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position); + if (lm.Gatekeeper == string.Empty) { base.RequestTeleportLandmark(remoteClient, lm); return; } - GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); + GridRegion info = m_scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); // Local region? if (info != null) { ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position, Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); + return; } else @@ -285,6 +283,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer GridRegion gatekeeper = new GridRegion(); gatekeeper.ServerURI = lm.Gatekeeper; GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID)); + if (finalDestination != null) { ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId); @@ -314,8 +313,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer IUserAgentService security = new UserAgentServiceConnector(url); return security.VerifyClient(aCircuit.SessionID, token); } - else - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent {0} {1} does not have a HomeURI OH NO!", aCircuit.firstname, aCircuit.lastname); + else + { + m_log.DebugFormat( + "[HG ENTITY TRANSFER MODULE]: Agent {0} {1} does not have a HomeURI OH NO!", + aCircuit.firstname, aCircuit.lastname); + } return false; } @@ -332,8 +335,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } // Let's find out if this is a foreign user or a local user - IUserManagement uMan = m_aScene.RequestModuleInterface(); - UserAccount account = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, obj.AgentId); + IUserManagement uMan = m_scene.RequestModuleInterface(); + UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, obj.AgentId); if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) { // local grid user @@ -356,7 +359,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion - private GridRegion MakeRegion(AgentCircuitData aCircuit) { GridRegion region = new GridRegion(); @@ -373,6 +375,5 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0); return region; } - } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 90f27c4..270daad 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs @@ -26,6 +26,7 @@ */ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using log4net; using Nini.Config; @@ -41,22 +42,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - // Version of this service - private const string m_Version = "SIMULATION/0.1"; - private List m_sceneList = new List(); + /// + /// Version of this service + /// + private const string m_Version = "SIMULATION/0.1"; - private IEntityTransferModule m_AgentTransferModule; - protected IEntityTransferModule AgentTransferModule - { - get - { - if (m_AgentTransferModule == null) - m_AgentTransferModule = m_sceneList[0].RequestModuleInterface(); - return m_AgentTransferModule; - } - } + /// + /// Map region ID to scene. + /// + private Dictionary m_scenes = new Dictionary(); + /// + /// Is this module enabled? + /// private bool m_ModuleEnabled = false; #region IRegionModule @@ -129,12 +128,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation /// public void RemoveScene(Scene scene) { - lock (m_sceneList) + lock (m_scenes) { - if (m_sceneList.Contains(scene)) - { - m_sceneList.Remove(scene); - } + if (m_scenes.ContainsKey(scene.RegionInfo.RegionID)) + m_scenes.Remove(scene.RegionInfo.RegionID); + else + m_log.WarnFormat( + "[LOCAL SIMULATION CONNECTOR]: Tried to remove region {0} but it was not present", + scene.RegionInfo.RegionName); } } @@ -144,13 +145,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation /// public void Init(Scene scene) { - if (!m_sceneList.Contains(scene)) + lock (m_scenes) { - lock (m_sceneList) - { - m_sceneList.Add(scene); - } - + if (!m_scenes.ContainsKey(scene.RegionInfo.RegionID)) + m_scenes[scene.RegionInfo.RegionID] = scene; + else + m_log.WarnFormat( + "[LOCAL SIMULATION CONNECTOR]: Tried to add region {0} but it is already present", + scene.RegionInfo.RegionName); } } @@ -160,13 +162,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation public IScene GetScene(ulong regionhandle) { - foreach (Scene s in m_sceneList) + foreach (Scene s in m_scenes.Values) { if (s.RegionInfo.RegionHandle == regionhandle) return s; } + // ? weird. should not happen - return m_sceneList[0]; + return m_scenes.Values.ToArray()[0]; } public ISimulationService GetInnerService() @@ -187,13 +190,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return false; } - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionHandle == destination.RegionHandle) - { // m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: Found region {0} to send SendCreateChildAgent", destination.RegionName); - return s.NewUserConnection(aCircuit, teleportFlags, out reason); - } + return m_scenes[destination.RegionID].NewUserConnection(aCircuit, teleportFlags, out reason); } reason = "Did not find region " + destination.RegionName; @@ -205,17 +205,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionHandle == destination.RegionHandle) - { // m_log.DebugFormat( // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", // s.RegionInfo.RegionName, destination.RegionHandle); - s.IncomingChildAgentDataUpdate(cAgentData); - return true; - } + return m_scenes[destination.RegionID].IncomingChildAgentDataUpdate(cAgentData); } // m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for ChildAgentUpdate", regionHandle); @@ -231,11 +227,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation // simulator so when we receive the update we need to hand it to each of the // scenes; scenes each check to see if the is a scene presence for the avatar // note that we really don't need the GridRegion for this call - foreach (Scene s in m_sceneList) + foreach (Scene s in m_scenes.Values) { //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); s.IncomingChildAgentDataUpdate(cAgentData); } + //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); return true; } @@ -247,14 +244,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionHandle == destination.RegionHandle) - { - //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); - return s.IncomingRetrieveRootAgent(id, out agent); - } +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + return m_scenes[destination.RegionID].IncomingRetrieveRootAgent(id, out agent); } + //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); return false; } @@ -266,27 +264,31 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionID == destination.RegionID) - return s.QueryAccess(id, position, out reason); +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + return m_scenes[destination.RegionID].QueryAccess(id, position, out reason); } + //m_log.Debug("[LOCAL COMMS]: region not found for QueryAccess"); return false; } - public bool ReleaseAgent(UUID origin, UUID id, string uri) + public bool ReleaseAgent(UUID originId, UUID agentId, string uri) { - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(originId)) { - if (s.RegionInfo.RegionID == origin) - { -// m_log.Debug("[LOCAL COMMS]: Found region to SendReleaseAgent"); - AgentTransferModule.AgentArrivedAtDestination(id); - return true; -// return s.IncomingReleaseAgent(id); - } +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + m_scenes[originId].EntityTransferModule.AgentArrivedAtDestination(agentId); + return true; } + //m_log.Debug("[LOCAL COMMS]: region not found in SendReleaseAgent " + origin); return false; } @@ -296,17 +298,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionID == destination.RegionID) - { - //m_log.Debug("[LOCAL COMMS]: Found region to SendCloseAgent"); - // Let's spawn a threadlet right here, because this may take - // a while - Util.FireAndForget(delegate { s.IncomingCloseAgent(id); }); - return true; - } +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); }); + return true; } + //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); return false; } @@ -320,25 +321,28 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionHandle == destination.RegionHandle) +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + Scene s = m_scenes[destination.RegionID]; + + if (isLocalCall) { - //m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); - if (isLocalCall) - { - // We need to make a local copy of the object - ISceneObject sogClone = sog.CloneForNewScene(); - sogClone.SetState(sog.GetStateSnapshot(), s); - return s.IncomingCreateObject(newPosition, sogClone); - } - else - { - // Use the object as it came through the wire - return s.IncomingCreateObject(newPosition, sog); - } + // We need to make a local copy of the object + ISceneObject sogClone = sog.CloneForNewScene(); + sogClone.SetState(sog.GetStateSnapshot(), s); + return s.IncomingCreateObject(newPosition, sogClone); + } + else + { + // Use the object as it came through the wire + return s.IncomingCreateObject(newPosition, sog); } } + return false; } @@ -347,13 +351,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionHandle == destination.RegionHandle) - { - return s.IncomingCreateObject(userID, itemID); - } +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + return m_scenes[destination.RegionID].IncomingCreateObject(userID, itemID); } + return false; } @@ -364,20 +370,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation public bool IsLocalRegion(ulong regionhandle) { - foreach (Scene s in m_sceneList) + foreach (Scene s in m_scenes.Values) if (s.RegionInfo.RegionHandle == regionhandle) return true; + return false; } public bool IsLocalRegion(UUID id) { - foreach (Scene s in m_sceneList) - if (s.RegionInfo.RegionID == id) - return true; - return false; + return m_scenes.ContainsKey(id); } #endregion } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index 18e9e3c..75c44d5 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -74,6 +74,13 @@ namespace OpenSim.Region.Framework.Interfaces /// void TeleportHome(UUID id, IClientAPI client); + /// + /// Show whether the given agent is being teleported. + /// + /// true if the agent is in the process of being teleported, false otherwise. + /// The agent ID + bool IsInTransit(UUID id); + bool Cross(ScenePresence agent, bool isFlying); void AgentArrivedAtDestination(UUID agent); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index fbe56f6..755b1e6 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -166,7 +166,6 @@ namespace OpenSim.Region.Framework.Scenes protected IConfigSource m_config; protected IRegionSerialiserModule m_serialiser; protected IDialogModule m_dialogModule; - protected IEntityTransferModule m_teleportModule; protected ICapabilitiesModule m_capsModule; protected IGroupsModule m_groupsModule; @@ -498,6 +497,7 @@ namespace OpenSim.Region.Framework.Scenes } public IAttachmentsModule AttachmentsModule { get; set; } + public IEntityTransferModule EntityTransferModule { get; private set; } public IAvatarFactoryModule AvatarFactory { @@ -924,8 +924,8 @@ namespace OpenSim.Region.Framework.Scenes List old = new List(); old.Add(otherRegion.RegionHandle); agent.DropOldNeighbours(old); - if (m_teleportModule != null && agent.PresenceType != PresenceType.Npc) - m_teleportModule.EnableChildAgent(agent, otherRegion); + if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc) + EntityTransferModule.EnableChildAgent(agent, otherRegion); }); } catch (NullReferenceException) @@ -1062,8 +1062,8 @@ namespace OpenSim.Region.Framework.Scenes { ForEachRootScenePresence(delegate(ScenePresence agent) { - if (m_teleportModule != null && agent.PresenceType != PresenceType.Npc) - m_teleportModule.EnableChildAgent(agent, r); + if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc) + EntityTransferModule.EnableChildAgent(agent, r); }); } catch (NullReferenceException) @@ -1238,7 +1238,7 @@ namespace OpenSim.Region.Framework.Scenes m_serialiser = RequestModuleInterface(); m_dialogModule = RequestModuleInterface(); m_capsModule = RequestModuleInterface(); - m_teleportModule = RequestModuleInterface(); + EntityTransferModule = RequestModuleInterface(); m_groupsModule = RequestModuleInterface(); } @@ -2275,8 +2275,8 @@ namespace OpenSim.Region.Framework.Scenes return; } - if (m_teleportModule != null) - m_teleportModule.Cross(grp, attemptedPosition, silent); + if (EntityTransferModule != null) + EntityTransferModule.Cross(grp, attemptedPosition, silent); } public Border GetCrossedBorder(Vector3 position, Cardinals gridline) @@ -3078,8 +3078,10 @@ namespace OpenSim.Region.Framework.Scenes /// The IClientAPI for the client public virtual void TeleportClientHome(UUID agentId, IClientAPI client) { - if (m_teleportModule != null) - m_teleportModule.TeleportHome(agentId, client); + if (EntityTransferModule != null) + { + EntityTransferModule.TeleportHome(agentId, client); + } else { m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); @@ -3638,7 +3640,6 @@ namespace OpenSim.Region.Framework.Scenes private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason) { - bool banned = land.IsBannedFromLand(agent.AgentID); bool restricted = land.IsRestrictedFromLand(agent.AgentID); @@ -4131,8 +4132,10 @@ namespace OpenSim.Region.Framework.Scenes position.Y -= shifty; } - if (m_teleportModule != null) - m_teleportModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags); + if (EntityTransferModule != null) + { + EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags); + } else { m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active"); @@ -4143,8 +4146,10 @@ namespace OpenSim.Region.Framework.Scenes public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying) { - if (m_teleportModule != null) - return m_teleportModule.Cross(agent, isFlying); + if (EntityTransferModule != null) + { + return EntityTransferModule.Cross(agent, isFlying); + } else { m_log.DebugFormat("[SCENE]: Unable to cross agent to neighbouring region, because there is no AgentTransferModule"); @@ -5188,14 +5193,34 @@ namespace OpenSim.Region.Framework.Scenes throw new Exception(error); } - // This method is called across the simulation connector to - // determine if a given agent is allowed in this region - // AS A ROOT AGENT. Returning false here will prevent them - // from logging into the region, teleporting into the region - // or corssing the broder walking, but will NOT prevent - // child agent creation, thereby emulating the SL behavior. + /// + /// This method is called across the simulation connector to + /// determine if a given agent is allowed in this region + /// AS A ROOT AGENT + /// + /// + /// Returning false here will prevent them + /// from logging into the region, teleporting into the region + /// or corssing the broder walking, but will NOT prevent + /// child agent creation, thereby emulating the SL behavior. + /// + /// + /// + /// + /// public bool QueryAccess(UUID agentID, Vector3 position, out string reason) { + if (EntityTransferModule.IsInTransit(agentID)) + { + reason = "Agent is already in transit on this region"; + + m_log.DebugFormat( + "[SCENE]: Denying agent {0} entry into {1} since region already has them registered as in transit", + agentID, RegionInfo.RegionName); + + return false; + } + // FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check. // However, the long term fix is to make sure root agent count is always accurate. m_sceneGraph.RecalculateStats(); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index 41bff7f..ccfe4ff 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -110,12 +110,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = TestHelpers.ParseTail(0x1); - EntityTransferModule etm = new EntityTransferModule(); + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); IConfig modulesConfig = config.AddConfig("Modules"); - modulesConfig.Set("EntityTransferModule", etm.Name); + modulesConfig.Set("EntityTransferModule", etmA.Name); modulesConfig.Set("SimulationServices", lscm.Name); IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); @@ -127,7 +128,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000); - SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); + SceneHelpers.SetupSceneModules(sceneA, config, etmA); + SceneHelpers.SetupSceneModules(sceneB, config, etmB); + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); @@ -174,12 +177,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = TestHelpers.ParseTail(0x1); Vector3 preTeleportPosition = new Vector3(30, 31, 32); - EntityTransferModule etm = new EntityTransferModule(); + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); + LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); - config.Configs["Modules"].Set("EntityTransferModule", etm.Name); + config.Configs["Modules"].Set("EntityTransferModule", etmA.Name); config.Configs["Modules"].Set("SimulationServices", lscm.Name); config.AddConfig("EntityTransfer"); @@ -195,13 +200,15 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000); + SceneHelpers.SetupSceneModules(sceneA, config, etmA ); + // We need to set up the permisions module on scene B so that our later use of agent limit to deny // QueryAccess won't succeed anyway because administrators are always allowed in and the default // IsAdministrator if no permissions module is present is true. - SceneHelpers.SetupSceneModules(sceneB, config, new object[] { new PermissionsModule() }); + SceneHelpers.SetupSceneModules(sceneB, config, new object[] { new PermissionsModule(), etmB }); // Shared scene modules - SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); @@ -249,12 +256,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = TestHelpers.ParseTail(0x1); Vector3 preTeleportPosition = new Vector3(30, 31, 32); - EntityTransferModule etm = new EntityTransferModule(); + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); - config.Configs["Modules"].Set("EntityTransferModule", etm.Name); + config.Configs["Modules"].Set("EntityTransferModule", etmA.Name); config.Configs["Modules"].Set("SimulationServices", lscm.Name); config.AddConfig("EntityTransfer"); @@ -267,8 +275,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000); + SceneHelpers.SetupSceneModules(sceneA, config, etmA); + SceneHelpers.SetupSceneModules(sceneB, config, etmB); + // Shared scene modules - SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); @@ -312,12 +323,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = TestHelpers.ParseTail(0x1); - EntityTransferModule etm = new EntityTransferModule(); + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); IConfig modulesConfig = config.AddConfig("Modules"); - modulesConfig.Set("EntityTransferModule", etm.Name); + modulesConfig.Set("EntityTransferModule", etmA.Name); modulesConfig.Set("SimulationServices", lscm.Name); IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); @@ -329,9 +341,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000); - SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); - SceneHelpers.SetupSceneModules(sceneA, new CapabilitiesModule()); - SceneHelpers.SetupSceneModules(sceneB, new CapabilitiesModule()); + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); + SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA); + SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB); Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); -- cgit v1.1 From 38ce9d45a523db277d3eb4d3ed310b7cd9ca6b43 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 May 2012 01:00:18 +0100 Subject: Make ISimulationScene.GetScene() used the more efficient region id for lookup rather than the region handle. --- .../Simulation/LocalSimulationConnector.cs | 20 ++++++++++++++------ .../Simulation/RemoteSimulationConnector.cs | 4 ++-- OpenSim/Server/Handlers/Simulation/AgentHandlers.cs | 4 ++-- OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs | 2 +- .../Simulation/SimulationServiceConnector.cs | 2 +- OpenSim/Services/Interfaces/ISimulationService.cs | 12 +++++++++++- 6 files changed, 31 insertions(+), 13 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 270daad..026c6c8 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs @@ -160,16 +160,24 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation #region ISimulation - public IScene GetScene(ulong regionhandle) + public IScene GetScene(UUID regionId) { - foreach (Scene s in m_scenes.Values) + if (m_scenes.ContainsKey(regionId)) { - if (s.RegionInfo.RegionHandle == regionhandle) - return s; + return m_scenes[regionId]; } + else + { + // FIXME: This was pre-existing behaviour but possibly not a good idea, since it hides an error rather + // than making it obvious and fixable. Need to see if the error message comes up in practice. + Scene s = m_scenes.Values.ToArray()[0]; - // ? weird. should not happen - return m_scenes.Values.ToArray()[0]; + m_log.ErrorFormat( + "[LOCAL SIMULATION CONNECTOR]: Region with id {0} not found. Returning {1} {2} instead", + regionId, s.RegionInfo.RegionName, s.RegionInfo.RegionID); + + return s; + } } public ISimulationService GetInnerService() diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index eaf9506..3d28518 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs @@ -151,9 +151,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation #region IInterregionComms - public IScene GetScene(ulong handle) + public IScene GetScene(UUID regionId) { - return m_localBackend.GetScene(handle); + return m_localBackend.GetScene(regionId); } public ISimulationService GetInnerService() diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index 5c9be8f..99ae7f0 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -546,7 +546,7 @@ namespace OpenSim.Server.Handlers.Simulation AgentData agent = new AgentData(); try { - agent.Unpack(args, m_SimulationService.GetScene(destination.RegionHandle)); + agent.Unpack(args, m_SimulationService.GetScene(destination.RegionID)); } catch (Exception ex) { @@ -566,7 +566,7 @@ namespace OpenSim.Server.Handlers.Simulation AgentPosition agent = new AgentPosition(); try { - agent.Unpack(args, m_SimulationService.GetScene(destination.RegionHandle)); + agent.Unpack(args, m_SimulationService.GetScene(destination.RegionID)); } catch (Exception ex) { diff --git a/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs b/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs index f0d8f69..a4d03ba 100644 --- a/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs @@ -161,7 +161,7 @@ namespace OpenSim.Server.Handlers.Simulation if (args.ContainsKey("extra") && args["extra"] != null) extraStr = args["extra"].AsString(); - IScene s = m_SimulationService.GetScene(destination.RegionHandle); + IScene s = m_SimulationService.GetScene(destination.RegionID); ISceneObject sog = null; try { diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index cb003d1..cc46ba8 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -62,7 +62,7 @@ namespace OpenSim.Services.Connectors.Simulation //m_Region = region; } - public IScene GetScene(ulong regionHandle) + public IScene GetScene(UUID regionId) { return null; } diff --git a/OpenSim/Services/Interfaces/ISimulationService.cs b/OpenSim/Services/Interfaces/ISimulationService.cs index 36fd6fc..4e52532 100644 --- a/OpenSim/Services/Interfaces/ISimulationService.cs +++ b/OpenSim/Services/Interfaces/ISimulationService.cs @@ -35,7 +35,17 @@ namespace OpenSim.Services.Interfaces { public interface ISimulationService { - IScene GetScene(ulong regionHandle); + /// + /// Retrieve the scene with the given region ID. + /// + /// + /// Region identifier. + /// + /// + /// The scene. + /// + IScene GetScene(UUID regionId); + ISimulationService GetInnerService(); #region Agents -- cgit v1.1 From f4cd4c8e284c8f1166028fe7f1585948a8c7c22f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 May 2012 04:33:36 +0100 Subject: Comment out accidentally left in log line that was printing out the control file on OAR save --- .../CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index 504f09b..4edaaca 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -428,9 +428,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver s = sw.ToString(); } - if (m_scene != null) - Console.WriteLine( - "[ARCHIVE WRITE REQUEST PREPARATION]: Control file for {0} is: {1}", m_scene.RegionInfo.RegionName, s); +// if (m_scene != null) +// Console.WriteLine( +// "[ARCHIVE WRITE REQUEST PREPARATION]: Control file for {0} is: {1}", m_scene.RegionInfo.RegionName, s); return s; } -- cgit v1.1 From 87f9aa9d0814fa4b5a89ad7f9794b096dfcbbeb0 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Thu, 24 May 2012 15:47:40 +0100 Subject: porting IDE tooltip-friendly documentation tweaks from Aurora-Sim Signed-off-by: BlueWall --- .../Servers/HttpServer/OSHttpStatusCodes.cs | 357 +++++++++++++-------- 1 file changed, 223 insertions(+), 134 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs index 5625227..3fc0832 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs @@ -28,143 +28,232 @@ namespace OpenSim.Framework.Servers.HttpServer { /// - /// HTTP status codes (almost) as defined by W3C in - /// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + /// HTTP status codes (almost) as defined by W3C in http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html /// public enum OSHttpStatusCode: int { - // 1xx Informational status codes providing a provisional - // response. - // 100 Tells client that to keep on going sending its request - InfoContinue = 100, - // 101 Server understands request, proposes to switch to different - // application level protocol - InfoSwitchingProtocols = 101, - - - // 2xx Success codes - // 200 Request successful - SuccessOk = 200, - // 201 Request successful, new resource created - SuccessOkCreated = 201, - // 202 Request accepted, processing still on-going - SuccessOkAccepted = 202, - // 203 Request successful, meta information not authoritative - SuccessOkNonAuthoritativeInformation = 203, - // 204 Request successful, nothing to return in the body - SuccessOkNoContent = 204, - // 205 Request successful, reset displayed content - SuccessOkResetContent = 205, - // 206 Request successful, partial content returned - SuccessOkPartialContent = 206, - - // 3xx Redirect code: user agent needs to go somewhere else - // 300 Redirect: different presentation forms available, take - // a pick - RedirectMultipleChoices = 300, - // 301 Redirect: requested resource has moved and now lives - // somewhere else - RedirectMovedPermanently = 301, - // 302 Redirect: Resource temporarily somewhere else, location - // might change - RedirectFound = 302, - // 303 Redirect: See other as result of a POST - RedirectSeeOther = 303, - // 304 Redirect: Resource still the same as before - RedirectNotModified = 304, - // 305 Redirect: Resource must be accessed via proxy provided - // in location field - RedirectUseProxy = 305, - // 307 Redirect: Resource temporarily somewhere else, location - // might change - RedirectMovedTemporarily = 307, - - // 4xx Client error: the client borked the request - // 400 Client error: bad request, server does not grok what - // the client wants - ClientErrorBadRequest = 400, - // 401 Client error: the client is not authorized, response - // provides WWW-Authenticate header field with a challenge - ClientErrorUnauthorized = 401, - // 402 Client error: Payment required (reserved for future use) - ClientErrorPaymentRequired = 402, - // 403 Client error: Server understood request, will not - // deliver, do not try again. - ClientErrorForbidden = 403, - // 404 Client error: Server cannot find anything matching the - // client request. - ClientErrorNotFound = 404, - // 405 Client error: The method specified by the client in the - // request is not allowed for the resource requested - ClientErrorMethodNotAllowed = 405, - // 406 Client error: Server cannot generate suitable response - // for the resource and content characteristics requested by - // the client - ClientErrorNotAcceptable = 406, - // 407 Client error: Similar to 401, Server requests that - // client authenticate itself with the proxy first - ClientErrorProxyAuthRequired = 407, - // 408 Client error: Server got impatient with client and - // decided to give up waiting for the client's request to - // arrive - ClientErrorRequestTimeout = 408, - // 409 Client error: Server could not fulfill the request for - // a resource as there is a conflict with the current state of - // the resource but thinks client can do something about this - ClientErrorConflict = 409, - // 410 Client error: The resource has moved somewhere else, - // but server has no clue where. - ClientErrorGone = 410, - // 411 Client error: The server is picky again and insists on - // having a content-length header field in the request - ClientErrorLengthRequired = 411, - // 412 Client error: one or more preconditions supplied in the - // client's request is false - ClientErrorPreconditionFailed = 412, - // 413 Client error: For fear of reflux, the server refuses to - // swallow that much data. - ClientErrorRequestEntityToLarge = 413, - // 414 Client error: The server considers the Request-URI to - // be indecently long and refuses to even look at it. - ClientErrorRequestURITooLong = 414, - // 415 Client error: The server has no clue about the media - // type requested by the client (contrary to popular belief it - // is not a warez server) - ClientErrorUnsupportedMediaType = 415, - // 416 Client error: The requested range cannot be delivered - // by the server. + #region 1xx Informational status codes providing a provisional response. + + /// + /// 100 Tells client that to keep on going sending its request + /// + InfoContinue = 100, + + /// + /// 101 Server understands request, proposes to switch to different application level protocol + /// + InfoSwitchingProtocols = 101, + + #endregion + + #region 2xx Success codes + + /// + /// 200 Request successful + /// + SuccessOk = 200, + + /// + /// 201 Request successful, new resource created + /// + SuccessOkCreated = 201, + + /// + /// 202 Request accepted, processing still on-going + /// + SuccessOkAccepted = 202, + + /// + /// 203 Request successful, meta information not authoritative + /// + SuccessOkNonAuthoritativeInformation = 203, + + /// + /// 204 Request successful, nothing to return in the body + /// + SuccessOkNoContent = 204, + + /// + /// 205 Request successful, reset displayed content + /// + SuccessOkResetContent = 205, + + /// + /// 206 Request successful, partial content returned + /// + SuccessOkPartialContent = 206, + + #endregion + + #region 3xx Redirect code: user agent needs to go somewhere else + + /// + /// 300 Redirect: different presentation forms available, take a pick + /// + RedirectMultipleChoices = 300, + + /// + /// 301 Redirect: requested resource has moved and now lives somewhere else + /// + RedirectMovedPermanently = 301, + + /// + /// 302 Redirect: Resource temporarily somewhere else, location might change + /// + RedirectFound = 302, + + /// + /// 303 Redirect: See other as result of a POST + /// + RedirectSeeOther = 303, + + /// + /// 304 Redirect: Resource still the same as before + /// + RedirectNotModified = 304, + + /// + /// 305 Redirect: Resource must be accessed via proxy provided in location field + /// + RedirectUseProxy = 305, + + /// + /// 307 Redirect: Resource temporarily somewhere else, location might change + /// + RedirectMovedTemporarily = 307, + + #endregion + + #region 4xx Client error: the client borked the request + + /// + /// 400 Client error: bad request, server does not grok what the client wants + /// + ClientErrorBadRequest = 400, + + /// + /// 401 Client error: the client is not authorized, response provides WWW-Authenticate header field with a challenge + /// + ClientErrorUnauthorized = 401, + + /// + /// 402 Client error: Payment required (reserved for future use) + /// + ClientErrorPaymentRequired = 402, + + /// + /// 403 Client error: Server understood request, will not deliver, do not try again. + ClientErrorForbidden = 403, + + /// + /// 404 Client error: Server cannot find anything matching the client request. + /// + ClientErrorNotFound = 404, + + /// + /// 405 Client error: The method specified by the client in the request is not allowed for the resource requested + /// + ClientErrorMethodNotAllowed = 405, + + /// + /// 406 Client error: Server cannot generate suitable response for the resource and content characteristics requested by the client + /// + ClientErrorNotAcceptable = 406, + + /// + /// 407 Client error: Similar to 401, Server requests that client authenticate itself with the proxy first + /// + ClientErrorProxyAuthRequired = 407, + + /// + /// 408 Client error: Server got impatient with client and decided to give up waiting for the client's request to arrive + /// + ClientErrorRequestTimeout = 408, + + /// + /// 409 Client error: Server could not fulfill the request for a resource as there is a conflict with the current state of the resource but thinks client can do something about this + /// + ClientErrorConflict = 409, + + /// + /// 410 Client error: The resource has moved somewhere else, but server has no clue where. + /// + ClientErrorGone = 410, + + /// + /// 411 Client error: The server is picky again and insists on having a content-length header field in the request + /// + ClientErrorLengthRequired = 411, + + /// + /// 412 Client error: one or more preconditions supplied in the client's request is false + /// + ClientErrorPreconditionFailed = 412, + + /// + /// 413 Client error: For fear of reflux, the server refuses to swallow that much data. + /// + ClientErrorRequestEntityToLarge = 413, + + /// + /// 414 Client error: The server considers the Request-URI to be indecently long and refuses to even look at it. + /// + ClientErrorRequestURITooLong = 414, + + /// + /// 415 Client error: The server has no clue about the media type requested by the client (contrary to popular belief it is not a warez server) + /// + ClientErrorUnsupportedMediaType = 415, + + /// + /// 416 Client error: The requested range cannot be delivered by the server. + /// ClientErrorRequestRangeNotSatisfiable = 416, - // 417 Client error: The expectations of the client as - // expressed in one or more Expect header fields cannot be met - // by the server, the server is awfully sorry about this. - ClientErrorExpectationFailed = 417, - // 499 Client error: Wildcard error. - ClientErrorJoker = 499, - - // 5xx Server errors (rare) - // 500 Server error: something really strange and unexpected - // happened - ServerErrorInternalError = 500, - // 501 Server error: The server does not do the functionality - // required to carry out the client request. not at - // all. certainly not before breakfast. but also not after - // breakfast. - ServerErrorNotImplemented = 501, - // 502 Server error: While acting as a proxy or a gateway, the - // server got ditched by the upstream server and as a - // consequence regretfully cannot fulfill the client's request - ServerErrorBadGateway = 502, - // 503 Server error: Due to unforseen circumstances the server - // cannot currently deliver the service requested. Retry-After - // header might indicate when to try again. - ServerErrorServiceUnavailable = 503, - // 504 Server error: The server blames the upstream server - // for not being able to deliver the service requested and - // claims that the upstream server is too slow delivering the - // goods. - ServerErrorGatewayTimeout = 504, - // 505 Server error: The server does not support the HTTP - // version conveyed in the client's request. - ServerErrorHttpVersionNotSupported = 505, + + /// + /// 417 Client error: The expectations of the client as expressed in one or more Expect header fields cannot be met by the server, the server is awfully sorry about this. + /// + ClientErrorExpectationFailed = 417, + + /// + /// 499 Client error: Wildcard error. + /// + ClientErrorJoker = 499, + + #endregion + + #region 5xx Server errors (rare) + + /// + /// 500 Server error: something really strange and unexpected happened + /// + ServerErrorInternalError = 500, + + /// + /// 501 Server error: The server does not do the functionality required to carry out the client request. not at all. certainly not before breakfast. but also not after breakfast. + /// + ServerErrorNotImplemented = 501, + + /// + /// 502 Server error: While acting as a proxy or a gateway, the server got ditched by the upstream server and as a consequence regretfully cannot fulfill the client's request + /// + ServerErrorBadGateway = 502, + + /// + /// 503 Server error: Due to unforseen circumstances the server cannot currently deliver the service requested. Retry-After header might indicate when to try again. + /// + ServerErrorServiceUnavailable = 503, + + /// + /// 504 Server error: The server blames the upstream server for not being able to deliver the service requested and claims that the upstream server is too slow delivering the goods. + /// + ServerErrorGatewayTimeout = 504, + + /// + /// 505 Server error: The server does not support the HTTP version conveyed in the client's request. + /// + ServerErrorHttpVersionNotSupported = 505, + + #endregion } } -- cgit v1.1 From 99cebec4ab819e93a2162be3fa4556ac5153ec8a Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Thu, 24 May 2012 16:01:46 +0100 Subject: adding status codes from rfc 6585 Signed-off-by: BlueWall --- .../Servers/HttpServer/OSHttpStatusCodes.cs | 24 ++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs index 3fc0832..a736c8b 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs @@ -28,9 +28,9 @@ namespace OpenSim.Framework.Servers.HttpServer { /// - /// HTTP status codes (almost) as defined by W3C in http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + /// HTTP status codes (almost) as defined by W3C in http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html and IETF in http://tools.ietf.org/html/rfc6585 /// - public enum OSHttpStatusCode: int + public enum OSHttpStatusCode : int { #region 1xx Informational status codes providing a provisional response. @@ -216,6 +216,21 @@ namespace OpenSim.Framework.Servers.HttpServer ClientErrorExpectationFailed = 417, /// + /// 428 Client error :The 428 status code indicates that the origin server requires the request to be conditional. + /// + ClientErrorPreconditionRequired = 428, + + /// + /// 429 Client error: The 429 status code indicates that the user has sent too many requests in a given amount of time ("rate limiting"). + /// + ClientErrorTooManyRequests = 429, + + /// + /// 431 Client error: The 431 status code indicates that the server is unwilling to process the request because its header fields are too large. The request MAY be resubmitted after reducing the size of the request header fields. + /// + ClientErrorRequestHeaderFieldsTooLarge = 431, + + /// /// 499 Client error: Wildcard error. /// ClientErrorJoker = 499, @@ -254,6 +269,11 @@ namespace OpenSim.Framework.Servers.HttpServer /// ServerErrorHttpVersionNotSupported = 505, + /// + /// 511 Server error: The 511 status code indicates that the client needs to authenticate to gain network access. + /// + ServerErrorNetworkAuthenticationRequired = 511, + #endregion } } -- cgit v1.1 From 5c9086ade688b457e9aa9cd0d2099985b7336b71 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 May 2012 22:26:02 +0100 Subject: Fix issue where a dns resolution failure on the final destination might leave the user unable to teleport since the transit flag was not being reset. This moves the 'already in transit' check further up and resets the flag if dns resolution fails and in the new required places. --- .../EntityTransfer/EntityTransferModule.cs | 392 +++++++++++---------- 1 file changed, 200 insertions(+), 192 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 408d63d..4988e93 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -358,33 +358,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags) { - RegionInfo sourceRegion = sp.Scene.RegionInfo; - - if (!IsWithinMaxTeleportDistance(sourceRegion, finalDestination)) + // 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 (!SetInTransit(sp.UUID)) { - sp.ControllingClient.SendTeleportFailed( - string.Format( - "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", - finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY, - sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, - MaxTransferDistance)); + 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; } - IEventQueue eq = sp.Scene.RequestModuleInterface(); - if (reg == null || finalDestination == null) { sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); - return; - } - - if (!SetInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this. - { - 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); + ResetFromTransit(sp.UUID); return; } @@ -394,6 +382,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.Name, sp.UUID, sp.Scene.RegionInfo.RegionName, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); + RegionInfo sourceRegion = sp.Scene.RegionInfo; + + if (!IsWithinMaxTeleportDistance(sourceRegion, finalDestination)) + { + sp.ControllingClient.SendTeleportFailed( + string.Format( + "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", + finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY, + sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, + MaxTransferDistance)); + + ResetFromTransit(sp.UUID); + + return; + } + + IEventQueue eq = sp.Scene.RequestModuleInterface(); + uint newRegionX = (uint)(reg.RegionHandle >> 40); uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); @@ -405,17 +411,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, // it's actually doing a lot of work. IPEndPoint endPoint = finalDestination.ExternalEndPoint; - if (endPoint.Address != null) + + if (endPoint.Address == null) { - // Fixing a bug where teleporting while sitting results in the avatar ending up removed from - // both regions - if (sp.ParentID != (uint)0) - sp.StandUp(); + sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); + ResetFromTransit(sp.UUID); + + return; + } - if (!sp.ValidateAttachments()) - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", - sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); + // Fixing a bug where teleporting while sitting results in the avatar ending up removed from + // both regions + if (sp.ParentID != (uint)0) + sp.StandUp(); + + if (!sp.ValidateAttachments()) + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", + sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); // if (!sp.ValidateAttachments()) // { @@ -423,211 +436,206 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // return; // } - string reason; - string version; - if (!m_scene.SimulationService.QueryAccess( - finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) - { - sp.ControllingClient.SendTeleportFailed(reason); - ResetFromTransit(sp.UUID); + string reason; + string version; + if (!m_scene.SimulationService.QueryAccess( + finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) + { + sp.ControllingClient.SendTeleportFailed(reason); + ResetFromTransit(sp.UUID); - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", - sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", + sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); - return; - } + return; + } - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); - sp.ControllingClient.SendTeleportStart(teleportFlags); + sp.ControllingClient.SendTeleportStart(teleportFlags); - // the avatar.Close below will clear the child region list. We need this below for (possibly) - // closing the child agents, so save it here (we need a copy as it is Clear()-ed). - //List childRegions = avatar.KnownRegionHandles; - // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport - // failure at this point (unlike a border crossing failure). So perhaps this can never fail - // once we reach here... - //avatar.Scene.RemoveCapsHandler(avatar.UUID); + // the avatar.Close below will clear the child region list. We need this below for (possibly) + // closing the child agents, so save it here (we need a copy as it is Clear()-ed). + //List childRegions = avatar.KnownRegionHandles; + // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport + // failure at this point (unlike a border crossing failure). So perhaps this can never fail + // once we reach here... + //avatar.Scene.RemoveCapsHandler(avatar.UUID); - string capsPath = String.Empty; + string capsPath = String.Empty; - AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); - AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); - agentCircuit.startpos = position; - agentCircuit.child = true; - agentCircuit.Appearance = sp.Appearance; - if (currentAgentCircuit != null) - { - agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; - agentCircuit.IPAddress = currentAgentCircuit.IPAddress; - agentCircuit.Viewer = currentAgentCircuit.Viewer; - agentCircuit.Channel = currentAgentCircuit.Channel; - agentCircuit.Mac = currentAgentCircuit.Mac; - agentCircuit.Id0 = currentAgentCircuit.Id0; - } + AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); + AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); + agentCircuit.startpos = position; + agentCircuit.child = true; + agentCircuit.Appearance = sp.Appearance; + if (currentAgentCircuit != null) + { + agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; + agentCircuit.IPAddress = currentAgentCircuit.IPAddress; + agentCircuit.Viewer = currentAgentCircuit.Viewer; + agentCircuit.Channel = currentAgentCircuit.Channel; + agentCircuit.Mac = currentAgentCircuit.Mac; + agentCircuit.Id0 = currentAgentCircuit.Id0; + } - if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) - { - // brand new agent, let's create a new caps seed - agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); - } + if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) + { + // brand new agent, let's create a new caps seed + agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); + } - // Let's create an agent there if one doesn't exist yet. - bool logout = false; - if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) - { - sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); - ResetFromTransit(sp.UUID); + // Let's create an agent there if one doesn't exist yet. + bool logout = false; + if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) + { + sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); + ResetFromTransit(sp.UUID); - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", - sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", + sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); - return; - } + return; + } - // OK, it got this agent. Let's close some child agents - sp.CloseChildAgents(newRegionX, newRegionY); + // OK, it got this agent. Let's close some child agents + sp.CloseChildAgents(newRegionX, newRegionY); - IClientIPEndpoint ipepClient; - if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) + IClientIPEndpoint ipepClient; + if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) + { + //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); + #region IP Translation for NAT + // Uses ipepClient above + if (sp.ClientView.TryGet(out ipepClient)) { - //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); - #region IP Translation for NAT - // Uses ipepClient above - if (sp.ClientView.TryGet(out ipepClient)) - { - endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); - } - #endregion - capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + } + #endregion + capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); - if (eq != null) - { - eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); + if (eq != null) + { + eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); - // ES makes the client send a UseCircuitCode message to the destination, - // which triggers a bunch of things there. - // So let's wait - Thread.Sleep(200); + // ES makes the client send a UseCircuitCode message to the destination, + // which triggers a bunch of things there. + // So let's wait + Thread.Sleep(200); - eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); + eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); - } - else - { - sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); - } } else { - agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); - capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); } + } + else + { + agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); + capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + } - // Let's send a full update of the agent. This is a synchronous call. - AgentData agent = new AgentData(); - sp.CopyTo(agent); - agent.Position = position; - SetCallbackURL(agent, sp.Scene.RegionInfo); + // Let's send a full update of the agent. This is a synchronous call. + AgentData agent = new AgentData(); + sp.CopyTo(agent); + agent.Position = position; + SetCallbackURL(agent, sp.Scene.RegionInfo); - //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); + //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); - if (!UpdateAgent(reg, finalDestination, agent)) - { - // Region doesn't take it - m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", - sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - - Fail(sp, finalDestination, logout); - return; - } + if (!UpdateAgent(reg, finalDestination, agent)) + { + // Region doesn't take it + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", + sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); + + Fail(sp, finalDestination, logout); + return; + } - sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); + sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", - capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", + capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); - if (eq != null) - { - eq.TeleportFinishEvent(destinationHandle, 13, endPoint, - 0, teleportFlags, capsPath, sp.UUID); - } - else - { - sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, - teleportFlags, capsPath); - } + if (eq != null) + { + eq.TeleportFinishEvent(destinationHandle, 13, endPoint, + 0, teleportFlags, capsPath, sp.UUID); + } + else + { + sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, + teleportFlags, capsPath); + } - // Let's set this to true tentatively. This does not trigger OnChildAgent - sp.IsChildAgent = true; + // Let's set this to true tentatively. This does not trigger OnChildAgent + sp.IsChildAgent = true; - // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which - // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation - // that the client contacted the destination before we close things here. - if (EnableWaitForCallbackFromTeleportDest && !WaitForCallback(sp.UUID)) - { - m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", - sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - - Fail(sp, finalDestination, logout); - return; - } + // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which + // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation + // that the client contacted the destination before we close things here. + if (EnableWaitForCallbackFromTeleportDest && !WaitForCallback(sp.UUID)) + { + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", + sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); + + Fail(sp, finalDestination, logout); + return; + } - // For backwards compatibility - if (version == "Unknown" || version == string.Empty) - { - // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one..."); - CrossAttachmentsIntoNewRegion(finalDestination, sp, true); - } + // For backwards compatibility + if (version == "Unknown" || version == string.Empty) + { + // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one..."); + CrossAttachmentsIntoNewRegion(finalDestination, sp, true); + } - // May need to logout or other cleanup - AgentHasMovedAway(sp, logout); + // May need to logout or other cleanup + AgentHasMovedAway(sp, logout); - // Well, this is it. The agent is over there. - KillEntity(sp.Scene, sp.LocalId); + // Well, this is it. The agent is over there. + KillEntity(sp.Scene, sp.LocalId); - // Now let's make it officially a child agent - sp.MakeChildAgent(); + // Now let's make it officially a child agent + sp.MakeChildAgent(); // sp.Scene.CleanDroppedAttachments(); - // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone - - if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) - { - // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before - // they regard the new region as the current region after receiving the AgentMovementComplete - // response. If close is sent before then, it will cause the viewer to quit instead. - // However, if this delay is longer, then a viewer can teleport back to this region and experience - // a failure because the old ScenePresence has not yet been cleaned up. - Thread.Sleep(2000); - - sp.Close(); - sp.Scene.IncomingCloseAgent(sp.UUID); - } - else - { - // now we have a child agent in this region. - sp.Reset(); - } + // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone - // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! - if (sp.Scene.NeedSceneCacheClear(sp.UUID)) - { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", - sp.UUID); - } + if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) + { + // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before + // they regard the new region as the current region after receiving the AgentMovementComplete + // response. If close is sent before then, it will cause the viewer to quit instead. + // However, if this delay is longer, then a viewer can teleport back to this region and experience + // a failure because the old ScenePresence has not yet been cleaned up. + Thread.Sleep(2000); + + sp.Close(); + sp.Scene.IncomingCloseAgent(sp.UUID); } else { - sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); + // now we have a child agent in this region. + sp.Reset(); + } + + // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! + if (sp.Scene.NeedSceneCacheClear(sp.UUID)) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", + sp.UUID); } } -- cgit v1.1 From cd225215b1284b4a50e5ebb928c1aecc3f005e05 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 May 2012 22:40:24 +0100 Subject: Now that the EntityTransferModule is per-region, fetch the event queue module once rather than repeatedly via scene presences --- .../EntityTransfer/EntityTransferModule.cs | 40 ++++++++++++---------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 4988e93..361e453 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -73,6 +73,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer private ExpiringCache> m_bannedRegions = new ExpiringCache>(); + private IEventQueue m_eqModule; + #region ISharedRegionModule public Type ReplaceableInterface @@ -147,7 +149,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public virtual void RemoveRegion(Scene scene) {} - public virtual void RegionLoaded(Scene scene) {} + public virtual void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + m_eqModule = m_scene.RequestModuleInterface(); + } #endregion @@ -398,8 +406,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - IEventQueue eq = sp.Scene.RequestModuleInterface(); - uint newRegionX = (uint)(reg.RegionHandle >> 40); uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); @@ -416,7 +422,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); ResetFromTransit(sp.UUID); - + return; } @@ -516,16 +522,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); - if (eq != null) + if (m_eqModule != null) { - eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); + m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID); // ES makes the client send a UseCircuitCode message to the destination, // which triggers a bunch of things there. // So let's wait Thread.Sleep(200); - eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); + m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); } else @@ -564,10 +570,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); - if (eq != null) + if (m_eqModule != null) { - eq.TeleportFinishEvent(destinationHandle, 13, endPoint, - 0, teleportFlags, capsPath, sp.UUID); + m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); } else { @@ -1122,11 +1127,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); - IEventQueue eq = agent.Scene.RequestModuleInterface(); - if (eq != null) + if (m_eqModule != null) { - eq.CrossRegion(neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, - capsPath, agent.UUID, agent.ControllingClient.SessionId); + m_eqModule.CrossRegion( + neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, + capsPath, agent.UUID, agent.ControllingClient.SessionId); } else { @@ -1474,8 +1479,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (regionAccepted && newAgent) { - IEventQueue eq = sp.Scene.RequestModuleInterface(); - if (eq != null) + if (m_eqModule != null) { #region IP Translation for NAT IClientIPEndpoint ipepClient; @@ -1489,8 +1493,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "and EstablishAgentCommunication with seed cap {4}", scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); - eq.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); - eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); + m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); + m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); } else { -- cgit v1.1 From cc53d91d2f53adf952703f7fb91a7ab33c7a5d8a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 May 2012 22:46:45 +0100 Subject: On inter-region teleport, only stand the avatar up if the QueryAccess call to the destination scene actually succeeds. --- .../Framework/EntityTransfer/EntityTransferModule.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 361e453..5afe553 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -153,7 +153,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { if (!m_Enabled) return; - + m_eqModule = m_scene.RequestModuleInterface(); } @@ -426,11 +426,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - // Fixing a bug where teleporting while sitting results in the avatar ending up removed from - // both regions - if (sp.ParentID != (uint)0) - sp.StandUp(); - if (!sp.ValidateAttachments()) m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", @@ -457,7 +452,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); + + // Fixing a bug where teleporting while sitting results in the avatar ending up removed from + // both regions + if (sp.ParentID != (uint)0) + sp.StandUp(); sp.ControllingClient.SendTeleportStart(teleportFlags); -- cgit v1.1 From 93ff27053a2d46a934bb6a1780ccfecd505ab44f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 May 2012 22:59:52 +0100 Subject: Don't actually proceed on a within-region teleport if another is already taking place, rather than just (falsely) logging that we're not going to proceed. An oversight from recent commit 9ab0c81 --- .../Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 5afe553..b5717cd 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -227,6 +227,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Ignoring within region teleport request of {0} {1} to {2} - agent is already in transit.", sp.Name, sp.UUID, position); + + return; } // Teleport within the same region -- cgit v1.1 From 7cceab12956dcb8ebeff129375888541831f7976 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 May 2012 01:41:00 +0100 Subject: In remote QueryAccess, also receive the actual status (true|false) instead of always true no matter what the callee actually returned. This was due to two things 1) SimulationServiceConnector.QueryAccess was always looking to the outer result["success"]. But if a "_Result" map is returned (which is certainly the case right now), then the true success is _Result["success"], result["success"] is always true no matter what 2) If QueryAccess was false at the destination, then AgentHandlers.DoQueryAccess() was never putting this in the result. The default action of SerializeJsonString() is not to put false booleans in the JSON!!!, so this has to be explicitly set. --- OpenSim/Server/Handlers/Simulation/AgentHandlers.cs | 7 +++++-- .../Services/Connectors/Simulation/SimulationServiceConnector.cs | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index 99ae7f0..012b14e 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -144,13 +144,16 @@ namespace OpenSim.Server.Handlers.Simulation responsedata["int_response_code"] = HttpStatusCode.OK; - OSDMap resp = new OSDMap(2); + OSDMap resp = new OSDMap(3); resp["success"] = OSD.FromBoolean(result); resp["reason"] = OSD.FromString(reason); resp["version"] = OSD.FromString(version); - responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); + // We must preserve defaults here, otherwise a false "success" will not be put into the JSON map! + responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp, true); + +// Console.WriteLine("str_response_string [{0}]", responsedata["str_response_string"]); } protected virtual void DoAgentGet(Hashtable request, Hashtable responsedata, UUID id, UUID regionID) diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index cc46ba8..032beb5 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -320,6 +320,10 @@ namespace OpenSim.Services.Connectors.Simulation { OSDMap data = (OSDMap)result["_Result"]; + // FIXME: If there is a _Result map then it's the success key here that indicates the true success + // or failure, not the sibling result node. + success = data["success"]; + reason = data["reason"].AsString(); if (data["version"] != null && data["version"].AsString() != string.Empty) version = data["version"].AsString(); -- cgit v1.1 From 40c78b06246d1131e07982dc6a9366666d9ea031 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 May 2012 02:02:53 +0100 Subject: Stop it being possible for an agent to teleport back to its source region before the source region has finished cleaning up old agent data and structures. If this is allowed, then the client usually gets forcibly logged out and data structures might be put into bad states. To prevent this, the binary state machine of EMT.m_agentsInTransit is replaced with a 4 state machine (Preparing, Transferring, ReceivedAtDestination, CleaningUp). This is necessary because the source region needs to know when the destination region has received the user but a teleport back cannot happen until the source region has cleaned up. Tested on standalone, grid and with v1 and v3 clients. --- .../EntityTransfer/EntityTransferModule.cs | 189 ++++++++++++++++++--- .../Framework/Interfaces/IEntityTransferModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 6 +- 3 files changed, 169 insertions(+), 28 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index b5717cd..ddb621d 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -46,6 +46,29 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { + /// + /// The possible states that an agent can be in when its being transferred between regions. + /// + /// + /// This is a state machine. + /// + /// [Entry] => Preparing + /// Preparing => { Transferring || CleaningUp || [Exit] } + /// Transferring => { ReceivedAtDestination || CleaningUp } + /// ReceivedAtDestination => CleaningUp + /// CleaningUp => [Exit] + /// + /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp + /// However, any state can transition to CleaningUp if the teleport has failed. + /// + enum AgentTransferState + { + Preparing, // The agent is being prepared for transfer + Transferring, // The agent is in the process of being transferred to a destination + ReceivedAtDestination, // The destination has notified us that the agent has been successfully received + CleaningUp // The agent is being changed to child/removed after a transfer + } + public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -68,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected Scene m_scene; - protected List m_agentsInTransit; + private Dictionary m_agentsInTransit; private ExpiringCache> m_bannedRegions = new ExpiringCache>(); @@ -120,7 +143,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer MaxTransferDistance = DefaultMaxTransferDistance; } - m_agentsInTransit = new List(); + m_agentsInTransit = new Dictionary(); m_Enabled = true; } @@ -259,17 +282,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer position.Z = newPosZ; } + UpdateInTransit(sp.UUID, AgentTransferState.Transferring); + sp.ControllingClient.SendTeleportStart(teleportFlags); sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); sp.Velocity = Vector3.Zero; sp.Teleport(position); + UpdateInTransit(sp.UUID, AgentTransferState.ReceivedAtDestination); + foreach (SceneObjectGroup grp in sp.GetAttachments()) { sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); } + UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); ResetFromTransit(sp.UUID); } @@ -454,7 +482,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); // Fixing a bug where teleporting while sitting results in the avatar ending up removed from // both regions @@ -508,6 +536,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } + // Past this point we have to attempt clean up if the teleport fails, so update transfer state. + UpdateInTransit(sp.UUID, AgentTransferState.Transferring); + // OK, it got this agent. Let's close some child agents sp.CloseChildAgents(newRegionX, newRegionY); @@ -598,6 +629,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } + UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); + // For backwards compatibility if (version == "Unknown" || version == string.Empty) { @@ -624,8 +657,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before // they regard the new region as the current region after receiving the AgentMovementComplete // response. If close is sent before then, it will cause the viewer to quit instead. - // However, if this delay is longer, then a viewer can teleport back to this region and experience - // a failure because the old ScenePresence has not yet been cleaned up. + // + // This sleep can be increased if necessary. However, whilst it's active, + // an agent cannot teleport back to this region if it has teleported away. Thread.Sleep(2000); sp.Close(); @@ -644,6 +678,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", sp.UUID); } + + ResetFromTransit(sp.UUID); } protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) @@ -1089,6 +1125,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); agent.RemoveFromPhysicalScene(); + SetInTransit(agent.UUID); AgentData cAgent = new AgentData(); @@ -1100,6 +1137,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // We don't need the callback anymnore cAgent.CallbackURI = String.Empty; + // Beyond this point, extra cleanup is needed beyond removing transit state + UpdateInTransit(agent.UUID, AgentTransferState.Transferring); + if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) { // region doesn't take it @@ -1141,8 +1181,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer capsPath); } - // SUCCESS! + // SUCCESS! + UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); + + // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. + UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); + agent.MakeChildAgent(); + + // FIXME: Possibly this should occur lower down after other commands to close other agents, + // but not sure yet what the side effects would be. ResetFromTransit(agent.UUID); // now we have a child agent in this region. Request all interesting data about other (root) agents @@ -1622,7 +1670,37 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Agent Arrived public void AgentArrivedAtDestination(UUID id) { - ResetFromTransit(id); + lock (m_agentsInTransit) + { + if (!m_agentsInTransit.ContainsKey(id)) + { + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but no teleport request is active", + m_scene.RegionInfo.RegionName, id); + + return; + } + + AgentTransferState currentState = m_agentsInTransit[id]; + + if (currentState == AgentTransferState.ReceivedAtDestination) + { + // An anomoly but don't make this an outright failure - destination region could be overzealous in sending notification. + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but notification has already previously been received", + m_scene.RegionInfo.RegionName, id); + } + else if (currentState != AgentTransferState.Transferring) + { + m_log.ErrorFormat( + "[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but agent is in transfer state {2}", + m_scene.RegionInfo.RegionName, id, currentState); + + return; + } + + m_agentsInTransit[id] = AgentTransferState.ReceivedAtDestination; + } } #endregion @@ -1964,10 +2042,29 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Misc - protected bool WaitForCallback(UUID id) + private bool WaitForCallback(UUID id) { + lock (m_agentsInTransit) + { + if (!IsInTransit(id)) + throw new Exception( + string.Format( + "Asked to wait for destination callback for agent with ID {0} but it is not in transit")); + + AgentTransferState currentState = m_agentsInTransit[id]; + + if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination) + throw new Exception( + string.Format( + "Asked to wait for destination callback for agent with ID {0} but it is in state {1}", + currentState)); + } + int count = 200; - while (m_agentsInTransit.Contains(id) && count-- > 0) + + // There should be no race condition here since no other code should be removing the agent transfer or + // changing the state to another other than Transferring => ReceivedAtDestination. + while (m_agentsInTransit[id] != AgentTransferState.ReceivedAtDestination && count-- > 0) { // m_log.Debug(" >>> Waiting... " + count); Thread.Sleep(100); @@ -1977,17 +2074,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } /// - /// Set that an agent is in the process of being teleported. + /// Set that an agent is in transit. /// /// The ID of the agent being teleported /// true if the agent was not already in transit, false if it was - protected bool SetInTransit(UUID id) + private bool SetInTransit(UUID id) { lock (m_agentsInTransit) { - if (!m_agentsInTransit.Contains(id)) + if (!m_agentsInTransit.ContainsKey(id)) { - m_agentsInTransit.Add(id); + m_agentsInTransit[id] = AgentTransferState.Preparing; return true; } } @@ -1996,29 +2093,73 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } /// - /// Show whether the given agent is being teleported. + /// Updates the state of an agent that is already in transit. /// - /// true if the agent is in the process of being teleported, false otherwise. - /// The agent ID + /// + /// + /// + /// Illegal transitions will throw an Exception + private void UpdateInTransit(UUID id, AgentTransferState newState) + { + lock (m_agentsInTransit) + { + // Illegal to try and update an agent that's not actually in transit. + if (!m_agentsInTransit.ContainsKey(id)) + throw new Exception(string.Format("Agent with ID {0} is not registered as in transit", id)); + + AgentTransferState oldState = m_agentsInTransit[id]; + + bool transitionOkay = false; + + if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) + transitionOkay = true; + else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing) + transitionOkay = true; + else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring) + transitionOkay = true; + + if (transitionOkay) + m_agentsInTransit[id] = newState; + else + throw new Exception( + string.Format( + "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2}", + id, oldState, newState)); + } + } + public bool IsInTransit(UUID id) { lock (m_agentsInTransit) - return m_agentsInTransit.Contains(id); + return m_agentsInTransit.ContainsKey(id); } /// - /// Set that an agent is no longer being teleported. + /// Removes an agent from the transit state machine. /// - /// - /// - /// true if the agent was flagged as being teleported when this method was called, false otherwise - /// - protected bool ResetFromTransit(UUID id) + /// + /// true if the agent was flagged as being teleported when this method was called, false otherwise + private bool ResetFromTransit(UUID id) { lock (m_agentsInTransit) { - if (m_agentsInTransit.Contains(id)) + if (m_agentsInTransit.ContainsKey(id)) { + AgentTransferState state = m_agentsInTransit[id]; + + if (state == AgentTransferState.Transferring || state == AgentTransferState.ReceivedAtDestination) + { + // FIXME: For now, we allow exit from any state since a thrown exception in teleport is now guranteed + // to be handled properly - ResetFromTransit() could be invoked at any step along the process + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: Agent with ID should not exit directly from state {1}, should go to {2} state first", + state, AgentTransferState.CleaningUp); + +// throw new Exception( +// "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first", +// state, AgentTransferState.CleaningUp); + } + m_agentsInTransit.Remove(id); m_log.DebugFormat( diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index 75c44d5..69be83e 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -77,8 +77,8 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Show whether the given agent is being teleported. /// - /// true if the agent is in the process of being teleported, false otherwise. /// The agent ID + /// true if the agent is in the process of being teleported, false otherwise. bool IsInTransit(UUID id); bool Cross(ScenePresence agent, bool isFlying); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 755b1e6..98a75e4 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5212,10 +5212,10 @@ namespace OpenSim.Region.Framework.Scenes { if (EntityTransferModule.IsInTransit(agentID)) { - reason = "Agent is already in transit on this region"; + reason = "Agent is still in transit from this region"; - m_log.DebugFormat( - "[SCENE]: Denying agent {0} entry into {1} since region already has them registered as in transit", + m_log.WarnFormat( + "[SCENE]: Denying agent {0} entry into {1} since region still has them registered as in transit", agentID, RegionInfo.RegionName); return false; -- cgit v1.1 From 96cde407ab0d40856fb10b3b9f304433ffe734a2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 May 2012 02:37:22 +0100 Subject: Fix bug where a failed QueryAccess to a remove region would always have the reason "Communications failure" no matter what the destination region actually returned --- .../Simulation/RemoteSimulationConnector.cs | 3 +- .../Simulation/SimulationServiceConnector.cs | 33 +++++++++++++--------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index 3d28518..f980f68 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs @@ -226,13 +226,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return m_remoteConnector.RetrieveAgent(destination, id, out agent); return false; - } public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) { reason = "Communications failure"; version = "Unknown"; + if (destination == null) return false; @@ -245,7 +245,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return m_remoteConnector.QueryAccess(destination, id, position, out version, out reason); return false; - } public bool ReleaseAgent(UUID origin, UUID id, string uri) diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index 032beb5..95c4f87 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -328,25 +328,32 @@ namespace OpenSim.Services.Connectors.Simulation if (data["version"] != null && data["version"].AsString() != string.Empty) version = data["version"].AsString(); - m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1} version {2} ({3})", uri, success, version, data["version"].AsString()); + m_log.DebugFormat( + "[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1}, reason {2}, version {3} ({4})", + uri, success, reason, version, data["version"].AsString()); } if (!success) { - if (result.ContainsKey("Message")) + // If we don't check this then OpenSimulator 0.7.3.1 and some period before will never see the + // actual failure message + if (!result.ContainsKey("_Result")) { - string message = result["Message"].AsString(); - if (message == "Service request failed: [MethodNotAllowed] MethodNotAllowed") // Old style region + if (result.ContainsKey("Message")) { - m_log.Info("[REMOTE SIMULATION CONNECTOR]: The above web util error was caused by a TP to a sim that doesn't support QUERYACCESS and can be ignored"); - return true; + string message = result["Message"].AsString(); + if (message == "Service request failed: [MethodNotAllowed] MethodNotAllowed") // Old style region + { + m_log.Info("[REMOTE SIMULATION CONNECTOR]: The above web util error was caused by a TP to a sim that doesn't support QUERYACCESS and can be ignored"); + return true; + } + + reason = result["Message"]; + } + else + { + reason = "Communications failure"; } - - reason = result["Message"]; - } - else - { - reason = "Communications failure"; } return false; @@ -356,7 +363,7 @@ namespace OpenSim.Services.Connectors.Simulation } catch (Exception e) { - m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR] QueryAcess failed with exception; {0}",e.ToString()); + m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR] QueryAcesss failed with exception; {0}",e.ToString()); } return false; -- cgit v1.1 From 9f1fc7ea8816e8a052e41b58d4cde077bc58b9e5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 May 2012 02:54:37 +0100 Subject: Remove a call stack debugging line accidentally left in from a few days ago at SceneObjectPartInventory.ApplyNextOwnerPermissions(). --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index d27d9e1..aaf9ffa 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -1027,8 +1027,6 @@ namespace OpenSim.Region.Framework.Scenes public void ApplyNextOwnerPermissions() { - Util.PrintCallStack(); - lock (m_items) { foreach (TaskInventoryItem item in m_items.Values) -- cgit v1.1 From 888210ea4af0f9d41263193d450d73eba5d866fc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 May 2012 03:06:26 +0100 Subject: refactor: make ETM.CrossAgentToNewRegionAsync neighbourRegion == null check return earlier to simplify method --- .../EntityTransfer/EntityTransferModule.cs | 182 +++++++++++---------- 1 file changed, 92 insertions(+), 90 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index ddb621d..7295383 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1106,119 +1106,121 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version) { + if (neighbourRegion == null) + return agent; + try { ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", agent.Firstname, agent.Lastname, neighbourx, neighboury, version); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", + agent.Firstname, agent.Lastname, neighbourx, neighboury, version); Scene m_scene = agent.Scene; - - if (neighbourRegion != null) - { - if (!agent.ValidateAttachments()) - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", - agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); - pos = pos + agent.Velocity; - Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); + if (!agent.ValidateAttachments()) + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", + agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); - agent.RemoveFromPhysicalScene(); + pos = pos + agent.Velocity; + Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); - SetInTransit(agent.UUID); + agent.RemoveFromPhysicalScene(); - AgentData cAgent = new AgentData(); - agent.CopyTo(cAgent); - cAgent.Position = pos; - if (isFlying) - cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; + SetInTransit(agent.UUID); - // We don't need the callback anymnore - cAgent.CallbackURI = String.Empty; + AgentData cAgent = new AgentData(); + agent.CopyTo(cAgent); + cAgent.Position = pos; + if (isFlying) + cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; - // Beyond this point, extra cleanup is needed beyond removing transit state - UpdateInTransit(agent.UUID, AgentTransferState.Transferring); + // We don't need the callback anymnore + cAgent.CallbackURI = String.Empty; - if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) - { - // region doesn't take it - ReInstantiateScripts(agent); - agent.AddToPhysicalScene(isFlying); - ResetFromTransit(agent.UUID); - return agent; - } - - //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); - agent.ControllingClient.RequestClientInfo(); - - //m_log.Debug("BEFORE CROSS"); - //Scene.DumpChildrenSeeds(UUID); - //DumpKnownRegions(); - string agentcaps; - if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) - { - m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", - neighbourRegion.RegionHandle); - return agent; - } - // No turning back - agent.IsChildAgent = true; + // Beyond this point, extra cleanup is needed beyond removing transit state + UpdateInTransit(agent.UUID, AgentTransferState.Transferring); - string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); - - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); + if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) + { + // region doesn't take it + ReInstantiateScripts(agent); + agent.AddToPhysicalScene(isFlying); + ResetFromTransit(agent.UUID); + return agent; + } - if (m_eqModule != null) - { - m_eqModule.CrossRegion( - neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, - capsPath, agent.UUID, agent.ControllingClient.SessionId); - } - else - { - agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, - capsPath); - } + //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); + agent.ControllingClient.RequestClientInfo(); - // SUCCESS! - UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); + //m_log.Debug("BEFORE CROSS"); + //Scene.DumpChildrenSeeds(UUID); + //DumpKnownRegions(); + string agentcaps; + if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) + { + m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", + neighbourRegion.RegionHandle); + return agent; + } + // No turning back + agent.IsChildAgent = true; - // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. - UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); + string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); - agent.MakeChildAgent(); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); - // FIXME: Possibly this should occur lower down after other commands to close other agents, - // but not sure yet what the side effects would be. - ResetFromTransit(agent.UUID); + if (m_eqModule != null) + { + m_eqModule.CrossRegion( + neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, + capsPath, agent.UUID, agent.ControllingClient.SessionId); + } + else + { + agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, + capsPath); + } - // now we have a child agent in this region. Request all interesting data about other (root) agents - agent.SendOtherAgentsAvatarDataToMe(); - agent.SendOtherAgentsAppearanceToMe(); + // SUCCESS! + UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); - // Backwards compatibility. Best effort - if (version == "Unknown" || version == string.Empty) - { - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); - Thread.Sleep(3000); // wait a little now that we're not waiting for the callback - CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); - } + // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. + UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); + agent.MakeChildAgent(); - // Next, let's close the child agent connections that are too far away. - agent.CloseChildAgents(neighbourx, neighboury); - - AgentHasMovedAway(agent, false); - - // the user may change their profile information in other region, - // so the userinfo in UserProfileCache is not reliable any more, delete it - // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! - if (agent.Scene.NeedSceneCacheClear(agent.UUID)) - { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); - } + // FIXME: Possibly this should occur lower down after other commands to close other agents, + // but not sure yet what the side effects would be. + ResetFromTransit(agent.UUID); + + // now we have a child agent in this region. Request all interesting data about other (root) agents + agent.SendOtherAgentsAvatarDataToMe(); + agent.SendOtherAgentsAppearanceToMe(); + + // Backwards compatibility. Best effort + if (version == "Unknown" || version == string.Empty) + { + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); + Thread.Sleep(3000); // wait a little now that we're not waiting for the callback + CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); + } + + + // Next, let's close the child agent connections that are too far away. + agent.CloseChildAgents(neighbourx, neighboury); + + AgentHasMovedAway(agent, false); + + // the user may change their profile information in other region, + // so the userinfo in UserProfileCache is not reliable any more, delete it + // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! + if (agent.Scene.NeedSceneCacheClear(agent.UUID)) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); } //m_log.Debug("AFTER CROSS"); -- cgit v1.1 From ab59c0a658c25f129255198f27704cdbbcb13d6b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 May 2012 03:39:10 +0100 Subject: on agent cross, remove from physics scene after its been placed in transit, not before. --- .../Framework/EntityTransfer/EntityTransferModule.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 7295383..a5fb0c2 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1111,6 +1111,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer try { + SetInTransit(agent.UUID); + ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); m_log.DebugFormat( @@ -1129,8 +1131,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.RemoveFromPhysicalScene(); - SetInTransit(agent.UUID); - AgentData cAgent = new AgentData(); agent.CopyTo(cAgent); cAgent.Position = pos; @@ -1146,9 +1146,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) { // region doesn't take it + UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); + ReInstantiateScripts(agent); agent.AddToPhysicalScene(isFlying); ResetFromTransit(agent.UUID); + return agent; } @@ -1208,7 +1211,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); } - // Next, let's close the child agent connections that are too far away. agent.CloseChildAgents(neighbourx, neighboury); @@ -1232,6 +1234,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.ErrorFormat( "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); + + // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. } return agent; -- cgit v1.1 From 67ebe80dd95ffa2c5e9b071497b472f9c99f00f8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 May 2012 04:03:16 +0100 Subject: Resolve some mono compiler warnings. --- .../Avatar/Attachments/AttachmentsModule.cs | 2 -- .../CoreModules/Avatar/Friends/HGFriendsModule.cs | 13 ++++++---- .../EntityTransfer/EntityTransferModule.cs | 2 +- .../EntityTransfer/HGEntityTransferModule.cs | 2 +- .../InventoryAccess/HGInventoryAccessModule.cs | 5 ++-- .../Hypergrid/HypergridServiceInConnectorModule.cs | 3 ++- .../ServiceConnectorsOut/Asset/HGAssetBroker.cs | 2 +- .../CoreModules/World/Terrain/FileLoaders/TIFF.cs | 2 +- .../World/Terrain/FileLoaders/Terragen.cs | 28 ++++++++++++---------- 9 files changed, 33 insertions(+), 26 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 510b483..88071f6 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -48,7 +48,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; - private IDialogModule m_dialogModule; private IInventoryAccessModule m_invAccessModule; /// @@ -89,7 +88,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public void RegionLoaded(Scene scene) { - m_dialogModule = m_scene.RequestModuleInterface(); m_invAccessModule = m_scene.RequestModuleInterface(); } diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index 3728b85..06f27e2 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -415,12 +415,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends protected override void StoreBackwards(UUID friendID, UUID agentID) { - Boolean agentIsLocal = true; - Boolean friendIsLocal = true; + bool agentIsLocal = true; +// bool friendIsLocal = true; + if (UserManagementModule != null) { agentIsLocal = UserManagementModule.IsLocalGridUser(agentID); - friendIsLocal = UserManagementModule.IsLocalGridUser(friendID); +// friendIsLocal = UserManagementModule.IsLocalGridUser(friendID); } // Is the requester a local user? @@ -507,7 +508,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { friendUUI = finfo.Friend; theFriendUUID = friendUUI; - UUID utmp = UUID.Zero; String url = String.Empty; String first = String.Empty, last = String.Empty, tmp = String.Empty; + UUID utmp = UUID.Zero; + string url = String.Empty; + string first = String.Empty; + string last = String.Empty; + // If it's confirming the friendship, we already have the full UUI with the secret if (Util.ParseUniversalUserIdentifier(theFriendUUID, out utmp, out url, out first, out last, out secret)) { diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index a5fb0c2..ae9fb53 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1240,7 +1240,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return agent; } - + private void CrossAgentToNewRegionCompleted(IAsyncResult iar) { CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 4124667..0fdd457 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -336,7 +336,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Let's find out if this is a foreign user or a local user IUserManagement uMan = m_scene.RequestModuleInterface(); - UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, obj.AgentId); +// UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, obj.AgentId); if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) { // local grid user diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index a71584a..cf72b58 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -364,8 +364,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Changing root inventory for user {0}", client.Name); InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID); - List fids = new List(); - List iids = new List(); + List keep = new List(); foreach (InventoryFolderBase f in content.Folders) @@ -395,4 +394,4 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess #endregion } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs index 8df1c7b..a7dd0dd 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs @@ -122,7 +122,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid ISimulationService simService = scene.RequestModuleInterface(); IFriendsSimConnector friendsConn = scene.RequestModuleInterface(); Object[] args = new Object[] { m_Config }; - IFriendsService friendsService = ServerUtils.LoadPlugin(m_LocalServiceDll, args); +// IFriendsService friendsService = ServerUtils.LoadPlugin(m_LocalServiceDll, args) + ServerUtils.LoadPlugin(m_LocalServiceDll, args); m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs index 8395f83..008465f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs @@ -149,7 +149,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset m_aScene = scene; - scene.RegisterModuleInterface(this); + m_aScene.RegisterModuleInterface(this); } public void RemoveRegion(Scene scene) diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs index 5d2f893..b416b82 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs @@ -59,7 +59,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders } //Returns true if this extension is supported for terrain save-tile - public bool SupportsTileSave() + public override bool SupportsTileSave() { return false; } diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs index 1ebf916..71c71e6 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs @@ -65,7 +65,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders bool eof = false; int fileXPoints = 0; - int fileYPoints = 0; +// int fileYPoints = 0; // Terragen file while (eof == false) @@ -75,7 +75,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders { case "SIZE": fileXPoints = bs.ReadInt16() + 1; - fileYPoints = fileXPoints; +// fileYPoints = fileXPoints; bs.ReadInt16(); break; case "XPTS": @@ -83,7 +83,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders bs.ReadInt16(); break; case "YPTS": - fileYPoints = bs.ReadInt16(); +// fileYPoints = bs.ReadInt16(); + bs.ReadInt16(); bs.ReadInt16(); break; case "ALTW": @@ -164,10 +165,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders bool eof = false; if (Encoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ") { - - int fileWidth = w; - int fileHeight = h; - +// int fileWidth = w; +// int fileHeight = h; // Terragen file while (eof == false) @@ -176,17 +175,22 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders switch (tmp) { case "SIZE": - int sztmp = bs.ReadInt16() + 1; - fileWidth = sztmp; - fileHeight = sztmp; +// int sztmp = bs.ReadInt16() + 1; +// fileWidth = sztmp; +// fileHeight = sztmp; + bs.ReadInt16(); + bs.ReadInt16(); + bs.ReadInt16(); bs.ReadInt16(); break; case "XPTS": - fileWidth = bs.ReadInt16(); +// fileWidth = bs.ReadInt16(); + bs.ReadInt16(); bs.ReadInt16(); break; case "YPTS": - fileHeight = bs.ReadInt16(); +// fileHeight = bs.ReadInt16(); + bs.ReadInt16(); bs.ReadInt16(); break; case "ALTW": -- cgit v1.1 From 120f8145fcfe2cdc4e39a92e5838a2a41eb51406 Mon Sep 17 00:00:00 2001 From: Talun Date: Wed, 23 May 2012 00:33:45 +0100 Subject: Mantis 6028 osAvatarStopAnimation not stopping animations via UUID Corrected to stop animations using the animation UUID similar to llStopAnimation. See http://opensimulator.org/wiki/OsAvatarStopAnimation --- .../ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index ad1a358..5dbd9ec 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -957,16 +957,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScenePresence target = (ScenePresence)World.Entities[avatarID]; if (target != null) { - UUID animID = UUID.Zero; - lock (m_host.TaskInventory) + UUID animID = new UUID(); + if (!UUID.TryParse(animation, out animID)) { - foreach (KeyValuePair inv in m_host.TaskInventory) + animID = UUID.Zero; + lock (m_host.TaskInventory) { - if (inv.Value.Name == animation) + foreach (KeyValuePair inv in m_host.TaskInventory) { - if (inv.Value.Type == (int)AssetType.Animation) - animID = inv.Value.AssetID; - continue; + if (inv.Value.Name == animation) + { + if (inv.Value.Type == (int)AssetType.Animation) + animID = inv.Value.AssetID; + continue; + } } } } -- cgit v1.1 From ff53add54dbc666e585b928ba51b4babb7441611 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 26 May 2012 00:36:01 +0100 Subject: refactor: replace LSL_Api.InventoryKey(string) largely with SceneObjectPartInventory.GetInventoryItem(string) Also gets llStopAnimation() to call KeyOrName rather than duplicating logic. --- .../Framework/Interfaces/IEntityInventory.cs | 13 ++++++ .../Framework/Scenes/SceneObjectPartInventory.cs | 22 +++++---- .../Shared/Api/Implementation/LSL_Api.cs | 52 +++++++--------------- 3 files changed, 42 insertions(+), 45 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 30ed7d1..4370fcc 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -164,6 +164,19 @@ namespace OpenSim.Region.Framework.Interfaces List GetInventoryItems(); /// + /// Gets an inventory item by name + /// + /// + /// This method returns the first inventory item that matches the given name. In SL this is all you need + /// since each item in a prim inventory must have a unique name. + /// + /// + /// + /// The inventory item. Null if no such item was found. + /// + TaskInventoryItem GetInventoryItem(string name); + + /// /// Get inventory items by name. /// /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index aaf9ffa..8810903 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -582,14 +582,20 @@ namespace OpenSim.Region.Framework.Scenes return item; } - /// - /// Get inventory items by name. - /// - /// - /// - /// A list of inventory items with that name. - /// If no inventory item has that name then an empty list is returned. - /// + public TaskInventoryItem GetInventoryItem(string name) + { + lock (m_items) + { + foreach (TaskInventoryItem item in m_items.Values) + { + if (item.Name == name) + return item; + } + } + + return null; + } + public List GetInventoryItems(string name) { List items = new List(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 4b28808..9908a39 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -104,9 +104,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected int m_scriptConsoleChannel = 0; protected bool m_scriptConsoleChannelEnabled = false; protected IUrlModule m_UrlModule = null; - protected Dictionary m_userInfoCache = - new Dictionary(); - protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. + protected Dictionary m_userInfoCache = new Dictionary(); + protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) { @@ -304,25 +303,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return UUID.Zero; } - protected UUID InventoryKey(string name) - { - m_host.AddScriptLPS(1); - - lock (m_host.TaskInventory) - { - foreach (KeyValuePair inv in m_host.TaskInventory) - { - if (inv.Value.Name == name) - { - return inv.Value.AssetID; - } - } - } - - return UUID.Zero; - } - - /// /// accepts a valid UUID, -or- a name of an inventory item. /// Returns a valid UUID or UUID.Zero if key invalid and item not found @@ -332,19 +312,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// protected UUID KeyOrName(string k) { - UUID key = UUID.Zero; + UUID key; // if we can parse the string as a key, use it. - if (UUID.TryParse(k, out key)) - { - return key; - } // else try to locate the name in inventory of object. found returns key, - // not found returns UUID.Zero which will translate to the default particle texture - else + // not found returns UUID.Zero + if (!UUID.TryParse(k, out key)) { - return InventoryKey(k); + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(k); + + if (item != null) + key = item.AssetID; + else + key = UUID.Zero; } + + return key; } // convert a LSL_Rotation to a Quaternion @@ -3315,17 +3298,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0) { - UUID animID = new UUID(); - - if (!UUID.TryParse(anim, out animID)) - { - animID = InventoryKey(anim); - } - ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); if (presence != null) { + UUID animID = KeyOrName(anim); + if (animID == UUID.Zero) presence.Animator.RemoveAnimation(anim); else -- cgit v1.1 From f2a5fad18f30d24cd8911de829ecb1a07b475e38 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 26 May 2012 00:54:00 +0100 Subject: Use SceneObjectPartInventory.GetInventoryItem() in OSSL.AvatarStopAnimation instead of searching the task inventory manually. --- .../Shared/Api/Implementation/OSSL_Api.cs | 26 ++++++++++------------ 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 5dbd9ec..7ea8b7a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -952,27 +952,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID avatarID = (UUID)avatar; m_host.AddScriptLPS(1); + + // FIXME: What we really want to do here is factor out the similar code in llStopAnimation() to a common + // method (though see that doesn't do the is animation check, which is probably a bug) and have both + // these functions call that common code. However, this does mean navigating the brain-dead requirement + // of calling InitLSL() if (World.Entities.ContainsKey(avatarID) && World.Entities[avatarID] is ScenePresence) { ScenePresence target = (ScenePresence)World.Entities[avatarID]; if (target != null) { - UUID animID = new UUID(); + UUID animID; + if (!UUID.TryParse(animation, out animID)) { - animID = UUID.Zero; - lock (m_host.TaskInventory) - { - foreach (KeyValuePair inv in m_host.TaskInventory) - { - if (inv.Value.Name == animation) - { - if (inv.Value.Type == (int)AssetType.Animation) - animID = inv.Value.AssetID; - continue; - } - } - } + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(animation); + if (item != null && item.Type == (int)AssetType.Animation) + animID = item.AssetID; + else + animID = UUID.Zero; } if (animID == UUID.Zero) -- cgit v1.1 From d6476b627752c99a6aea5093d080d3633aa6dde8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 26 May 2012 01:03:53 +0100 Subject: Use GetInventoryItem() in LSL_Api.InventoryKey(string name, int type). Also removes small bug where calling this method would add 1 to LPS, evne though all callers already did this. --- .../Shared/Api/Implementation/LSL_Api.cs | 24 +++++++--------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 9908a39..6438bcc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -284,23 +284,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected UUID InventoryKey(string name, int type) { - m_host.AddScriptLPS(1); + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); - lock (m_host.TaskInventory) - { - foreach (KeyValuePair inv in m_host.TaskInventory) - { - if (inv.Value.Name == name) - { - if (inv.Value.Type != type) - return UUID.Zero; - - return inv.Value.AssetID; - } - } - } - - return UUID.Zero; + if (item != null && item.Type == type) + return item.AssetID; + else + return UUID.Zero; } /// @@ -1707,14 +1696,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return rgb; } + if (face >= 0 && face < GetNumberOfSides(part)) { texcolor = tex.GetFace((uint)face).RGBA; rgb.x = texcolor.R; rgb.y = texcolor.G; rgb.z = texcolor.B; + return rgb; - } else { -- cgit v1.1 From 33b66009e43fa7c488b06c557dc46273288750d4 Mon Sep 17 00:00:00 2001 From: Blake.Bourque Date: Wed, 23 May 2012 07:38:03 -0400 Subject: One can now get hyoergrid region co-ordinates with llRequestSimulatorData --- .../Shared/Api/Implementation/LSL_Api.cs | 26 +++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 6438bcc..84493b1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9098,7 +9098,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api GridRegion info; - if (m_ScriptEngine.World.RegionInfo.RegionName == simulator) + if (m_ScriptEngine.World.RegionInfo.RegionName == simulator) //Det data for this simulator? + info = new GridRegion(m_ScriptEngine.World.RegionInfo); else info = m_ScriptEngine.World.GridService.GetRegionByName(m_ScriptEngine.World.RegionInfo.ScopeID, simulator); @@ -9111,10 +9112,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScriptSleep(1000); return UUID.Zero.ToString(); } - reply = new LSL_Vector( - info.RegionLocX, - info.RegionLocY, - 0).ToString(); + if (m_ScriptEngine.World.RegionInfo.RegionName != simulator) + { + //Hypergrid Region co-ordinates + uint rx = 0, ry = 0; + Utils.LongToUInts(Convert.ToUInt64(info.RegionSecret), out rx, out ry); + + reply = new LSL_Vector( + rx, + ry, + 0).ToString(); + } + else + { + //Local-cooridnates + reply = new LSL_Vector( + info.RegionLocX, + info.RegionLocY, + 0).ToString(); + } break; case ScriptBaseClass.DATA_SIM_STATUS: if (info != null) -- cgit v1.1 From 3ac3be99ae73aae1bf9b3cfad7dfd6c018357c83 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 26 May 2012 01:35:33 +0100 Subject: Add Blake/Techplex to CONTRIBUTORS. Thanks! --- CONTRIBUTORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 8350802..608a032 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -146,6 +146,7 @@ what it is today. * Stefan_Boom / stoehr * Strawberry Fride * Talun +* TechplexEngineer (Blake Bourque) * TBG Renfold * tglion * tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud) -- cgit v1.1 From 43a6f286209e87ebaeabc9e1f966444fa2fac18e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 26 May 2012 01:55:35 +0100 Subject: If restating a region, clean up the physics scene after the main scene has been closed not before. If this is done before then on ODE agent update calls still incoming can fail as they try to use a raycastmanager that has been disposed. Bullet plugin does nothing on Dispose() However, I wouldn't be at all surprised if individual region restarting was buggy in lots of other areas. --- OpenSim/Region/Framework/Scenes/Scene.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 98a75e4..ce386be 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1032,13 +1032,13 @@ namespace OpenSim.Region.Framework.Scenes } } + m_log.Error("[REGION]: Closing"); + Close(); + if (PhysicsScene != null) { PhysicsScene.Dispose(); - } - - m_log.Error("[REGION]: Closing"); - Close(); + } m_log.Error("[REGION]: Firing Region Restart Message"); -- cgit v1.1 From 0b72f773c7df849b335895d7c7a6cfe949f59f00 Mon Sep 17 00:00:00 2001 From: Talun Date: Tue, 22 May 2012 23:06:40 +0100 Subject: Mantis 6025 llRequestPermissions auto grant for NPCs. If the script requesting permissions is owned by either the NPC or the NPCs owner (if the NPC is created as owned) then grant any permissions automatically. --- .../Shared/Api/Implementation/LSL_Api.cs | 24 +++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 84493b1..f3787a0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3406,9 +3406,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } ScenePresence presence = World.GetScenePresence(agentID); - if (presence != null) { + // If permissions are being requested from an NPC and were not implicitly granted above then + // auto grant all reuqested permissions if the script is owned by the NPC or the NPCs owner + INPCModule npcModule = World.RequestModuleInterface(); + if (npcModule != null && npcModule.IsNPC(agentID, World)) + { + if (agentID == m_host.ParentGroup.OwnerID || npcModule.GetOwner(agentID) == m_host.ParentGroup.OwnerID) + { + lock (m_host.TaskInventory) + { + m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; + m_host.TaskInventory[m_item.ItemID].PermsMask = perm; + } + + m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( + "run_time_permissions", new Object[] { + new LSL_Integer(perm) }, + new DetectParams[0])); + } + // it is an NPC, exit even if the permissions werent granted above, they are not going to answer + // the question! + return; + } + string ownerName = resolveName(m_host.ParentGroup.RootPart.OwnerID); if (ownerName == String.Empty) ownerName = "(hippos)"; -- cgit v1.1 From 7fd38788b4a654983c11efbcddb107feb4b3634a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 26 May 2012 02:14:32 +0100 Subject: minor: code formatting from 0b72f773 --- .../Shared/Api/Implementation/LSL_Api.cs | 23 +++++++++++----------- 1 file changed, 11 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 f3787a0..deb68b8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3421,11 +3421,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.TaskInventory[m_item.ItemID].PermsMask = perm; } - m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( - "run_time_permissions", new Object[] { - new LSL_Integer(perm) }, - new DetectParams[0])); + m_ScriptEngine.PostScriptEvent( + m_item.ItemID, + new EventParams( + "run_time_permissions", new Object[] { new LSL_Integer(perm) }, new DetectParams[0])); } + // it is an NPC, exit even if the permissions werent granted above, they are not going to answer // the question! return; @@ -3454,10 +3455,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } // Requested agent is not in range, refuse perms - m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( - "run_time_permissions", new Object[] { - new LSL_Integer(0) }, - new DetectParams[0])); + m_ScriptEngine.PostScriptEvent( + m_item.ItemID, + new EventParams("run_time_permissions", new Object[] { new LSL_Integer(0) }, new DetectParams[0])); } void handleScriptAnswer(IClientAPI client, UUID taskID, UUID itemID, int answer) @@ -3476,10 +3476,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.TaskInventory[m_item.ItemID].PermsMask = answer; } - m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( - "run_time_permissions", new Object[] { - new LSL_Integer(answer) }, - new DetectParams[0])); + m_ScriptEngine.PostScriptEvent( + m_item.ItemID, + new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); } public LSL_String llGetPermissionsKey() -- cgit v1.1 From 8f87f55d053a69bf1f5b2758d51871c4c76e15b9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 28 May 2012 22:14:37 +0100 Subject: If handling the failure of teleport, move agent state to CleaningUp when we start the handling. Also fixes the log warning from ResetInTransit() if the state is cleared direct from Transferring or ReceiveAtDestination, as pointed out in mantis 5426 --- .../CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index ae9fb53..ab1424d 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -684,13 +684,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) { + UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); + // Client never contacted destination. Let's restore everything back sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); // Fail. Reset it back sp.IsChildAgent = false; ReInstantiateScripts(sp); - ResetFromTransit(sp.UUID); EnableChildAgents(sp); @@ -698,6 +699,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_scene.SimulationService.CloseAgent(finalDestination, sp.UUID); sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); + + ResetFromTransit(sp.UUID); } protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) @@ -2158,8 +2161,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // FIXME: For now, we allow exit from any state since a thrown exception in teleport is now guranteed // to be handled properly - ResetFromTransit() could be invoked at any step along the process m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: Agent with ID should not exit directly from state {1}, should go to {2} state first", - state, AgentTransferState.CleaningUp); + "[ENTITY TRANSFER MODULE]: Agent with ID {0} should not exit directly from state {1}, should go to {2} state first", + id, state, AgentTransferState.CleaningUp); // throw new Exception( // "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first", -- cgit v1.1 From 79f3ce2e9f3563165ee640f917f944ec4b370ac7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 28 May 2012 23:06:00 +0100 Subject: refactor: factor out entity transfer state machine into a separate class to make code more analyzable --- .../EntityTransfer/EntityTransferModule.cs | 284 ++++----------------- .../EntityTransfer/EntityTransferStateMachine.cs | 269 +++++++++++++++++++ .../EntityTransfer/HGEntityTransferModule.cs | 16 +- 3 files changed, 330 insertions(+), 239 deletions(-) create mode 100644 OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index ab1424d..f2926ea 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -46,35 +46,12 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { - /// - /// The possible states that an agent can be in when its being transferred between regions. - /// - /// - /// This is a state machine. - /// - /// [Entry] => Preparing - /// Preparing => { Transferring || CleaningUp || [Exit] } - /// Transferring => { ReceivedAtDestination || CleaningUp } - /// ReceivedAtDestination => CleaningUp - /// CleaningUp => [Exit] - /// - /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp - /// However, any state can transition to CleaningUp if the teleport has failed. - /// - enum AgentTransferState - { - Preparing, // The agent is being prepared for transfer - Transferring, // The agent is in the process of being transferred to a destination - ReceivedAtDestination, // The destination has notified us that the agent has been successfully received - CleaningUp // The agent is being changed to child/removed after a transfer - } - public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public const int DefaultMaxTransferDistance = 4095; - public const bool EnableWaitForCallbackFromTeleportDestDefault = true; + public const bool WaitForAgentArrivedAtDestinationDefault = true; /// /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer. @@ -85,13 +62,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// If true then on a teleport, the source region waits for a callback from the destination region. If /// a callback fails to arrive within a set time then the user is pulled back into the source region. /// - public bool EnableWaitForCallbackFromTeleportDest { get; set; } + public bool WaitForAgentArrivedAtDestination { get; set; } protected bool m_Enabled = false; - protected Scene m_scene; + public Scene Scene { get; private set; } - private Dictionary m_agentsInTransit; + /// + /// Handles recording and manipulation of state for entities that are in transfer within or between regions + /// (cross or teleport). + /// + private EntityTransferStateMachine m_entityTransferStateMachine; private ExpiringCache> m_bannedRegions = new ExpiringCache>(); @@ -133,8 +114,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer IConfig transferConfig = source.Configs["EntityTransfer"]; if (transferConfig != null) { - EnableWaitForCallbackFromTeleportDest - = transferConfig.GetBoolean("wait_for_callback", EnableWaitForCallbackFromTeleportDestDefault); + WaitForAgentArrivedAtDestination + = transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault); MaxTransferDistance = transferConfig.GetInt("max_distance", DefaultMaxTransferDistance); } @@ -143,7 +124,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer MaxTransferDistance = DefaultMaxTransferDistance; } - m_agentsInTransit = new Dictionary(); + m_entityTransferStateMachine = new EntityTransferStateMachine(this); + m_Enabled = true; } @@ -156,7 +138,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!m_Enabled) return; - m_scene = scene; + Scene = scene; scene.RegisterModuleInterface(this); scene.EventManager.OnNewClient += OnNewClient; @@ -177,7 +159,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!m_Enabled) return; - m_eqModule = m_scene.RequestModuleInterface(); + m_eqModule = Scene.RequestModuleInterface(); } #endregion @@ -226,7 +208,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer e.Message, e.StackTrace); // Make sure that we clear the in-transit flag so that future teleport attempts don't always fail. - ResetFromTransit(sp.UUID); + m_entityTransferStateMachine.ResetFromTransit(sp.UUID); sp.ControllingClient.SendTeleportFailed("Internal error"); } @@ -245,7 +227,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", sp.Name, position, sp.Scene.RegionInfo.RegionName); - if (!SetInTransit(sp.UUID)) + if (!m_entityTransferStateMachine.SetInTransit(sp.UUID)) { m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Ignoring within region teleport request of {0} {1} to {2} - agent is already in transit.", @@ -282,7 +264,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer position.Z = newPosZ; } - UpdateInTransit(sp.UUID, AgentTransferState.Transferring); + m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); sp.ControllingClient.SendTeleportStart(teleportFlags); @@ -290,15 +272,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.Velocity = Vector3.Zero; sp.Teleport(position); - UpdateInTransit(sp.UUID, AgentTransferState.ReceivedAtDestination); + m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.ReceivedAtDestination); foreach (SceneObjectGroup grp in sp.GetAttachments()) { sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); } - UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); - ResetFromTransit(sp.UUID); + m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); + m_entityTransferStateMachine.ResetFromTransit(sp.UUID); } /// @@ -316,7 +298,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { uint x = 0, y = 0; Utils.LongToUInts(regionHandle, out x, out y); - GridRegion reg = m_scene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); + GridRegion reg = Scene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); if (reg != null) { @@ -398,7 +380,7 @@ 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 (!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.", @@ -410,7 +392,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (reg == null || finalDestination == null) { sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); - ResetFromTransit(sp.UUID); + m_entityTransferStateMachine.ResetFromTransit(sp.UUID); return; } @@ -431,7 +413,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, MaxTransferDistance)); - ResetFromTransit(sp.UUID); + m_entityTransferStateMachine.ResetFromTransit(sp.UUID); return; } @@ -451,7 +433,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (endPoint.Address == null) { sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); - ResetFromTransit(sp.UUID); + m_entityTransferStateMachine.ResetFromTransit(sp.UUID); return; } @@ -469,11 +451,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer string reason; string version; - if (!m_scene.SimulationService.QueryAccess( + if (!Scene.SimulationService.QueryAccess( finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) { sp.ControllingClient.SendTeleportFailed(reason); - ResetFromTransit(sp.UUID); + m_entityTransferStateMachine.ResetFromTransit(sp.UUID); m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", @@ -527,7 +509,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) { sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); - ResetFromTransit(sp.UUID); + m_entityTransferStateMachine.ResetFromTransit(sp.UUID); m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", @@ -537,7 +519,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } // Past this point we have to attempt clean up if the teleport fails, so update transfer state. - UpdateInTransit(sp.UUID, AgentTransferState.Transferring); + m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); // OK, it got this agent. Let's close some child agents sp.CloseChildAgents(newRegionX, newRegionY); @@ -619,7 +601,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation // that the client contacted the destination before we close things here. - if (EnableWaitForCallbackFromTeleportDest && !WaitForCallback(sp.UUID)) + if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID)) { m_log.WarnFormat( "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", @@ -629,7 +611,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); + m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); // For backwards compatibility if (version == "Unknown" || version == string.Empty) @@ -679,12 +661,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.UUID); } - ResetFromTransit(sp.UUID); + m_entityTransferStateMachine.ResetFromTransit(sp.UUID); } protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) { - UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); + m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); // Client never contacted destination. Let's restore everything back sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); @@ -696,17 +678,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer EnableChildAgents(sp); // Finally, kill the agent we just created at the destination. - m_scene.SimulationService.CloseAgent(finalDestination, sp.UUID); + Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); - ResetFromTransit(sp.UUID); + m_entityTransferStateMachine.ResetFromTransit(sp.UUID); } protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) { logout = false; - bool success = m_scene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); + bool success = Scene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); if (success) sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout); @@ -716,7 +698,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) { - return m_scene.SimulationService.UpdateAgent(finalDestination, agent); + return Scene.SimulationService.UpdateAgent(finalDestination, agent); } protected virtual void SetCallbackURL(AgentData agent, RegionInfo region) @@ -779,7 +761,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm) { - GridRegion info = m_scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); + GridRegion info = Scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); if (info == null) { @@ -800,12 +782,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); - //OpenSim.Services.Interfaces.PresenceInfo pinfo = m_scene.PresenceService.GetAgent(client.SessionId); - GridUserInfo uinfo = m_scene.GridUserService.GetGridUserInfo(client.AgentId.ToString()); + //OpenSim.Services.Interfaces.PresenceInfo pinfo = Scene.PresenceService.GetAgent(client.SessionId); + GridUserInfo uinfo = Scene.GridUserService.GetGridUserInfo(client.AgentId.ToString()); if (uinfo != null) { - GridRegion regionInfo = m_scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); + GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); if (regionInfo == null) { // can't find the Home region: Tell viewer and abort @@ -1114,7 +1096,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer try { - SetInTransit(agent.UUID); + m_entityTransferStateMachine.SetInTransit(agent.UUID); ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); @@ -1144,16 +1126,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer cAgent.CallbackURI = String.Empty; // Beyond this point, extra cleanup is needed beyond removing transit state - UpdateInTransit(agent.UUID, AgentTransferState.Transferring); + m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) { // region doesn't take it - UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); + m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); ReInstantiateScripts(agent); agent.AddToPhysicalScene(isFlying); - ResetFromTransit(agent.UUID); + m_entityTransferStateMachine.ResetFromTransit(agent.UUID); return agent; } @@ -1191,16 +1173,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } // SUCCESS! - UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); + m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. - UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); + m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); agent.MakeChildAgent(); // FIXME: Possibly this should occur lower down after other commands to close other agents, // but not sure yet what the side effects would be. - ResetFromTransit(agent.UUID); + m_entityTransferStateMachine.ResetFromTransit(agent.UUID); // now we have a child agent in this region. Request all interesting data about other (root) agents agent.SendOtherAgentsAvatarDataToMe(); @@ -1675,41 +1657,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion - #region Agent Arrived + public void AgentArrivedAtDestination(UUID id) { - lock (m_agentsInTransit) - { - if (!m_agentsInTransit.ContainsKey(id)) - { - m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but no teleport request is active", - m_scene.RegionInfo.RegionName, id); - - return; - } - - AgentTransferState currentState = m_agentsInTransit[id]; - - if (currentState == AgentTransferState.ReceivedAtDestination) - { - // An anomoly but don't make this an outright failure - destination region could be overzealous in sending notification. - m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but notification has already previously been received", - m_scene.RegionInfo.RegionName, id); - } - else if (currentState != AgentTransferState.Transferring) - { - m_log.ErrorFormat( - "[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but agent is in transfer state {2}", - m_scene.RegionInfo.RegionName, id, currentState); - - return; - } - - m_agentsInTransit[id] = AgentTransferState.ReceivedAtDestination; - } + m_entityTransferStateMachine.SetAgentArrivedAtDestination(id); } #endregion @@ -1979,8 +1931,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer //// And the new channel... //if (m_interregionCommsOut != null) // successYN = m_interregionCommsOut.SendCreateObject(newRegionHandle, grp, true); - if (m_scene.SimulationService != null) - successYN = m_scene.SimulationService.CreateObject(destination, newPosition, grp, true); + if (Scene.SimulationService != null) + successYN = Scene.SimulationService.CreateObject(destination, newPosition, grp, true); if (successYN) { @@ -2051,139 +2003,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Misc - private bool WaitForCallback(UUID id) - { - lock (m_agentsInTransit) - { - if (!IsInTransit(id)) - throw new Exception( - string.Format( - "Asked to wait for destination callback for agent with ID {0} but it is not in transit")); - - AgentTransferState currentState = m_agentsInTransit[id]; - - if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination) - throw new Exception( - string.Format( - "Asked to wait for destination callback for agent with ID {0} but it is in state {1}", - currentState)); - } - - int count = 200; - - // There should be no race condition here since no other code should be removing the agent transfer or - // changing the state to another other than Transferring => ReceivedAtDestination. - while (m_agentsInTransit[id] != AgentTransferState.ReceivedAtDestination && count-- > 0) - { -// m_log.Debug(" >>> Waiting... " + count); - Thread.Sleep(100); - } - - return count > 0; - } - - /// - /// Set that an agent is in transit. - /// - /// The ID of the agent being teleported - /// true if the agent was not already in transit, false if it was - private bool SetInTransit(UUID id) - { - lock (m_agentsInTransit) - { - if (!m_agentsInTransit.ContainsKey(id)) - { - m_agentsInTransit[id] = AgentTransferState.Preparing; - return true; - } - } - - return false; - } - - /// - /// Updates the state of an agent that is already in transit. - /// - /// - /// - /// - /// Illegal transitions will throw an Exception - private void UpdateInTransit(UUID id, AgentTransferState newState) - { - lock (m_agentsInTransit) - { - // Illegal to try and update an agent that's not actually in transit. - if (!m_agentsInTransit.ContainsKey(id)) - throw new Exception(string.Format("Agent with ID {0} is not registered as in transit", id)); - - AgentTransferState oldState = m_agentsInTransit[id]; - - bool transitionOkay = false; - - if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) - transitionOkay = true; - else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing) - transitionOkay = true; - else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring) - transitionOkay = true; - - if (transitionOkay) - m_agentsInTransit[id] = newState; - else - throw new Exception( - string.Format( - "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2}", - id, oldState, newState)); - } - } - public bool IsInTransit(UUID id) { - lock (m_agentsInTransit) - return m_agentsInTransit.ContainsKey(id); - } - - /// - /// Removes an agent from the transit state machine. - /// - /// - /// true if the agent was flagged as being teleported when this method was called, false otherwise - private bool ResetFromTransit(UUID id) - { - lock (m_agentsInTransit) - { - if (m_agentsInTransit.ContainsKey(id)) - { - AgentTransferState state = m_agentsInTransit[id]; - - if (state == AgentTransferState.Transferring || state == AgentTransferState.ReceivedAtDestination) - { - // FIXME: For now, we allow exit from any state since a thrown exception in teleport is now guranteed - // to be handled properly - ResetFromTransit() could be invoked at any step along the process - m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: Agent with ID {0} should not exit directly from state {1}, should go to {2} state first", - id, state, AgentTransferState.CleaningUp); - -// throw new Exception( -// "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first", -// state, AgentTransferState.CleaningUp); - } - - m_agentsInTransit.Remove(id); - - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Agent {0} cleared from transit in {1}", - id, m_scene.RegionInfo.RegionName); - - return true; - } - } - - m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: Agent {0} requested to clear from transit in {1} but was already cleared.", - id, m_scene.RegionInfo.RegionName); - - return false; + return m_entityTransferStateMachine.IsInTransit(id); } protected void ReInstantiateScripts(ScenePresence sp) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs new file mode 100644 index 0000000..d0cab49 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs @@ -0,0 +1,269 @@ +/* + * 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.Net; +using System.Reflection; +using System.Threading; +using OpenMetaverse; +using log4net; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Capabilities; +using OpenSim.Framework.Client; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Physics.Manager; +using OpenSim.Services.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +namespace OpenSim.Region.CoreModules.Framework.EntityTransfer +{ + /// + /// The possible states that an agent can be in when its being transferred between regions. + /// + /// + /// This is a state machine. + /// + /// [Entry] => Preparing + /// Preparing => { Transferring || CleaningUp || [Exit] } + /// Transferring => { ReceivedAtDestination || CleaningUp } + /// ReceivedAtDestination => CleaningUp + /// CleaningUp => [Exit] + /// + /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp + /// However, any state can transition to CleaningUp if the teleport has failed. + /// + enum AgentTransferState + { + Preparing, // The agent is being prepared for transfer + Transferring, // The agent is in the process of being transferred to a destination + ReceivedAtDestination, // The destination has notified us that the agent has been successfully received + CleaningUp // The agent is being changed to child/removed after a transfer + } + + /// + /// Records the state of entities when they are in transfer within or between regions (cross or teleport). + /// + public class EntityTransferStateMachine + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// If true then on a teleport, the source region waits for a callback from the destination region. If + /// a callback fails to arrive within a set time then the user is pulled back into the source region. + /// + public bool EnableWaitForAgentArrivedAtDestination { get; set; } + + private EntityTransferModule m_mod; + + private Dictionary m_agentsInTransit = new Dictionary(); + + public EntityTransferStateMachine(EntityTransferModule module) + { + m_mod = module; + } + + /// + /// Set that an agent is in transit. + /// + /// The ID of the agent being teleported + /// true if the agent was not already in transit, false if it was + internal bool SetInTransit(UUID id) + { + lock (m_agentsInTransit) + { + if (!m_agentsInTransit.ContainsKey(id)) + { + m_agentsInTransit[id] = AgentTransferState.Preparing; + return true; + } + } + + return false; + } + + /// + /// Updates the state of an agent that is already in transit. + /// + /// + /// + /// + /// Illegal transitions will throw an Exception + internal void UpdateInTransit(UUID id, AgentTransferState newState) + { + lock (m_agentsInTransit) + { + // Illegal to try and update an agent that's not actually in transit. + if (!m_agentsInTransit.ContainsKey(id)) + throw new Exception( + string.Format( + "Agent with ID {0} is not registered as in transit in {1}", + id, m_mod.Scene.RegionInfo.RegionName)); + + AgentTransferState oldState = m_agentsInTransit[id]; + + bool transitionOkay = false; + + if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) + transitionOkay = true; + else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing) + transitionOkay = true; + else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring) + transitionOkay = true; + + if (transitionOkay) + m_agentsInTransit[id] = newState; + else + throw new Exception( + string.Format( + "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}", + id, oldState, newState, m_mod.Scene.RegionInfo.RegionName)); + } + } + + internal bool IsInTransit(UUID id) + { + lock (m_agentsInTransit) + return m_agentsInTransit.ContainsKey(id); + } + + /// + /// Removes an agent from the transit state machine. + /// + /// + /// true if the agent was flagged as being teleported when this method was called, false otherwise + internal bool ResetFromTransit(UUID id) + { + lock (m_agentsInTransit) + { + if (m_agentsInTransit.ContainsKey(id)) + { + AgentTransferState state = m_agentsInTransit[id]; + + if (state == AgentTransferState.Transferring || state == AgentTransferState.ReceivedAtDestination) + { + // FIXME: For now, we allow exit from any state since a thrown exception in teleport is now guranteed + // to be handled properly - ResetFromTransit() could be invoked at any step along the process + m_log.WarnFormat( + "[ENTITY TRANSFER STATE MACHINE]: Agent with ID {0} should not exit directly from state {1}, should go to {2} state first in {3}", + id, state, AgentTransferState.CleaningUp, m_mod.Scene.RegionInfo.RegionName); + +// throw new Exception( +// "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first", +// state, AgentTransferState.CleaningUp); + } + + m_agentsInTransit.Remove(id); + + m_log.DebugFormat( + "[ENTITY TRANSFER STATE MACHINE]: Agent {0} cleared from transit in {1}", + id, m_mod.Scene.RegionInfo.RegionName); + + return true; + } + } + + m_log.WarnFormat( + "[ENTITY TRANSFER STATE MACHINE]: Agent {0} requested to clear from transit in {1} but was already cleared", + id, m_mod.Scene.RegionInfo.RegionName); + + return false; + } + + internal bool WaitForAgentArrivedAtDestination(UUID id) + { + if (!m_mod.WaitForAgentArrivedAtDestination) + return true; + + lock (m_agentsInTransit) + { + if (!IsInTransit(id)) + throw new Exception( + string.Format( + "Asked to wait for destination callback for agent with ID {0} in {1} but agent is not in transit", + id, m_mod.Scene.RegionInfo.RegionName)); + + AgentTransferState currentState = m_agentsInTransit[id]; + + if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination) + throw new Exception( + string.Format( + "Asked to wait for destination callback for agent with ID {0} in {1} but agent is in state {2}", + id, m_mod.Scene.RegionInfo.RegionName, currentState)); + } + + int count = 200; + + // There should be no race condition here since no other code should be removing the agent transfer or + // changing the state to another other than Transferring => ReceivedAtDestination. + while (m_agentsInTransit[id] != AgentTransferState.ReceivedAtDestination && count-- > 0) + { +// m_log.Debug(" >>> Waiting... " + count); + Thread.Sleep(100); + } + + return count > 0; + } + + internal void SetAgentArrivedAtDestination(UUID id) + { + lock (m_agentsInTransit) + { + if (!m_agentsInTransit.ContainsKey(id)) + { + m_log.WarnFormat( + "[ENTITY TRANSFER STATE MACHINE]: Region {0} received notification of arrival in destination of agent {1} but no teleport request is active", + m_mod.Scene.RegionInfo.RegionName, id); + + return; + } + + AgentTransferState currentState = m_agentsInTransit[id]; + + if (currentState == AgentTransferState.ReceivedAtDestination) + { + // An anomoly but don't make this an outright failure - destination region could be overzealous in sending notification. + m_log.WarnFormat( + "[ENTITY TRANSFER STATE MACHINE]: Region {0} received notification of arrival in destination of agent {1} but notification has already previously been received", + m_mod.Scene.RegionInfo.RegionName, id); + } + else if (currentState != AgentTransferState.Transferring) + { + m_log.ErrorFormat( + "[ENTITY TRANSFER STATE MACHINE]: Region {0} received notification of arrival in destination of agent {1} but agent is in state {2}", + m_mod.Scene.RegionInfo.RegionName, id, currentState); + + return; + } + + m_agentsInTransit[id] = AgentTransferState.ReceivedAtDestination; + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 0fdd457..43a72e2 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -117,7 +117,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected override GridRegion GetFinalDestination(GridRegion region) { - int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, region.RegionID); + int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, region.RegionID); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) @@ -139,7 +139,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) return true; - int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, reg.RegionID); + int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) return true; @@ -152,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (logout) { // Log them out of this grid - m_scene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); + Scene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); } } @@ -161,7 +161,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI); reason = string.Empty; logout = false; - int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, reg.RegionID); + int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) { // this user is going to another grid @@ -201,7 +201,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); // Let's find out if this is a foreign user or a local user - IUserManagement uMan = m_scene.RequestModuleInterface(); + IUserManagement uMan = Scene.RequestModuleInterface(); if (uMan != null && uMan.IsLocalGridUser(id)) { // local grid user @@ -265,7 +265,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - GridRegion info = m_scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); + GridRegion info = Scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); // Local region? if (info != null) @@ -335,8 +335,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } // Let's find out if this is a foreign user or a local user - IUserManagement uMan = m_scene.RequestModuleInterface(); -// UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, obj.AgentId); + IUserManagement uMan = Scene.RequestModuleInterface(); +// UserAccount account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, obj.AgentId); if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) { // local grid user -- cgit v1.1 From c46b31a9b4cc8a1a731b0e109cd2ebd52c1425d6 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 29 May 2012 16:58:08 +0200 Subject: Re-add script collisions that were lost in a merge --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 225d4c9..1adf13e 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3513,6 +3513,8 @@ namespace OpenSim.Region.Framework.Scenes } } + RaiseCollisionScriptEvents(coldata); + // Gods do not take damage and Invulnerable is set depending on parcel/region flags if (Invulnerable || GodLevel > 0) return; -- cgit v1.1 From b660c4991bf5982bc22690357e2dd6a4b015d9e9 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 29 May 2012 18:18:47 +0100 Subject: Fix collision filtering. The filter should be checked on the receiving part! --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index dc76d22..17c7661 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2023,21 +2023,21 @@ namespace OpenSim.Region.Framework.Scenes { } - private bool CollisionFilteredOut(SceneObjectPart dest, UUID objectID, string objectName) + public bool CollisionFilteredOut(UUID objectID, string objectName) { - if(dest.CollisionFilter.Count == 0) + if(CollisionFilter.Count == 0) return false; - if (dest.CollisionFilter.ContainsValue(objectID.ToString()) || - dest.CollisionFilter.ContainsValue(objectID.ToString() + objectName) || - dest.CollisionFilter.ContainsValue(UUID.Zero.ToString() + objectName)) + if (CollisionFilter.ContainsValue(objectID.ToString()) || + CollisionFilter.ContainsValue(objectID.ToString() + objectName) || + CollisionFilter.ContainsValue(UUID.Zero.ToString() + objectName)) { - if (dest.CollisionFilter.ContainsKey(1)) + if (CollisionFilter.ContainsKey(1)) return false; return true; } - if (dest.CollisionFilter.ContainsKey(1)) + if (CollisionFilter.ContainsKey(1)) return true; return false; @@ -2100,7 +2100,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); if (obj != null) { - if (!dest.CollisionFilteredOut(this, obj.UUID, obj.Name)) + if (!dest.CollisionFilteredOut(obj.UUID, obj.Name)) colliding.Add(CreateDetObject(obj)); } else @@ -2108,7 +2108,7 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence av = ParentGroup.Scene.GetScenePresence(localId); if (av != null && (!av.IsChildAgent)) { - if (!dest.CollisionFilteredOut(this, av.UUID, av.Name)) + if (!dest.CollisionFilteredOut(av.UUID, av.Name)) colliding.Add(CreateDetObject(av)); } } -- cgit v1.1 From bf0b8170f7617fe9524b691b59ca7a7b660aec30 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 29 May 2012 23:35:20 +0100 Subject: Add console command "teleport user" to allow teleport from the region console See "help teleport user" on the console for more details --- .../Avatar/Commands/UserCommandsModule.cs | 189 +++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs diff --git a/OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs b/OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs new file mode 100644 index 0000000..4bcd2ac --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs @@ -0,0 +1,189 @@ +/* + * 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 System.Text; +using System.Text.RegularExpressions; +using log4net; +using Mono.Addins; +using NDesk.Options; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Statistics; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.Avatars.Commands +{ + /// + /// A module that holds commands for manipulating objects in the scene. + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserCommandsModule")] + public class UserCommandsModule : ISharedRegionModule + { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public const string TeleportUserCommandSyntax = "teleport user "; + + public static Regex InterRegionDestinationRegex + = new Regex(@"^(?.+)/(?\d+)/(?\d+)/(?\d+)$", RegexOptions.Compiled); + + public static Regex WithinRegionDestinationRegex + = new Regex(@"^(?\d+)/(?\d+)/(?\d+)$", RegexOptions.Compiled); + + private Dictionary m_scenes = new Dictionary(); + + public string Name { get { return "User Commands Module"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { +// m_log.DebugFormat("[USER COMMANDS MODULE]: INITIALIZED MODULE"); + } + + public void PostInitialise() + { +// m_log.DebugFormat("[USER COMMANDS MODULE]: POST INITIALIZED MODULE"); + } + + public void Close() + { +// m_log.DebugFormat("[USER COMMANDS MODULE]: CLOSED MODULE"); + } + + public void AddRegion(Scene scene) + { +// m_log.DebugFormat("[USER COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); + + lock (m_scenes) + m_scenes[scene.RegionInfo.RegionID] = scene; + + scene.AddCommand( + "Users", + this, + "teleport user", + TeleportUserCommandSyntax, + "Teleport a user in this simulator to the given destination", + " is in format []///, e.g. regionone/20/30/40 or just 20/30/40 to teleport within same region." + + "\nIf the region contains a space then the whole destination must be in quotes, e.g. \"region one/20/30/40\"", + HandleTeleportUser); + } + + public void RemoveRegion(Scene scene) + { +// m_log.DebugFormat("[USER COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); + + lock (m_scenes) + m_scenes.Remove(scene.RegionInfo.RegionID); + } + + public void RegionLoaded(Scene scene) + { +// m_log.DebugFormat("[USER COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); + } + + private ScenePresence GetUser(string firstName, string lastName) + { + ScenePresence userFound = null; + + lock (m_scenes) + { + foreach (Scene scene in m_scenes.Values) + { + ScenePresence user = scene.GetScenePresence(firstName, lastName); + if (user != null && !user.IsChildAgent) + { + userFound = user; + break; + } + } + } + + return userFound; + } + + private void HandleTeleportUser(string module, string[] cmd) + { + if (cmd.Length < 5) + { + MainConsole.Instance.OutputFormat("Usage: " + TeleportUserCommandSyntax); + return; + } + + string firstName = cmd[2]; + string lastName = cmd[3]; + string rawDestination = cmd[4]; + + ScenePresence user = GetUser(firstName, lastName); + + if (user == null) + { + MainConsole.Instance.OutputFormat("No user found with name {0} {1}", firstName, lastName); + return; + } + +// MainConsole.Instance.OutputFormat("rawDestination [{0}]", rawDestination); + + Match m = WithinRegionDestinationRegex.Match(rawDestination); + + if (!m.Success) + { + m = InterRegionDestinationRegex.Match(rawDestination); + + if (!m.Success) + { + MainConsole.Instance.OutputFormat("Invalid destination {0}", rawDestination); + return; + } + } + + string regionName + = m.Groups["regionName"].Success ? m.Groups["regionName"].Value : user.Scene.RegionInfo.RegionName; + + MainConsole.Instance.OutputFormat( + "Teleporting {0} to {1},{2},{3} in {4}", + user.Name, + m.Groups["x"], m.Groups["y"], m.Groups["z"], + regionName); + + user.Scene.RequestTeleportLocation( + user.ControllingClient, + regionName, + new Vector3( + float.Parse(m.Groups["x"].Value), + float.Parse(m.Groups["y"].Value), + float.Parse(m.Groups["z"].Value)), + user.Lookat, + (uint)TeleportFlags.ViaLocation); + } + } +} \ No newline at end of file -- cgit v1.1 From 0b02a4d42e989609a4e1ba39d2aee9a7f9655613 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 31 May 2012 01:52:26 +0100 Subject: Add an optional mechanism for physics modules to collect and return arbitrary stats. If active, the physics module can return arbitrary stat counters that can be seen via the MonitoringModule (http://opensimulator.org/wiki/Monitoring_Module) This is only active in OdeScene if collect_stats = true in [ODEPhysicsSettings]. This patch allows OdeScene to collect elapsed time information for calls to the ODE native collision methods to assess what proportion of time this takes compared to total physics processing. This data is returned as ODENativeCollisionFrameMS in the monitoring module, updated every 3 seconds. The performance effect of collecting stats is probably extremely minor, dwarfed by the rest of the physics code. --- OpenSim/Region/Application/OpenSim.cs | 3 +- .../Framework/Monitoring/MonitorModule.cs | 108 +++++++++------- .../Region/Framework/Scenes/SimStatsReporter.cs | 48 ++++++- OpenSim/Region/Physics/Manager/PhysicsScene.cs | 14 +++ OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 139 +++++++++++++++++++-- bin/OpenSimDefaults.ini | 30 +++-- 6 files changed, 271 insertions(+), 71 deletions(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 6796f2b..c0913c5 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Reflection; using System.Text; @@ -138,7 +139,7 @@ namespace OpenSim m_log.Info("===================================================================="); m_log.Info("========================= STARTING OPENSIM ========================="); m_log.Info("===================================================================="); - + //m_log.InfoFormat("[OPENSIM MAIN]: GC Is Server GC: {0}", GCSettings.IsServerGC.ToString()); // http://msdn.microsoft.com/en-us/library/bb384202.aspx //GCSettings.LatencyMode = GCLatencyMode.Batch; diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs index 7f8271d..4a8c369 100644 --- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs @@ -49,7 +49,16 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring public bool Enabled { get; private set; } private Scene m_scene; - private readonly List m_monitors = new List(); + + /// + /// These are monitors where we know the static details in advance. + /// + /// + /// Dynamic monitors also exist (we don't know any of the details of what stats we get back here) + /// but these are currently hardcoded. + /// + private readonly List m_staticMonitors = new List(); + private readonly List m_alerts = new List(); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -84,9 +93,18 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring public void DebugMonitors(string module, string[] args) { - foreach (IMonitor monitor in m_monitors) + foreach (IMonitor monitor in m_staticMonitors) { - m_log.Info("[MonitorModule]: " + m_scene.RegionInfo.RegionName + " reports " + monitor.GetFriendlyName() + " = " + monitor.GetFriendlyValue()); + m_log.InfoFormat( + "[MONITOR MODULE]: {0} reports {1} = {2}", + m_scene.RegionInfo.RegionName, monitor.GetFriendlyName(), monitor.GetFriendlyValue()); + } + + foreach (KeyValuePair tuple in m_scene.StatsReporter.GetExtraSimStats()) + { + m_log.InfoFormat( + "[MONITOR MODULE]: {0} reports {1} = {2}", + m_scene.RegionInfo.RegionName, tuple.Key, tuple.Value); } } @@ -106,11 +124,12 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring { string monID = (string) request["monitor"]; - foreach (IMonitor monitor in m_monitors) + foreach (IMonitor monitor in m_staticMonitors) { string elemName = monitor.ToString(); if (elemName.StartsWith(monitor.GetType().Namespace)) elemName = elemName.Substring(monitor.GetType().Namespace.Length + 1); + if (elemName == monID || monitor.ToString() == monID) { Hashtable ereply3 = new Hashtable(); @@ -123,6 +142,9 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring } } + // FIXME: Arguably this should also be done with dynamic monitors but I'm not sure what the above code + // is even doing. Why are we inspecting the type of the monitor??? + // No monitor with that name Hashtable ereply2 = new Hashtable(); @@ -134,12 +156,18 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring } string xml = ""; - foreach (IMonitor monitor in m_monitors) + foreach (IMonitor monitor in m_staticMonitors) { string elemName = monitor.GetName(); xml += "<" + elemName + ">" + monitor.GetValue().ToString() + ""; // m_log.DebugFormat("[MONITOR MODULE]: {0} = {1}", elemName, monitor.GetValue()); } + + foreach (KeyValuePair tuple in m_scene.StatsReporter.GetExtraSimStats()) + { + xml += "<" + tuple.Key + ">" + tuple.Value + ""; + } + xml += ""; Hashtable ereply = new Hashtable(); @@ -156,20 +184,20 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring if (!Enabled) return; - m_monitors.Add(new AgentCountMonitor(m_scene)); - m_monitors.Add(new ChildAgentCountMonitor(m_scene)); - m_monitors.Add(new GCMemoryMonitor()); - m_monitors.Add(new ObjectCountMonitor(m_scene)); - m_monitors.Add(new PhysicsFrameMonitor(m_scene)); - m_monitors.Add(new PhysicsUpdateFrameMonitor(m_scene)); - m_monitors.Add(new PWSMemoryMonitor()); - m_monitors.Add(new ThreadCountMonitor()); - m_monitors.Add(new TotalFrameMonitor(m_scene)); - m_monitors.Add(new EventFrameMonitor(m_scene)); - m_monitors.Add(new LandFrameMonitor(m_scene)); - m_monitors.Add(new LastFrameTimeMonitor(m_scene)); + m_staticMonitors.Add(new AgentCountMonitor(m_scene)); + m_staticMonitors.Add(new ChildAgentCountMonitor(m_scene)); + m_staticMonitors.Add(new GCMemoryMonitor()); + m_staticMonitors.Add(new ObjectCountMonitor(m_scene)); + m_staticMonitors.Add(new PhysicsFrameMonitor(m_scene)); + m_staticMonitors.Add(new PhysicsUpdateFrameMonitor(m_scene)); + m_staticMonitors.Add(new PWSMemoryMonitor()); + m_staticMonitors.Add(new ThreadCountMonitor()); + m_staticMonitors.Add(new TotalFrameMonitor(m_scene)); + m_staticMonitors.Add(new EventFrameMonitor(m_scene)); + m_staticMonitors.Add(new LandFrameMonitor(m_scene)); + m_staticMonitors.Add(new LastFrameTimeMonitor(m_scene)); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "TimeDilationMonitor", @@ -177,7 +205,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[0], m => m.GetValue().ToString())); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "SimFPSMonitor", @@ -185,7 +213,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[1], m => string.Format("{0}", m.GetValue()))); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "PhysicsFPSMonitor", @@ -193,7 +221,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[2], m => string.Format("{0}", m.GetValue()))); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "AgentUpdatesPerSecondMonitor", @@ -201,15 +229,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[3], m => string.Format("{0} per second", m.GetValue()))); - m_monitors.Add( - new GenericMonitor( - m_scene, - "ObjectUpdatesPerSecondMonitor", - "Object Updates", - m => m.Scene.StatsReporter.LastReportedObjectUpdates, - m => string.Format("{0} per second", m.GetValue()))); - - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "ActiveObjectCountMonitor", @@ -217,7 +237,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[7], m => string.Format("{0}", m.GetValue()))); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "ActiveScriptsMonitor", @@ -225,7 +245,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[19], m => string.Format("{0}", m.GetValue()))); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "ScriptEventsPerSecondMonitor", @@ -233,7 +253,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[20], m => string.Format("{0} per second", m.GetValue()))); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "InPacketsPerSecondMonitor", @@ -241,7 +261,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[13], m => string.Format("{0} per second", m.GetValue()))); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "OutPacketsPerSecondMonitor", @@ -249,7 +269,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[14], m => string.Format("{0} per second", m.GetValue()))); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "UnackedBytesMonitor", @@ -257,7 +277,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[15], m => string.Format("{0}", m.GetValue()))); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "PendingDownloadsMonitor", @@ -265,7 +285,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[17], m => string.Format("{0}", m.GetValue()))); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "PendingUploadsMonitor", @@ -273,7 +293,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[18], m => string.Format("{0}", m.GetValue()))); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "TotalFrameTimeMonitor", @@ -281,7 +301,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[8], m => string.Format("{0} ms", m.GetValue()))); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "NetFrameTimeMonitor", @@ -289,7 +309,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[9], m => string.Format("{0} ms", m.GetValue()))); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "PhysicsFrameTimeMonitor", @@ -297,7 +317,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[10], m => string.Format("{0} ms", m.GetValue()))); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "SimulationFrameTimeMonitor", @@ -305,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[12], m => string.Format("{0} ms", m.GetValue()))); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "AgentFrameTimeMonitor", @@ -313,7 +333,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[16], m => string.Format("{0} ms", m.GetValue()))); - m_monitors.Add( + m_staticMonitors.Add( new GenericMonitor( m_scene, "ImagesFrameTimeMonitor", @@ -321,7 +341,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[11], m => string.Format("{0} ms", m.GetValue()))); - m_alerts.Add(new DeadlockAlert(m_monitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor)); + m_alerts.Add(new DeadlockAlert(m_staticMonitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor)); foreach (IAlert alert in m_alerts) { diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs index 5c56264..08d8d7c 100644 --- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs +++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs @@ -26,7 +26,7 @@ */ using System; -//using System.Collections.Generic; +using System.Collections.Generic; using System.Timers; using OpenMetaverse.Packets; using OpenSim.Framework; @@ -35,10 +35,18 @@ using OpenSim.Region.Framework.Interfaces; namespace OpenSim.Region.Framework.Scenes { + /// + /// Collect statistics from the scene to send to the client and for access by other monitoring tools. + /// + /// + /// FIXME: This should be a monitoring region module + /// public class SimStatsReporter { -// private static readonly log4net.ILog m_log -// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private static readonly log4net.ILog m_log + = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + public const string LastReportedObjectUpdateStatName = "LastReportedObjectUpdates"; public delegate void SendStatResult(SimStats stats); @@ -100,6 +108,14 @@ namespace OpenSim.Region.Framework.Scenes get { return lastReportedSimStats; } } + /// + /// Extra sim statistics that are used by monitors but not sent to the client. + /// + /// + /// The keys are the stat names. + /// + private Dictionary m_lastReportedExtraSimStats = new Dictionary(); + // Sending a stats update every 3 seconds- private int statsUpdatesEveryMS = 3000; private float statsUpdateFactor = 0; @@ -334,7 +350,20 @@ namespace OpenSim.Region.Framework.Scenes } // Extra statistics that aren't currently sent to clients - LastReportedObjectUpdates = m_objectUpdates / statsUpdateFactor; + lock (m_lastReportedExtraSimStats) + { + m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / statsUpdateFactor; + + Dictionary physicsStats = m_scene.PhysicsScene.GetStats(); + + if (physicsStats != null) + { + foreach (KeyValuePair tuple in physicsStats) + { + m_lastReportedExtraSimStats[tuple.Key] = tuple.Value / statsUpdateFactor; + } + } + } resetvalues(); } @@ -487,7 +516,10 @@ namespace OpenSim.Region.Framework.Scenes public void AddPendingDownloads(int count) { m_pendingDownloads += count; - if (m_pendingDownloads < 0) m_pendingDownloads = 0; + + if (m_pendingDownloads < 0) + m_pendingDownloads = 0; + //m_log.InfoFormat("[stats]: Adding {0} to pending downloads to make {1}", count, m_pendingDownloads); } @@ -509,5 +541,11 @@ namespace OpenSim.Region.Framework.Scenes } #endregion + + public Dictionary GetExtraSimStats() + { + lock (m_lastReportedExtraSimStats) + return new Dictionary(m_lastReportedExtraSimStats); + } } } diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 2a6163c..b32cd30 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -192,8 +192,22 @@ namespace OpenSim.Region.Physics.Manager public abstract void AddPhysicsActorTaint(PhysicsActor prim); + /// + /// Perform a simulation of the current physics scene over the given timestep. + /// + /// + /// The number of frames simulated over that period. public abstract float Simulate(float timeStep); + /// + /// Get statistics about this scene. + /// + /// This facility is currently experimental and subject to change. + /// + /// A dictionary where the key is the statistic name. If no statistics are supplied then returns null. + /// + public virtual Dictionary GetStats() { return null; } + public abstract void GetResults(); public abstract void SetTerrain(float[] heightMap); diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 409b27b..fa65945 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -131,6 +131,41 @@ namespace OpenSim.Region.Physics.OdePlugin /// internal static Object UniversalColliderSyncObject = new Object(); + /// + /// Is stats collecting enabled for this ODE scene? + /// + public bool CollectStats { get; set; } + + /// + /// Statistics for this scene. + /// + private Dictionary m_stats = new Dictionary(); + + /// + /// Stat name for recording the number of milliseconds that ODE spends in native collision code. + /// + public const string ODENativeCollisionFrameMsStatName = "ODENativeCollisionFrameMS"; + + /// + /// Used to hold tick numbers for stat collection purposes. + /// + private int m_nativeCollisionTickRecorder; + + /// + /// A messy way to tell if we need to avoid adding a collision time because this was already done in the callback. + /// + private bool m_inCollisionTiming; + + /// + /// Used in calculating physics frame time dilation + /// + private int tickCountFrameRun; + + /// + /// Used in calculating physics frame time dilation + /// + private int latertickcount; + private Random fluidRandomizer = new Random(Environment.TickCount); private const uint m_regionWidth = Constants.RegionSize; @@ -345,9 +380,6 @@ namespace OpenSim.Region.Physics.OdePlugin private OdePrim cp1; private OdeCharacter cc2; private OdePrim cp2; - private int tickCountFrameRun; - - private int latertickcount=0; //private int cStartStop = 0; //private string cDictKey = ""; @@ -440,6 +472,8 @@ namespace OpenSim.Region.Physics.OdePlugin // Initialize the mesh plugin public override void Initialise(IMesher meshmerizer, IConfigSource config) { + m_stats[ODENativeCollisionFrameMsStatName] = 0; + mesher = meshmerizer; m_config = config; // Defaults @@ -464,6 +498,8 @@ namespace OpenSim.Region.Physics.OdePlugin IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"]; if (physicsconfig != null) { + CollectStats = physicsconfig.GetBoolean("collect_stats", false); + gravityx = physicsconfig.GetFloat("world_gravityx", 0f); gravityy = physicsconfig.GetFloat("world_gravityy", 0f); gravityz = physicsconfig.GetFloat("world_gravityz", -9.8f); @@ -765,6 +801,62 @@ namespace OpenSim.Region.Physics.OdePlugin #region Collision Detection /// + /// Collides two geometries. + /// + /// + /// + /// /param> + /// + /// + /// + private int CollideGeoms( + IntPtr geom1, IntPtr geom2, int maxContacts, Ode.NET.d.ContactGeom[] contactsArray, int contactGeomSize) + { + int count; + + lock (OdeScene.UniversalColliderSyncObject) + { + // We do this inside the lock so that we don't count any delay in acquiring it + if (CollectStats) + m_nativeCollisionTickRecorder = Util.EnvironmentTickCount(); + + count = d.Collide(geom1, geom2, maxContacts, contactsArray, contactGeomSize); + } + + // We do this outside the lock so that any waiting threads aren't held up, though the effect is probably + // negligable + if (CollectStats) + m_stats[ODENativeCollisionFrameMsStatName] + += Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder); + + return count; + } + + /// + /// Collide two spaces or a space and a geometry. + /// + /// + /// /param> + /// + private void CollideSpaces(IntPtr space1, IntPtr space2, IntPtr data) + { + if (CollectStats) + { + m_inCollisionTiming = true; + m_nativeCollisionTickRecorder = Util.EnvironmentTickCount(); + } + + d.SpaceCollide2(space1, space2, data, nearCallback); + + if (CollectStats && m_inCollisionTiming) + { + m_stats[ODENativeCollisionFrameMsStatName] + += Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder); + m_inCollisionTiming = false; + } + } + + /// /// This is our near callback. A geometry is near a body /// /// The space that contains the geoms. Remember, spaces are also geoms @@ -772,6 +864,13 @@ namespace OpenSim.Region.Physics.OdePlugin /// another geometry or space private void near(IntPtr space, IntPtr g1, IntPtr g2) { + if (CollectStats && m_inCollisionTiming) + { + m_stats[ODENativeCollisionFrameMsStatName] + += Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder); + m_inCollisionTiming = false; + } + // m_log.DebugFormat("[PHYSICS]: Colliding {0} and {1} in {2}", g1, g2, space); // no lock here! It's invoked from within Simulate(), which is thread-locked @@ -789,7 +888,7 @@ namespace OpenSim.Region.Physics.OdePlugin // contact points in the space try { - d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); + CollideSpaces(g1, g2, IntPtr.Zero); } catch (AccessViolationException) { @@ -832,6 +931,7 @@ namespace OpenSim.Region.Physics.OdePlugin // Figure out how many contact points we have int count = 0; + try { // Colliding Geom To Geom @@ -843,8 +943,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) return; - lock (OdeScene.UniversalColliderSyncObject) - count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf); + count = CollideGeoms(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf); if (count > contacts.Length) m_log.Error("[ODE SCENE]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length); @@ -1578,7 +1677,7 @@ namespace OpenSim.Region.Physics.OdePlugin // and we'll run it again on all of them. try { - d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback); + CollideSpaces(space, chr.Shell, IntPtr.Zero); } catch (AccessViolationException) { @@ -1593,6 +1692,9 @@ namespace OpenSim.Region.Physics.OdePlugin //} } +// if (framecount % 55 == 0) +// m_log.DebugFormat("Processed {0} collisions", _perloopContact.Count); + List removeprims = null; foreach (OdePrim chr in _activeprims) { @@ -1604,7 +1706,7 @@ namespace OpenSim.Region.Physics.OdePlugin { if (space != IntPtr.Zero && chr.prim_geom != IntPtr.Zero && chr.m_taintremove == false) { - d.SpaceCollide2(space, chr.prim_geom, IntPtr.Zero, nearCallback); + CollideSpaces(space, chr.prim_geom, IntPtr.Zero); } else { @@ -2689,7 +2791,7 @@ namespace OpenSim.Region.Physics.OdePlugin /// It calls the methods that report back to the object owners.. (scenepresence, SceneObjectGroup) /// /// - /// + /// The number of frames simulated over that period. public override float Simulate(float timeStep) { if (framecount >= int.MaxValue) @@ -3190,7 +3292,7 @@ namespace OpenSim.Region.Physics.OdePlugin public override bool IsThreaded { // for now we won't be multithreaded - get { return (false); } + get { return false; } } #region ODE Specific Terrain Fixes @@ -3955,5 +4057,22 @@ namespace OpenSim.Region.Physics.OdePlugin ds.SetViewpoint(ref xyz, ref hpr); } #endif + + public override Dictionary GetStats() + { + if (!CollectStats) + return null; + + Dictionary returnStats; + + lock (OdeLock) + { + returnStats = new Dictionary(m_stats); + + m_stats[ODENativeCollisionFrameMsStatName] = 0; + } + + return returnStats; + } } } \ No newline at end of file diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 5da3ba2..27d86e8 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -675,6 +675,25 @@ [ODEPhysicsSettings] + ; ## + ; ## Physics stats settings + ; + + ; If collect_stats is enabled, then extra stat information is collected which is accessible via the MonitorModule + ; (see http://opensimulator.org/wiki/Monitoring_Module for more details). + collect_stats = false + + ; ## + ; ## Physics logging settings - logfiles are saved to *.DIF files + ; ## + + ; default is false + ;physics_logging = true + ;; every n simulation iterations, the physics snapshot file is updated + ;physics_logging_interval = 50 + ;; append to existing physics logfile, or overwrite existing logfiles? + ;physics_logging_append_existing_logfile = true + ;## ;## World Settings ;## @@ -824,17 +843,6 @@ mesh_physical_lod = 16 ; ## - ; ## Physics logging settings - logfiles are saved to *.DIF files - ; ## - - ; default is false - ;physics_logging = true - ;; every n simulation iterations, the physics snapshot file is updated - ;physics_logging_interval = 50 - ;; append to existing physics logfile, or overwrite existing logfiles? - ;physics_logging_append_existing_logfile = true - - ; ## ; ## Joint support ; ## -- cgit v1.1 From 878b67b333320070f643dfdd11e0a9c6ff453543 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 00:26:11 +0100 Subject: Fix OdeScene.GetTopColliders() to return the top 25 colliders rather than the first 25 that had non-zero collision scores. Also zeros collisions scores on all prims after report collection, not just the top 25. As before, this collision scores are only reset after a report is requested, which may give unrealistic numbers on the first request. So to see more realistic scores, ignore the first report and then refresh the request after a couple of seconds or so. --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 32 +++++++++++----------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index fa65945..25b3266 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -30,20 +30,21 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Threading; -using System.IO; -using System.Diagnostics; using log4net; using Nini.Config; using Ode.NET; +using OpenMetaverse; #if USE_DRAWSTUFF using Drawstuff.NET; #endif using OpenSim.Framework; using OpenSim.Region.Physics.Manager; -using OpenMetaverse; namespace OpenSim.Region.Physics.OdePlugin { @@ -3868,26 +3869,19 @@ namespace OpenSim.Region.Physics.OdePlugin public override Dictionary GetTopColliders() { - Dictionary returncolliders = new Dictionary(); - int cnt = 0; + Dictionary topColliders; + lock (_prims) { - foreach (OdePrim prm in _prims) - { - if (prm.CollisionScore > 0) - { - returncolliders.Add(prm.LocalID, prm.CollisionScore); - cnt++; - prm.CollisionScore = 0f; - if (cnt > 25) - { - break; - } - } - } + List orderedPrims = new List(_prims); + orderedPrims.OrderByDescending(p => p.CollisionScore).Take(25); + topColliders = orderedPrims.ToDictionary(p => p.LocalID, p => p.CollisionScore); + + foreach (OdePrim p in _prims) + p.CollisionScore = 0; } - return returncolliders; + return topColliders; } public override bool SupportsRayCast() -- cgit v1.1 From 93fa9e89918f41db01229c61a228724d380552ac Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 00:56:13 +0100 Subject: Add ODE avatar and prim collision numbers if extra stats collection is enabled. --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 39 ++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 25b3266..864cdc2 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -148,6 +148,16 @@ namespace OpenSim.Region.Physics.OdePlugin public const string ODENativeCollisionFrameMsStatName = "ODENativeCollisionFrameMS"; /// + /// Stat name for the number of avatar collisions with another entity. + /// + public const string ODEAvatarCollisionsStatName = "ODEAvatarCollisions"; + + /// + /// Stat name for the number of prim collisions with another entity. + /// + public const string ODEPrimCollisionsStatName = "ODEPrimCollisions"; + + /// /// Used to hold tick numbers for stat collection purposes. /// private int m_nativeCollisionTickRecorder; @@ -158,6 +168,12 @@ namespace OpenSim.Region.Physics.OdePlugin private bool m_inCollisionTiming; /// + /// A temporary holder for the number of avatar collisions in a frame, so we can work out how many object + /// collisions occured using the _perloopcontact if stats collection is enabled. + /// + private int m_tempAvatarCollisionsThisFrame; + + /// /// Used in calculating physics frame time dilation /// private int tickCountFrameRun; @@ -473,7 +489,7 @@ namespace OpenSim.Region.Physics.OdePlugin // Initialize the mesh plugin public override void Initialise(IMesher meshmerizer, IConfigSource config) { - m_stats[ODENativeCollisionFrameMsStatName] = 0; + InitializeExtraStats(); mesher = meshmerizer; m_config = config; @@ -1455,7 +1471,7 @@ namespace OpenSim.Region.Physics.OdePlugin break; } } - //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); + //m_log.DebugFormat("[Collision]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); //m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z)); } } @@ -1693,8 +1709,11 @@ namespace OpenSim.Region.Physics.OdePlugin //} } -// if (framecount % 55 == 0) -// m_log.DebugFormat("Processed {0} collisions", _perloopContact.Count); + if (CollectStats) + { + m_tempAvatarCollisionsThisFrame = _perloopContact.Count; + m_stats[ODEAvatarCollisionsStatName] += m_tempAvatarCollisionsThisFrame; + } List removeprims = null; foreach (OdePrim chr in _activeprims) @@ -1728,6 +1747,9 @@ namespace OpenSim.Region.Physics.OdePlugin } } + if (CollectStats) + m_stats[ODEPrimCollisionsStatName] += _perloopContact.Count - m_tempAvatarCollisionsThisFrame; + if (removeprims != null) { foreach (OdePrim chr in removeprims) @@ -4063,10 +4085,17 @@ namespace OpenSim.Region.Physics.OdePlugin { returnStats = new Dictionary(m_stats); - m_stats[ODENativeCollisionFrameMsStatName] = 0; + InitializeExtraStats(); } return returnStats; } + + private void InitializeExtraStats() + { + m_stats[ODENativeCollisionFrameMsStatName] = 0; + m_stats[ODEAvatarCollisionsStatName] = 0; + m_stats[ODEPrimCollisionsStatName] = 0; + } } } \ No newline at end of file -- cgit v1.1 From 8301f7b17f8e524d2412f927530da95f711bd6ac Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 00:57:55 +0100 Subject: minor: comment out currently unused OdeScene.sCollisionData --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 864cdc2..ace0ba5 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -55,15 +55,15 @@ namespace OpenSim.Region.Physics.OdePlugin End = 2 } - public struct sCollisionData - { - public uint ColliderLocalId; - public uint CollidedWithLocalId; - public int NumberOfCollisions; - public int CollisionType; - public int StatusIndicator; - public int lastframe; - } +// public struct sCollisionData +// { +// public uint ColliderLocalId; +// public uint CollidedWithLocalId; +// public int NumberOfCollisions; +// public int CollisionType; +// public int StatusIndicator; +// public int lastframe; +// } [Flags] public enum CollisionCategories : int -- cgit v1.1 From e1f8d2adb0dc1dffad8caf47611217b1f7f14f47 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 01:12:30 +0100 Subject: Stop adding an unnecessary duplicate _perloopcontact if the avatar is standing on a prim. This has already been added earlier on in the method. --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index ace0ba5..55c7e5a 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -1229,14 +1229,12 @@ namespace OpenSim.Region.Physics.OdePlugin { _perloopContact.Add(curContact); - // If we're colliding against terrain if (name1 == "Terrain" || name2 == "Terrain") { - // If we're moving if ((p2.PhysicsActorType == (int) ActorTypes.Agent) && (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) { - // Use the movement terrain contact + // Avatar is moving on terrain, use the movement terrain contact AvatarMovementTerrainContact.geom = curContact; if (m_global_contactcount < maxContactsbeforedeath) @@ -1249,7 +1247,7 @@ namespace OpenSim.Region.Physics.OdePlugin { if (p2.PhysicsActorType == (int)ActorTypes.Agent) { - // Use the non moving terrain contact + // Avatar is standing on terrain, use the non moving terrain contact TerrainContact.geom = curContact; if (m_global_contactcount < maxContactsbeforedeath) @@ -1344,13 +1342,11 @@ namespace OpenSim.Region.Physics.OdePlugin } else { - // we're colliding with prim or avatar - // check if we're moving if ((p2.PhysicsActorType == (int)ActorTypes.Agent)) { if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) { - // Use the Movement prim contact + // Avatar is moving on a prim, use the Movement prim contact AvatarMovementprimContact.geom = curContact; if (m_global_contactcount < maxContactsbeforedeath) @@ -1361,9 +1357,8 @@ namespace OpenSim.Region.Physics.OdePlugin } else { - // Use the non movement contact + // Avatar is standing still on a prim, use the non movement contact contact.geom = curContact; - _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { -- cgit v1.1 From c33c8db8256225b5ec09c0767c8b65341964d678 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 01:15:27 +0100 Subject: Rename new collision stats to 'contacts' - there are/can be multiple contacts per collision and this is what is actually being measured. --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 55c7e5a..32dac22 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -150,12 +150,12 @@ namespace OpenSim.Region.Physics.OdePlugin /// /// Stat name for the number of avatar collisions with another entity. /// - public const string ODEAvatarCollisionsStatName = "ODEAvatarCollisions"; + public const string ODEAvatarContactsStatsName = "ODEAvatarContacts"; /// /// Stat name for the number of prim collisions with another entity. /// - public const string ODEPrimCollisionsStatName = "ODEPrimCollisions"; + public const string ODEPrimContactsStatName = "ODEPrimContacts"; /// /// Used to hold tick numbers for stat collection purposes. @@ -1707,7 +1707,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (CollectStats) { m_tempAvatarCollisionsThisFrame = _perloopContact.Count; - m_stats[ODEAvatarCollisionsStatName] += m_tempAvatarCollisionsThisFrame; + m_stats[ODEAvatarContactsStatsName] += m_tempAvatarCollisionsThisFrame; } List removeprims = null; @@ -1743,7 +1743,7 @@ namespace OpenSim.Region.Physics.OdePlugin } if (CollectStats) - m_stats[ODEPrimCollisionsStatName] += _perloopContact.Count - m_tempAvatarCollisionsThisFrame; + m_stats[ODEPrimContactsStatName] += _perloopContact.Count - m_tempAvatarCollisionsThisFrame; if (removeprims != null) { @@ -4089,8 +4089,8 @@ namespace OpenSim.Region.Physics.OdePlugin private void InitializeExtraStats() { m_stats[ODENativeCollisionFrameMsStatName] = 0; - m_stats[ODEAvatarCollisionsStatName] = 0; - m_stats[ODEPrimCollisionsStatName] = 0; + m_stats[ODEAvatarContactsStatsName] = 0; + m_stats[ODEPrimContactsStatName] = 0; } } } \ No newline at end of file -- cgit v1.1 From 8333b928fa3353304358ed55293b52478a39ab6e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 01:27:19 +0100 Subject: Break down native ODE collision frame time stat into native space collision and geom collision stats --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 32dac22..d4c0b85 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -148,6 +148,16 @@ namespace OpenSim.Region.Physics.OdePlugin public const string ODENativeCollisionFrameMsStatName = "ODENativeCollisionFrameMS"; /// + /// Stat name for recording the number of milliseconds that ODE spends in native space collision code. + /// + public const string ODENativeSpaceCollisionFrameMsStatName = "ODENativeSpaceCollisionFrameMS"; + + /// + /// Stat name for recording the number of milliseconds that ODE spends in native geom collision code. + /// + public const string ODENativeGeomCollisionFrameMsStatName = "ODENativeGeomCollisionFrameMS"; + + /// /// Stat name for the number of avatar collisions with another entity. /// public const string ODEAvatarContactsStatsName = "ODEAvatarContacts"; @@ -843,7 +853,7 @@ namespace OpenSim.Region.Physics.OdePlugin // We do this outside the lock so that any waiting threads aren't held up, though the effect is probably // negligable if (CollectStats) - m_stats[ODENativeCollisionFrameMsStatName] + m_stats[ODENativeGeomCollisionFrameMsStatName] += Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder); return count; @@ -867,7 +877,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (CollectStats && m_inCollisionTiming) { - m_stats[ODENativeCollisionFrameMsStatName] + m_stats[ODENativeSpaceCollisionFrameMsStatName] += Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder); m_inCollisionTiming = false; } @@ -883,7 +893,7 @@ namespace OpenSim.Region.Physics.OdePlugin { if (CollectStats && m_inCollisionTiming) { - m_stats[ODENativeCollisionFrameMsStatName] + m_stats[ODENativeSpaceCollisionFrameMsStatName] += Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder); m_inCollisionTiming = false; } @@ -4079,6 +4089,10 @@ namespace OpenSim.Region.Physics.OdePlugin lock (OdeLock) { returnStats = new Dictionary(m_stats); + + returnStats[ODENativeCollisionFrameMsStatName] + = returnStats[ODENativeSpaceCollisionFrameMsStatName] + + returnStats[ODENativeGeomCollisionFrameMsStatName]; InitializeExtraStats(); } @@ -4088,7 +4102,11 @@ namespace OpenSim.Region.Physics.OdePlugin private void InitializeExtraStats() { - m_stats[ODENativeCollisionFrameMsStatName] = 0; + // No need to zero since this is calculated by addition + // m_stats[ODENativeCollisionFrameMsStatName] = 0; + + m_stats[ODENativeSpaceCollisionFrameMsStatName] = 0; + m_stats[ODENativeGeomCollisionFrameMsStatName] = 0; m_stats[ODEAvatarContactsStatsName] = 0; m_stats[ODEPrimContactsStatName] = 0; } -- cgit v1.1 From f2c8c7a7b8cd6a3d3cbbaafa2ba266658b7d0998 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 01:37:19 +0100 Subject: Add total ODE frame time optional stat, as a sanity check on the main scene physics stat --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index d4c0b85..ab03696 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -143,6 +143,14 @@ namespace OpenSim.Region.Physics.OdePlugin private Dictionary m_stats = new Dictionary(); /// + /// Stat name for the total time spent in ODE frame processing. + /// + /// + /// A sanity check for the main scene loop physics time. + /// + public const string ODETotalFrameMsStatName = "ODETotalFrameMS"; + + /// /// Stat name for recording the number of milliseconds that ODE spends in native collision code. /// public const string ODENativeCollisionFrameMsStatName = "ODENativeCollisionFrameMS"; @@ -170,7 +178,7 @@ namespace OpenSim.Region.Physics.OdePlugin /// /// Used to hold tick numbers for stat collection purposes. /// - private int m_nativeCollisionTickRecorder; + private int m_nativeCollisionStartTick; /// /// A messy way to tell if we need to avoid adding a collision time because this was already done in the callback. @@ -845,7 +853,7 @@ namespace OpenSim.Region.Physics.OdePlugin { // We do this inside the lock so that we don't count any delay in acquiring it if (CollectStats) - m_nativeCollisionTickRecorder = Util.EnvironmentTickCount(); + m_nativeCollisionStartTick = Util.EnvironmentTickCount(); count = d.Collide(geom1, geom2, maxContacts, contactsArray, contactGeomSize); } @@ -854,7 +862,7 @@ namespace OpenSim.Region.Physics.OdePlugin // negligable if (CollectStats) m_stats[ODENativeGeomCollisionFrameMsStatName] - += Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder); + += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick); return count; } @@ -870,7 +878,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (CollectStats) { m_inCollisionTiming = true; - m_nativeCollisionTickRecorder = Util.EnvironmentTickCount(); + m_nativeCollisionStartTick = Util.EnvironmentTickCount(); } d.SpaceCollide2(space1, space2, data, nearCallback); @@ -878,7 +886,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (CollectStats && m_inCollisionTiming) { m_stats[ODENativeSpaceCollisionFrameMsStatName] - += Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder); + += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick); m_inCollisionTiming = false; } } @@ -894,7 +902,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (CollectStats && m_inCollisionTiming) { m_stats[ODENativeSpaceCollisionFrameMsStatName] - += Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder); + += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick); m_inCollisionTiming = false; } @@ -2822,6 +2830,8 @@ namespace OpenSim.Region.Physics.OdePlugin /// The number of frames simulated over that period. public override float Simulate(float timeStep) { + int startFrameTick = Util.EnvironmentTickCount(); + if (framecount >= int.MaxValue) framecount = 0; @@ -3087,6 +3097,9 @@ namespace OpenSim.Region.Physics.OdePlugin tickCountFrameRun = Util.EnvironmentTickCount(); } + if (CollectStats) + m_stats[ODETotalFrameMsStatName] += Util.EnvironmentTickCount() - startFrameTick; + return fps; } @@ -4089,7 +4102,7 @@ namespace OpenSim.Region.Physics.OdePlugin lock (OdeLock) { returnStats = new Dictionary(m_stats); - + returnStats[ODENativeCollisionFrameMsStatName] = returnStats[ODENativeSpaceCollisionFrameMsStatName] + returnStats[ODENativeGeomCollisionFrameMsStatName]; @@ -4105,6 +4118,7 @@ namespace OpenSim.Region.Physics.OdePlugin // No need to zero since this is calculated by addition // m_stats[ODENativeCollisionFrameMsStatName] = 0; + m_stats[ODETotalFrameMsStatName] = 0; m_stats[ODENativeSpaceCollisionFrameMsStatName] = 0; m_stats[ODENativeGeomCollisionFrameMsStatName] = 0; m_stats[ODEAvatarContactsStatsName] = 0; -- cgit v1.1 From 5cc9b820e5b0a9490e6499ee5151c5e698c3e110 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 01:58:28 +0100 Subject: Add option native step frame ms stat --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 30 +++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index ab03696..04c4722 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -151,6 +151,11 @@ namespace OpenSim.Region.Physics.OdePlugin public const string ODETotalFrameMsStatName = "ODETotalFrameMS"; /// + /// The amount of time spent in native code that actually steps through the simulation. + /// + public const string ODENativeStepFrameMsStatName = "ODENativeStepFrameMS"; + + /// /// Stat name for recording the number of milliseconds that ODE spends in native collision code. /// public const string ODENativeCollisionFrameMsStatName = "ODENativeCollisionFrameMS"; @@ -2821,23 +2826,23 @@ namespace OpenSim.Region.Physics.OdePlugin /// /// This is our main simulate loop + /// + /// /// It's thread locked by a Mutex in the scene. /// It holds Collisions, it instructs ODE to step through the physical reactions /// It moves the objects around in memory /// It calls the methods that report back to the object owners.. (scenepresence, SceneObjectGroup) - /// + /// /// /// The number of frames simulated over that period. public override float Simulate(float timeStep) { - int startFrameTick = Util.EnvironmentTickCount(); + int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0; + int quickStepTick = 0; if (framecount >= int.MaxValue) framecount = 0; - //if (m_worldOffset != Vector3.Zero) - // return 0; - framecount++; float fps = 0; @@ -2845,7 +2850,7 @@ namespace OpenSim.Region.Physics.OdePlugin float timeLeft = timeStep; //m_log.Info(timeStep.ToString()); -// step_time += timeStep; +// step_time += timeSte // // // If We're loaded down by something else, // // or debugging with the Visual Studio project on pause @@ -3007,9 +3012,15 @@ namespace OpenSim.Region.Physics.OdePlugin // "[PHYSICS]: Collision contacts to process this frame = {0}", m_global_contactcount); m_global_contactcount = 0; - + + if (CollectStats) + quickStepTick = Util.EnvironmentTickCount(); + d.WorldQuickStep(world, ODE_STEPSIZE); + if (CollectStats) + m_stats[ODENativeStepFrameMsStatName] += Util.EnvironmentTickCountSubtract(quickStepTick); + d.JointGroupEmpty(contactgroup); } catch (Exception e) @@ -3077,7 +3088,7 @@ namespace OpenSim.Region.Physics.OdePlugin d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); } - latertickcount = Util.EnvironmentTickCount() - tickCountFrameRun; + latertickcount = Util.EnvironmentTickCountSubtract(tickCountFrameRun); // OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics // has a max of 100 ms to run theoretically. @@ -3098,7 +3109,7 @@ namespace OpenSim.Region.Physics.OdePlugin } if (CollectStats) - m_stats[ODETotalFrameMsStatName] += Util.EnvironmentTickCount() - startFrameTick; + m_stats[ODETotalFrameMsStatName] += Util.EnvironmentTickCountSubtract(startFrameTick); return fps; } @@ -4119,6 +4130,7 @@ namespace OpenSim.Region.Physics.OdePlugin // m_stats[ODENativeCollisionFrameMsStatName] = 0; m_stats[ODETotalFrameMsStatName] = 0; + m_stats[ODENativeStepFrameMsStatName] = 0; m_stats[ODENativeSpaceCollisionFrameMsStatName] = 0; m_stats[ODENativeGeomCollisionFrameMsStatName] = 0; m_stats[ODEAvatarContactsStatsName] = 0; -- cgit v1.1 From 5f44be99ef63f2f5ef7bcf73f61c29318d657e59 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 02:25:42 +0100 Subject: Add avatar and prim update milliseconds per frame optional stats --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 38 +++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 04c4722..f1fa38e 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -151,26 +151,36 @@ namespace OpenSim.Region.Physics.OdePlugin public const string ODETotalFrameMsStatName = "ODETotalFrameMS"; /// - /// The amount of time spent in native code that actually steps through the simulation. + /// Stat name for the amount of time spent in native code that actually steps through the simulation. /// public const string ODENativeStepFrameMsStatName = "ODENativeStepFrameMS"; /// - /// Stat name for recording the number of milliseconds that ODE spends in native collision code. + /// Stat name for the number of milliseconds that ODE spends in native collision code. /// public const string ODENativeCollisionFrameMsStatName = "ODENativeCollisionFrameMS"; /// - /// Stat name for recording the number of milliseconds that ODE spends in native space collision code. + /// Stat name for the number of milliseconds that ODE spends in native space collision code. /// public const string ODENativeSpaceCollisionFrameMsStatName = "ODENativeSpaceCollisionFrameMS"; /// - /// Stat name for recording the number of milliseconds that ODE spends in native geom collision code. + /// Stat name for the number of milliseconds that ODE spends in native geom collision code. /// public const string ODENativeGeomCollisionFrameMsStatName = "ODENativeGeomCollisionFrameMS"; /// + /// Stat name for the milliseconds spent updating avatar position and velocity + /// + public const string ODEAvatarUpdateFrameMsStatName = "ODEAvatarUpdateFrameMS"; + + /// + /// Stat name for the milliseconds spent updating prim position and velocity + /// + public const string ODEPrimUpdateFrameMsStatName = "ODEPrimUpdateFrameMS"; + + /// /// Stat name for the number of avatar collisions with another entity. /// public const string ODEAvatarContactsStatsName = "ODEAvatarContacts"; @@ -2838,7 +2848,7 @@ namespace OpenSim.Region.Physics.OdePlugin public override float Simulate(float timeStep) { int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0; - int quickStepTick = 0; + int tempTick = 0;; if (framecount >= int.MaxValue) framecount = 0; @@ -3014,12 +3024,12 @@ namespace OpenSim.Region.Physics.OdePlugin m_global_contactcount = 0; if (CollectStats) - quickStepTick = Util.EnvironmentTickCount(); + tempTick = Util.EnvironmentTickCount(); d.WorldQuickStep(world, ODE_STEPSIZE); if (CollectStats) - m_stats[ODENativeStepFrameMsStatName] += Util.EnvironmentTickCountSubtract(quickStepTick); + m_stats[ODENativeStepFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick); d.JointGroupEmpty(contactgroup); } @@ -3031,6 +3041,9 @@ namespace OpenSim.Region.Physics.OdePlugin timeLeft -= ODE_STEPSIZE; } + if (CollectStats) + tempTick = Util.EnvironmentTickCount(); + foreach (OdeCharacter actor in _characters) { if (actor.bad) @@ -3054,6 +3067,12 @@ namespace OpenSim.Region.Physics.OdePlugin defects.Clear(); } + if (CollectStats) + { + m_stats[ODEAvatarUpdateFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick); + tempTick = Util.EnvironmentTickCount(); + } + //if (timeStep < 0.2f) foreach (OdePrim prim in _activeprims) @@ -3067,6 +3086,9 @@ namespace OpenSim.Region.Physics.OdePlugin } } + if (CollectStats) + m_stats[ODEPrimUpdateFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick); + //DumpJointInfo(); // Finished with all sim stepping. If requested, dump world state to file for debugging. @@ -4135,6 +4157,8 @@ namespace OpenSim.Region.Physics.OdePlugin m_stats[ODENativeGeomCollisionFrameMsStatName] = 0; m_stats[ODEAvatarContactsStatsName] = 0; m_stats[ODEPrimContactsStatName] = 0; + m_stats[ODEAvatarUpdateFrameMsStatName] = 0; + m_stats[ODEPrimUpdateFrameMsStatName] = 0; } } } \ No newline at end of file -- cgit v1.1 From 31343aa7c3182f4b7e05d7dc01c4c43bd2d43596 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 02:33:44 +0100 Subject: Add optional stat that records milliseconds spent notifying collision listeners in physics frames --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index f1fa38e..0b9ad61 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -171,6 +171,11 @@ namespace OpenSim.Region.Physics.OdePlugin public const string ODENativeGeomCollisionFrameMsStatName = "ODENativeGeomCollisionFrameMS"; /// + /// Stat name for time spent notifying listeners of collisions + /// + public const string ODECollisionNotificationFrameMsStatName = "ODECollisionNotificationFrameMS"; + + /// /// Stat name for the milliseconds spent updating avatar position and velocity /// public const string ODEAvatarUpdateFrameMsStatName = "ODEAvatarUpdateFrameMS"; @@ -2998,6 +3003,9 @@ namespace OpenSim.Region.Physics.OdePlugin collision_optimized(); + if (CollectStats) + tempTick = Util.EnvironmentTickCount(); + foreach (PhysicsActor obj in _collisionEventPrim.Values) { // m_log.DebugFormat("[PHYSICS]: Assessing {0} {1} for collision events", obj.SOPName, obj.LocalID); @@ -3024,7 +3032,12 @@ namespace OpenSim.Region.Physics.OdePlugin m_global_contactcount = 0; if (CollectStats) + { + m_stats[ODECollisionNotificationFrameMsStatName] + += Util.EnvironmentTickCountSubtract(tempTick); + tempTick = Util.EnvironmentTickCount(); + } d.WorldQuickStep(world, ODE_STEPSIZE); @@ -4155,6 +4168,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_stats[ODENativeStepFrameMsStatName] = 0; m_stats[ODENativeSpaceCollisionFrameMsStatName] = 0; m_stats[ODENativeGeomCollisionFrameMsStatName] = 0; + m_stats[ODECollisionNotificationFrameMsStatName] = 0; m_stats[ODEAvatarContactsStatsName] = 0; m_stats[ODEPrimContactsStatName] = 0; m_stats[ODEAvatarUpdateFrameMsStatName] = 0; -- cgit v1.1 From d1b5f8d9d76e3c7c4c23f485dd070e3775e8e85f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 02:35:11 +0100 Subject: Remove recent optional native collision frame milliseconds stat Unnecessary since this has now been broken down into space collisions and geom collisions --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 0b9ad61..948930b 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -156,11 +156,6 @@ namespace OpenSim.Region.Physics.OdePlugin public const string ODENativeStepFrameMsStatName = "ODENativeStepFrameMS"; /// - /// Stat name for the number of milliseconds that ODE spends in native collision code. - /// - public const string ODENativeCollisionFrameMsStatName = "ODENativeCollisionFrameMS"; - - /// /// Stat name for the number of milliseconds that ODE spends in native space collision code. /// public const string ODENativeSpaceCollisionFrameMsStatName = "ODENativeSpaceCollisionFrameMS"; @@ -3035,7 +3030,7 @@ namespace OpenSim.Region.Physics.OdePlugin { m_stats[ODECollisionNotificationFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick); - + tempTick = Util.EnvironmentTickCount(); } @@ -4149,10 +4144,6 @@ namespace OpenSim.Region.Physics.OdePlugin { returnStats = new Dictionary(m_stats); - returnStats[ODENativeCollisionFrameMsStatName] - = returnStats[ODENativeSpaceCollisionFrameMsStatName] - + returnStats[ODENativeGeomCollisionFrameMsStatName]; - InitializeExtraStats(); } @@ -4161,9 +4152,6 @@ namespace OpenSim.Region.Physics.OdePlugin private void InitializeExtraStats() { - // No need to zero since this is calculated by addition - // m_stats[ODENativeCollisionFrameMsStatName] = 0; - m_stats[ODETotalFrameMsStatName] = 0; m_stats[ODENativeStepFrameMsStatName] = 0; m_stats[ODENativeSpaceCollisionFrameMsStatName] = 0; -- cgit v1.1 From 9ff8efc72014d8d5e971c3ceb7ec83bf9c19d69f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 03:03:48 +0100 Subject: Collection optional avatar and prim taint frame millisecond times --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 43 +++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 948930b..63b999e 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -151,6 +151,16 @@ namespace OpenSim.Region.Physics.OdePlugin public const string ODETotalFrameMsStatName = "ODETotalFrameMS"; /// + /// Stat name for amount of time spent processing avatar taints per frame + /// + public const string ODEAvatarTaintMsStatName = "ODEAvatarTaintFrameMS"; + + /// + /// Stat name for amount of time spent processing prim taints per frame + /// + public const string ODEPrimTaintMsStatName = "ODEPrimTaintFrameMS"; + + /// /// Stat name for the amount of time spent in native code that actually steps through the simulation. /// public const string ODENativeStepFrameMsStatName = "ODENativeStepFrameMS"; @@ -2848,7 +2858,7 @@ namespace OpenSim.Region.Physics.OdePlugin public override float Simulate(float timeStep) { int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0; - int tempTick = 0;; + int tempTick = 0, tempTick2 = 0; if (framecount >= int.MaxValue) framecount = 0; @@ -2926,6 +2936,9 @@ namespace OpenSim.Region.Physics.OdePlugin { try { + if (CollectStats) + tempTick = Util.EnvironmentTickCount(); + lock (_taintedActors) { foreach (OdeCharacter character in _taintedActors) @@ -2934,6 +2947,13 @@ namespace OpenSim.Region.Physics.OdePlugin _taintedActors.Clear(); } + if (CollectStats) + { + tempTick2 = Util.EnvironmentTickCount(); + m_stats[ODEAvatarTaintMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); + tempTick = tempTick2; + } + lock (_taintedPrims) { foreach (OdePrim prim in _taintedPrims) @@ -2964,6 +2984,13 @@ namespace OpenSim.Region.Physics.OdePlugin _taintedPrims.Clear(); } + if (CollectStats) + { + tempTick2 = Util.EnvironmentTickCount(); + m_stats[ODEPrimTaintMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); + tempTick = tempTick2; + } + // Move characters foreach (OdeCharacter actor in _characters) actor.Move(defects); @@ -3028,10 +3055,9 @@ namespace OpenSim.Region.Physics.OdePlugin if (CollectStats) { - m_stats[ODECollisionNotificationFrameMsStatName] - += Util.EnvironmentTickCountSubtract(tempTick); - - tempTick = Util.EnvironmentTickCount(); + tempTick2 = Util.EnvironmentTickCount(); + m_stats[ODECollisionNotificationFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); + tempTick = tempTick2; } d.WorldQuickStep(world, ODE_STEPSIZE); @@ -3077,8 +3103,9 @@ namespace OpenSim.Region.Physics.OdePlugin if (CollectStats) { - m_stats[ODEAvatarUpdateFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick); - tempTick = Util.EnvironmentTickCount(); + tempTick2 = Util.EnvironmentTickCount(); + m_stats[ODEAvatarUpdateFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); + tempTick = tempTick2; } //if (timeStep < 0.2f) @@ -4153,6 +4180,8 @@ namespace OpenSim.Region.Physics.OdePlugin private void InitializeExtraStats() { m_stats[ODETotalFrameMsStatName] = 0; + m_stats[ODEAvatarTaintMsStatName] = 0; + m_stats[ODEPrimTaintMsStatName] = 0; m_stats[ODENativeStepFrameMsStatName] = 0; m_stats[ODENativeSpaceCollisionFrameMsStatName] = 0; m_stats[ODENativeGeomCollisionFrameMsStatName] = 0; -- cgit v1.1 From d34b84b53137f5516f790563588676ac5fbf0e49 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 03:23:19 +0100 Subject: Add avatar forces calculation, prim force and raycasting per frame millisecond optional stats --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 53 ++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 63b999e..e44375b 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -151,17 +151,32 @@ namespace OpenSim.Region.Physics.OdePlugin public const string ODETotalFrameMsStatName = "ODETotalFrameMS"; /// - /// Stat name for amount of time spent processing avatar taints per frame + /// Stat name for time spent processing avatar taints per frame /// public const string ODEAvatarTaintMsStatName = "ODEAvatarTaintFrameMS"; /// - /// Stat name for amount of time spent processing prim taints per frame + /// Stat name for time spent processing prim taints per frame /// public const string ODEPrimTaintMsStatName = "ODEPrimTaintFrameMS"; /// - /// Stat name for the amount of time spent in native code that actually steps through the simulation. + /// Stat name for time spent calculating avatar forces per frame. + /// + public const string ODEAvatarForcesFrameMsStatName = "ODEAvatarForcesFrameMS"; + + /// + /// Stat name for time spent calculating prim forces per frame + /// + public const string ODEPrimForcesFrameMsStatName = "ODEPrimForcesFrameMS"; + + /// + /// Stat name for time spent fulfilling raycasting requests per frame + /// + public const string ODERaycastingFrameMsStatName = "ODERaycastingFrameMS"; + + /// + /// Stat name for time spent in native code that actually steps through the simulation. /// public const string ODENativeStepFrameMsStatName = "ODENativeStepFrameMS"; @@ -171,7 +186,7 @@ namespace OpenSim.Region.Physics.OdePlugin public const string ODENativeSpaceCollisionFrameMsStatName = "ODENativeSpaceCollisionFrameMS"; /// - /// Stat name for the number of milliseconds that ODE spends in native geom collision code. + /// Stat name for milliseconds that ODE spends in native geom collision code. /// public const string ODENativeGeomCollisionFrameMsStatName = "ODENativeGeomCollisionFrameMS"; @@ -181,7 +196,7 @@ namespace OpenSim.Region.Physics.OdePlugin public const string ODECollisionNotificationFrameMsStatName = "ODECollisionNotificationFrameMS"; /// - /// Stat name for the milliseconds spent updating avatar position and velocity + /// Stat name for milliseconds spent updating avatar position and velocity /// public const string ODEAvatarUpdateFrameMsStatName = "ODEAvatarUpdateFrameMS"; @@ -191,12 +206,12 @@ namespace OpenSim.Region.Physics.OdePlugin public const string ODEPrimUpdateFrameMsStatName = "ODEPrimUpdateFrameMS"; /// - /// Stat name for the number of avatar collisions with another entity. + /// Stat name for avatar collisions with another entity. /// public const string ODEAvatarContactsStatsName = "ODEAvatarContacts"; /// - /// Stat name for the number of prim collisions with another entity. + /// Stat name for prim collisions with another entity. /// public const string ODEPrimContactsStatName = "ODEPrimContacts"; @@ -3010,6 +3025,13 @@ namespace OpenSim.Region.Physics.OdePlugin defects.Clear(); } + if (CollectStats) + { + tempTick2 = Util.EnvironmentTickCount(); + m_stats[ODEAvatarForcesFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); + tempTick = tempTick2; + } + // Move other active objects foreach (OdePrim prim in _activeprims) { @@ -3017,12 +3039,26 @@ namespace OpenSim.Region.Physics.OdePlugin prim.Move(timeStep); } + if (CollectStats) + { + tempTick2 = Util.EnvironmentTickCount(); + m_stats[ODEPrimForcesFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); + tempTick = tempTick2; + } + //if ((framecount % m_randomizeWater) == 0) // randomizeWater(waterlevel); //int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests(); m_rayCastManager.ProcessQueuedRequests(); + if (CollectStats) + { + tempTick2 = Util.EnvironmentTickCount(); + m_stats[ODERaycastingFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); + tempTick = tempTick2; + } + collision_optimized(); if (CollectStats) @@ -4182,6 +4218,9 @@ namespace OpenSim.Region.Physics.OdePlugin m_stats[ODETotalFrameMsStatName] = 0; m_stats[ODEAvatarTaintMsStatName] = 0; m_stats[ODEPrimTaintMsStatName] = 0; + m_stats[ODEAvatarForcesFrameMsStatName] = 0; + m_stats[ODEPrimForcesFrameMsStatName] = 0; + m_stats[ODERaycastingFrameMsStatName] = 0; m_stats[ODENativeStepFrameMsStatName] = 0; m_stats[ODENativeSpaceCollisionFrameMsStatName] = 0; m_stats[ODENativeGeomCollisionFrameMsStatName] = 0; -- cgit v1.1 From 200376b3c4717e9ae00b67ef5f2a57383952f2d5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 03:49:42 +0100 Subject: Add optional stat for the other collision time per frame not spent in ODE native spaces or geom collision code --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index e44375b..8590453 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -191,6 +191,11 @@ namespace OpenSim.Region.Physics.OdePlugin public const string ODENativeGeomCollisionFrameMsStatName = "ODENativeGeomCollisionFrameMS"; /// + /// Time spent in collision processing that is not spent in native space or geom collision code. + /// + public const string ODEOtherCollisionFrameMsStatName = "ODEOtherCollisionFrameMS"; + + /// /// Stat name for time spent notifying listeners of collisions /// public const string ODECollisionNotificationFrameMsStatName = "ODECollisionNotificationFrameMS"; @@ -3062,7 +3067,11 @@ namespace OpenSim.Region.Physics.OdePlugin collision_optimized(); if (CollectStats) - tempTick = Util.EnvironmentTickCount(); + { + tempTick2 = Util.EnvironmentTickCount(); + m_stats[ODEOtherCollisionFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); + tempTick = tempTick2; + } foreach (PhysicsActor obj in _collisionEventPrim.Values) { @@ -4210,6 +4219,11 @@ namespace OpenSim.Region.Physics.OdePlugin InitializeExtraStats(); } + returnStats[ODEOtherCollisionFrameMsStatName] + = returnStats[ODEOtherCollisionFrameMsStatName] + - returnStats[ODENativeSpaceCollisionFrameMsStatName] + - returnStats[ODENativeGeomCollisionFrameMsStatName]; + return returnStats; } @@ -4224,6 +4238,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_stats[ODENativeStepFrameMsStatName] = 0; m_stats[ODENativeSpaceCollisionFrameMsStatName] = 0; m_stats[ODENativeGeomCollisionFrameMsStatName] = 0; + m_stats[ODEOtherCollisionFrameMsStatName] = 0; m_stats[ODECollisionNotificationFrameMsStatName] = 0; m_stats[ODEAvatarContactsStatsName] = 0; m_stats[ODEPrimContactsStatName] = 0; -- cgit v1.1 From 4e06a46dc5e6d0fb6a894932e706e4a01351ec64 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 04:07:39 +0100 Subject: If OdeScene.Near() returns no collision contacts, then exit as early as possible. All subsequent code is only relevant if there are contacts. --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 8590453..c26c9c5 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -1025,6 +1025,10 @@ namespace OpenSim.Region.Physics.OdePlugin count = CollideGeoms(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf); + // All code after this is only relevant if we have any collisions + if (count <= 0) + return; + if (count > contacts.Length) m_log.Error("[ODE SCENE]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length); } -- cgit v1.1 From 6375db1533e6c625d7b6394542f74141092ff780 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 04:23:36 +0100 Subject: Add optional total avatars, total prims and active prims stats to ODE plugin. These will act as a sanity check with the main scene stats, to show that physics scene entities are being managed properly. Total prims will not match scene total prims since physics total does not include phantom prims --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index c26c9c5..c6ecc68 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -143,6 +143,21 @@ namespace OpenSim.Region.Physics.OdePlugin private Dictionary m_stats = new Dictionary(); /// + /// Stat name for total number of avatars in this ODE scene. + /// + public const string ODETotalAvatarsStatName = "ODETotalAvatars"; + + /// + /// Stat name for total number of prims in this ODE scene. + /// + public const string ODETotalPrimsStatName = "ODETotalPrims"; + + /// + /// Stat name for total number of prims with active physics in this ODE scene. + /// + public const string ODEActivePrimsStatName = "ODEActivePrims"; + + /// /// Stat name for the total time spent in ODE frame processing. /// /// @@ -4220,6 +4235,12 @@ namespace OpenSim.Region.Physics.OdePlugin { returnStats = new Dictionary(m_stats); + // FIXME: This is a SUPER DUMB HACK until we can establish stats that aren't subject to a division by + // 3 from the SimStatsReporter. + returnStats[ODETotalAvatarsStatName] = _characters.Count * 3; + returnStats[ODETotalPrimsStatName] = _prims.Count * 3; + returnStats[ODEActivePrimsStatName] = _activeprims.Count * 3; + InitializeExtraStats(); } -- cgit v1.1 From 72219eae7d3dac01e73ab5fdf84f05f8d0fa00cf Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Jun 2012 04:45:42 +0100 Subject: Instead of updating sim stats root agent, child, objects and scripts accounts every single scene frame, update in the once every 3 seconds SimStatsReporter run --- OpenSim/Region/Framework/Scenes/Scene.cs | 5 --- .../Region/Framework/Scenes/SimStatsReporter.cs | 42 ++++++++-------------- 2 files changed, 14 insertions(+), 33 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index ce386be..702e322 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1462,10 +1462,6 @@ namespace OpenSim.Region.Framework.Scenes StatsReporter.AddPhysicsFPS(physicsFPS); StatsReporter.AddTimeDilation(TimeDilation); StatsReporter.AddFPS(1); - StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount()); - StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount()); - StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount()); - StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount()); // frameMS currently records work frame times, not total frame times (work + any required sleep to // reach min frame time. @@ -1474,7 +1470,6 @@ namespace OpenSim.Region.Framework.Scenes StatsReporter.addAgentMS(agentMS); StatsReporter.addPhysicsMS(physicsMS + physicsMS2); StatsReporter.addOtherMS(otherMS); - StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount()); StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); if (LoginsDisabled && Frame == 20) diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs index 08d8d7c..87af311 100644 --- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs +++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs @@ -207,6 +207,10 @@ namespace OpenSim.Region.Framework.Scenes m_report.Close(); } + /// + /// Sets the number of milliseconds between stat updates. + /// + /// public void SetUpdateMS(int ms) { statsUpdatesEveryMS = ms; @@ -254,6 +258,16 @@ namespace OpenSim.Region.Framework.Scenes physfps = 0; #endregion + + m_rootAgents = m_scene.SceneGraph.GetRootAgentCount(); + m_childAgents = m_scene.SceneGraph.GetChildAgentCount(); + m_numPrim = m_scene.SceneGraph.GetTotalObjectsCount(); + m_activePrim = m_scene.SceneGraph.GetActiveObjectsCount(); + m_activeScripts = m_scene.SceneGraph.GetActiveScriptsCount(); + + // FIXME: Checking for stat sanity is a complex approach. What we really need to do is fix the code + // so that stat numbers are always consistent. + CheckStatSanity(); //Our time dilation is 0.91 when we're running a full speed, // therefore to make sure we get an appropriate range, @@ -408,13 +422,6 @@ namespace OpenSim.Region.Framework.Scenes m_timeDilation = td; } - public void SetRootAgents(int rootAgents) - { - m_rootAgents = rootAgents; - CheckStatSanity(); - - } - internal void CheckStatSanity() { if (m_rootAgents < 0 || m_childAgents < 0) @@ -431,22 +438,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public void SetChildAgents(int childAgents) - { - m_childAgents = childAgents; - CheckStatSanity(); - } - - public void SetObjects(int objects) - { - m_numPrim = objects; - } - - public void SetActiveObjects(int objects) - { - m_activePrim = objects; - } - public void AddFPS(int frames) { m_fps += frames; @@ -528,11 +519,6 @@ namespace OpenSim.Region.Framework.Scenes m_scriptLinesPerSecond += count; } - public void SetActiveScripts(int count) - { - m_activeScripts = count; - } - public void AddPacketsStats(int inPackets, int outPackets, int unAckedBytes) { AddInPackets(inPackets); -- cgit v1.1 From 01a2b0b289933febc95523de02275c9bd573b10e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 2 Jun 2012 04:57:10 +0100 Subject: Fix various issues with http inventory 1) The return messages were being wrongly populated with the names of asset, inventory and sale types when their corresponding integers should have been used instead. 2) Folders with links were including the linked items in the descendents figure, when only the links should be included. 3) Links and linked items in link folders were not being included in the return data, and not in the correct order. Now that these issues have been addressed, outfits and attachments appear to work consistently when HTTP inventory is enabled (as is now the default). --- .../FetchInventory2/FetchInventory2Handler.cs | 30 +---- .../WebFetchInvDescHandler.cs | 125 +++++++++++++-------- OpenSim/Capabilities/LLSDInventoryItem.cs | 6 +- .../Services/InventoryService/XInventoryService.cs | 2 +- 4 files changed, 85 insertions(+), 78 deletions(-) diff --git a/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2Handler.cs b/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2Handler.cs index 717a097..c0ca1e1 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2Handler.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2Handler.cs @@ -101,18 +101,8 @@ namespace OpenSim.Capabilities.Handlers llsdItem.item_id = invItem.ID; llsdItem.name = invItem.Name; llsdItem.parent_id = invItem.Folder; - - try - { - llsdItem.type = Utils.AssetTypeToString((AssetType)invItem.AssetType); - llsdItem.inv_type = Utils.InventoryTypeToString((InventoryType)invItem.InvType); - } - catch (Exception e) - { - m_log.ErrorFormat( - "[WEB FETCH INV DESC HANDLER]: Problem setting asset {0} inventory {1} types while converting inventory item {2}: {3}", - invItem.AssetType, invItem.InvType, invItem.Name, e.Message); - } + llsdItem.type = invItem.AssetType; + llsdItem.inv_type = invItem.InvType; llsdItem.permissions = new LLSDPermissions(); llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; @@ -126,21 +116,7 @@ namespace OpenSim.Capabilities.Handlers llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; llsdItem.sale_info = new LLSDSaleInfo(); llsdItem.sale_info.sale_price = invItem.SalePrice; - switch (invItem.SaleType) - { - default: - llsdItem.sale_info.sale_type = "not"; - break; - case 1: - llsdItem.sale_info.sale_type = "original"; - break; - case 2: - llsdItem.sale_info.sale_type = "copy"; - break; - case 3: - llsdItem.sale_info.sale_type = "contents"; - break; - } + llsdItem.sale_info.sale_type = invItem.SaleType; return llsdItem; } diff --git a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs index d5c062b..b3196d9 100644 --- a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs +++ b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs @@ -156,11 +156,12 @@ namespace OpenSim.Capabilities.Handlers inv.Folders = new List(); inv.Items = new List(); int version = 0; + int descendents = 0; inv = Fetch( invFetch.owner_id, invFetch.folder_id, invFetch.owner_id, - invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version); + invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version, out descendents); if (inv != null && inv.Folders != null) { @@ -168,6 +169,8 @@ namespace OpenSim.Capabilities.Handlers { contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); } + + descendents += inv.Folders; } if (inv != null && inv.Items != null) @@ -178,7 +181,7 @@ namespace OpenSim.Capabilities.Handlers } } - contents.descendents = contents.items.Array.Count + contents.categories.Array.Count; + contents.descendents = descendents; contents.version = version; // m_log.DebugFormat( @@ -206,7 +209,7 @@ namespace OpenSim.Capabilities.Handlers /// An empty InventoryCollection if the inventory look up failed private InventoryCollection Fetch( UUID agentID, UUID folderID, UUID ownerID, - bool fetchFolders, bool fetchItems, int sortOrder, out int version) + bool fetchFolders, bool fetchItems, int sortOrder, out int version, out int descendents) { // m_log.DebugFormat( // "[WEB FETCH INV DESC HANDLER]: Fetching folders ({0}), items ({1}) from {2} for agent {3}", @@ -215,6 +218,8 @@ namespace OpenSim.Capabilities.Handlers // FIXME MAYBE: We're not handling sortOrder! version = 0; + descendents = 0; + InventoryFolderImpl fold; if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner) { @@ -223,6 +228,7 @@ namespace OpenSim.Capabilities.Handlers InventoryCollection ret = new InventoryCollection(); ret.Folders = new List(); ret.Items = fold.RequestListOfItems(); + descendents = ret.Folders.Count + ret.Items.Count; return ret; } @@ -246,24 +252,73 @@ namespace OpenSim.Capabilities.Handlers version = containingFolder.Version; -// if (fetchItems) + if (fetchItems) + { + List itemsToReturn = contents.Items; + List originalItems = new List(itemsToReturn); + + // descendents must only include the links, not the linked items we add + descendents = originalItems.Count; + + // Second, add target items for links in this folder + foreach (InventoryItemBase item in originalItems) + { + if (item.AssetType == (int)AssetType.Link) + { + InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID)); + + // Take care of genuinely broken links where the target doesn't exist + // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, + // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles + // rather than having to keep track of every folder requested in the recursion. + if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link) + itemsToReturn.Insert(0, linkedItem); + } + } + + // First, scan for folder links and add target items in those folders. + foreach (InventoryItemBase item in originalItems) + { + if (item.AssetType == (int)AssetType.LinkFolder) + { + InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(ownerID, item.AssetID); + List links = linkedFolderContents.Items; + + // Second, insert the links contained in this linked folder. + itemsToReturn.InsertRange(0, links); + + // Third, insert the real items linked by the links in this linked folder. + foreach (InventoryItemBase link in linkedFolderContents.Items) + { + // Take care of genuinely broken links where the target doesn't exist + // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, + // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles + // rather than having to keep track of every folder requested in the recursion. + if (link != null) + { +// m_log.DebugFormat( +// "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3}", +// link.Name, (AssetType)link.AssetType, item.AssetID, containingFolder.Name); + + InventoryItemBase linkedItem + = m_InventoryService.GetItem(new InventoryItemBase(link.AssetID)); + + itemsToReturn.Insert(0, linkedItem); + } + } + } + } + } + +// foreach (InventoryItemBase item in contents.Items) // { -// List linkedItemsToAdd = new List(); -// -// foreach (InventoryItemBase item in contents.Items) -// { -// if (item.AssetType == (int)AssetType.Link) -// { -// InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID)); -// -// // Take care of genuinely broken links where the target doesn't exist -// // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, -// // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles -// // rather than having to keep track of every folder requested in the recursion. -// if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link) -// linkedItemsToAdd.Insert(0, linkedItem); -// } -// } +// m_log.DebugFormat( +// "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}", +// item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID); +// } + + // ===== + // // foreach (InventoryItemBase linkedItem in linkedItemsToAdd) // { @@ -365,18 +420,8 @@ namespace OpenSim.Capabilities.Handlers llsdItem.item_id = invItem.ID; llsdItem.name = invItem.Name; llsdItem.parent_id = invItem.Folder; - - try - { - llsdItem.type = Utils.AssetTypeToString((AssetType)invItem.AssetType); - llsdItem.inv_type = Utils.InventoryTypeToString((InventoryType)invItem.InvType); - } - catch (Exception e) - { - m_log.ErrorFormat( - "[WEB FETCH INV DESC HANDLER]: Problem setting asset {0} inventory {1} types while converting inventory item {2}: {3}", - invItem.AssetType, invItem.InvType, invItem.Name, e.Message); - } + llsdItem.type = invItem.AssetType; + llsdItem.inv_type = invItem.InvType; llsdItem.permissions = new LLSDPermissions(); llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; @@ -390,21 +435,7 @@ namespace OpenSim.Capabilities.Handlers llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; llsdItem.sale_info = new LLSDSaleInfo(); llsdItem.sale_info.sale_price = invItem.SalePrice; - switch (invItem.SaleType) - { - default: - llsdItem.sale_info.sale_type = "not"; - break; - case 1: - llsdItem.sale_info.sale_type = "original"; - break; - case 2: - llsdItem.sale_info.sale_type = "copy"; - break; - case 3: - llsdItem.sale_info.sale_type = "contents"; - break; - } + llsdItem.sale_info.sale_type = invItem.SaleType; return llsdItem; } diff --git a/OpenSim/Capabilities/LLSDInventoryItem.cs b/OpenSim/Capabilities/LLSDInventoryItem.cs index 426a6cb..958e807 100644 --- a/OpenSim/Capabilities/LLSDInventoryItem.cs +++ b/OpenSim/Capabilities/LLSDInventoryItem.cs @@ -37,8 +37,8 @@ namespace OpenSim.Framework.Capabilities public UUID asset_id; public UUID item_id; public LLSDPermissions permissions; - public string type; - public string inv_type; + public int type; + public int inv_type; public int flags; public LLSDSaleInfo sale_info; @@ -65,7 +65,7 @@ namespace OpenSim.Framework.Capabilities public class LLSDSaleInfo { public int sale_price; - public string sale_type; + public int sale_type; } [OSDMap] diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 3355428..7518b86 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -436,7 +436,7 @@ namespace OpenSim.Services.InventoryService public virtual bool AddItem(InventoryItemBase item) { // m_log.DebugFormat( -// "[XINVENTORY SERVICE]: Adding item {0} to folder {1} for {2}", item.ID, item.Folder, item.Owner); +// "[XINVENTORY SERVICE]: Adding item {0} {1} to folder {2} for {3}", item.Name, item.ID, item.Folder, item.Owner); return m_Database.StoreItem(ConvertFromOpenSim(item)); } -- cgit v1.1 From 2de5479c3f0df84ab76365dc3a6eb618012c3153 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 2 Jun 2012 05:01:56 +0100 Subject: minor: tidy up some comments --- .../Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs index b3196d9..1594c55 100644 --- a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs +++ b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs @@ -260,7 +260,7 @@ namespace OpenSim.Capabilities.Handlers // descendents must only include the links, not the linked items we add descendents = originalItems.Count; - // Second, add target items for links in this folder + // Add target items for links in this folder before the links themselves. foreach (InventoryItemBase item in originalItems) { if (item.AssetType == (int)AssetType.Link) @@ -276,7 +276,7 @@ namespace OpenSim.Capabilities.Handlers } } - // First, scan for folder links and add target items in those folders. + // Now scan for folder links and insert the items they target and those links at the head of the return data foreach (InventoryItemBase item in originalItems) { if (item.AssetType == (int)AssetType.LinkFolder) @@ -284,10 +284,8 @@ namespace OpenSim.Capabilities.Handlers InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(ownerID, item.AssetID); List links = linkedFolderContents.Items; - // Second, insert the links contained in this linked folder. itemsToReturn.InsertRange(0, links); - // Third, insert the real items linked by the links in this linked folder. foreach (InventoryItemBase link in linkedFolderContents.Items) { // Take care of genuinely broken links where the target doesn't exist -- cgit v1.1 From 729d90173f82f5ac51b8b69ee8b3362599ffd2f1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 2 Jun 2012 05:03:56 +0100 Subject: Fix build break whree accidentally did inv.Folders rather than inv.Folders.Count in a minor change. --- .../Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs index 1594c55..849cad2 100644 --- a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs +++ b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs @@ -170,7 +170,7 @@ namespace OpenSim.Capabilities.Handlers contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); } - descendents += inv.Folders; + descendents += inv.Folders.Count; } if (inv != null && inv.Items != null) -- cgit v1.1 From 5c646e26031400961dcfe3d7c4bd84512a1bc7cb Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 4 Jun 2012 18:22:09 +0100 Subject: Remove the "Profile" config as it's covered by the replaceable interface --- OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs index 8101ca2..87ca327 100644 --- a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs @@ -57,14 +57,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile public void Initialise(IConfigSource config) { - // This can be reduced later as the loader will determine - // whether we are needed - if (config.Configs["Profile"] != null) - { - if (config.Configs["Profile"].GetString("Module", string.Empty) != "BasicProfileModule") - return; - } - m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled"); m_Enabled = true; } -- cgit v1.1 From f94ef37b46c680e3d74b21cdb2e2a89f482bcc62 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 4 Jun 2012 10:26:39 -0700 Subject: Correct the delegate specification in EventManager.TriggerTerrainTainted. Looks like the wrong one was cut and pasted. --- OpenSim/Region/Framework/Scenes/EventManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index f97b0a9..f92ed8e 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -923,7 +923,7 @@ namespace OpenSim.Region.Framework.Scenes OnTerrainTaintedDelegate handlerTerrainTainted = OnTerrainTainted; if (handlerTerrainTainted != null) { - foreach (OnTerrainTickDelegate d in handlerTerrainTainted.GetInvocationList()) + foreach (OnTerrainTaintedDelegate d in handlerTerrainTainted.GetInvocationList()) { try { -- cgit v1.1 From 9707a2d57c4a4a8e818e0e9b0ec57c5b7abcb70c Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 4 Jun 2012 18:24:02 +0100 Subject: Remove profile from basic configuration --- bin/config-include/Grid.ini | 3 --- bin/config-include/Standalone.ini | 3 --- 2 files changed, 6 deletions(-) diff --git a/bin/config-include/Grid.ini b/bin/config-include/Grid.ini index 95d6264..cb3a5c8 100644 --- a/bin/config-include/Grid.ini +++ b/bin/config-include/Grid.ini @@ -29,9 +29,6 @@ SimulationServiceInConnector = true LibraryModule = true -[Profile] - Module = "BasicProfileModule" - [SimulationDataStore] LocalServiceModule = "OpenSim.Services.Connectors.dll:SimulationDataService" diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini index 74d9d2e..ba72fe7 100644 --- a/bin/config-include/Standalone.ini +++ b/bin/config-include/Standalone.ini @@ -25,9 +25,6 @@ GridInfoServiceInConnector = true MapImageServiceInConnector = true -[Profile] - Module = "BasicProfileModule" - [SimulationDataStore] LocalServiceModule = "OpenSim.Services.Connectors.dll:SimulationDataService" -- cgit v1.1 From 3229e32b4e818c6a0897800d8770c95f90ee3a94 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Mon, 4 Jun 2012 17:22:46 -0400 Subject: Add replaceable region modules to the "show modules" command --- OpenSim/Region/Application/OpenSim.cs | 78 ++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index c0913c5..76ac827 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -971,8 +971,7 @@ namespace OpenSim if (showParams.Length > 1 && showParams[1] == "full") { agents = m_sceneManager.GetCurrentScenePresences(); - } - else + } else { agents = m_sceneManager.GetCurrentSceneAvatars(); } @@ -981,7 +980,8 @@ namespace OpenSim MainConsole.Instance.Output( String.Format("{0,-16} {1,-16} {2,-37} {3,-11} {4,-16} {5,-30}", "Firstname", "Lastname", - "Agent ID", "Root/Child", "Region", "Position")); + "Agent ID", "Root/Child", "Region", "Position") + ); foreach (ScenePresence presence in agents) { @@ -991,8 +991,7 @@ namespace OpenSim if (regionInfo == null) { regionName = "Unresolvable"; - } - else + } else { regionName = regionInfo.RegionName; } @@ -1005,7 +1004,8 @@ namespace OpenSim presence.UUID, presence.IsChildAgent ? "Child" : "Root", regionName, - presence.AbsolutePosition.ToString())); + presence.AbsolutePosition.ToString()) + ); } MainConsole.Instance.Output(String.Empty); @@ -1014,16 +1014,20 @@ namespace OpenSim case "connections": System.Text.StringBuilder connections = new System.Text.StringBuilder("Connections:\n"); m_sceneManager.ForEachScene( - delegate(Scene scene) - { - scene.ForEachClient( - delegate(IClientAPI client) - { - connections.AppendFormat("{0}: {1} ({2}) from {3} on circuit {4}\n", - scene.RegionInfo.RegionName, client.Name, client.AgentId, client.RemoteEndPoint, client.CircuitCode); - } + delegate(Scene scene) { + scene.ForEachClient( + delegate(IClientAPI client) { + connections.AppendFormat( + "{0}: {1} ({2}) from {3} on circuit {4}\n", + scene.RegionInfo.RegionName, + client.Name, + client.AgentId, + client.RemoteEndPoint, + client.CircuitCode ); } + ); + } ); MainConsole.Instance.Output(connections.ToString()); @@ -1032,13 +1036,17 @@ namespace OpenSim case "circuits": System.Text.StringBuilder acd = new System.Text.StringBuilder("Agent Circuits:\n"); m_sceneManager.ForEachScene( - delegate(Scene scene) - { - //this.HttpServer. - acd.AppendFormat("{0}:\n", scene.RegionInfo.RegionName); - foreach (AgentCircuitData aCircuit in scene.AuthenticateHandler.GetAgentCircuits().Values) - acd.AppendFormat("\t{0} {1} ({2})\n", aCircuit.firstname, aCircuit.lastname, (aCircuit.child ? "Child" : "Root")); - } + delegate(Scene scene) { + //this.HttpServer. + acd.AppendFormat("{0}:\n", scene.RegionInfo.RegionName); + foreach (AgentCircuitData aCircuit in scene.AuthenticateHandler.GetAgentCircuits().Values) + acd.AppendFormat( + "\t{0} {1} ({2})\n", + aCircuit.firstname, + aCircuit.lastname, + (aCircuit.child ? "Child" : "Root") + ); + } ); MainConsole.Instance.Output(acd.ToString()); @@ -1079,17 +1087,29 @@ namespace OpenSim } m_sceneManager.ForEachScene( - delegate(Scene scene) + delegate(Scene scene) { + m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:"); + foreach (IRegionModule module in scene.Modules.Values) { - m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:"); - foreach (IRegionModule module in scene.Modules.Values) + if (!module.IsSharedModule) { - if (!module.IsSharedModule) - { - m_log.Error("Region Module: " + module.Name); - } + m_log.Error("Region Module: " + module.Name); } - }); + } + } + ); + + m_sceneManager.ForEachScene( + delegate(Scene scene) { + MainConsole.Instance.Output("Loaded new region modules in" + scene.RegionInfo.RegionName + " are:"); + foreach (IRegionModuleBase module in scene.RegionModules.Values) + { + Type type = module.GetType().GetInterface("ISharedRegionModule"); + string module_type = type != null ? "Shared" : "Non-Shared"; + MainConsole.Instance.OutputFormat("New Region Module ({0}): {1}", module_type, module.Name); + } + } + ); MainConsole.Instance.Output(""); break; -- cgit v1.1 From a7f4804f53f391d5d67bf3484733ab5e41bc34be Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 4 Jun 2012 23:07:53 +0100 Subject: Properly show per frame millisecond statistics per frame, not as amount of time taken per second. This is to make these statistics actually match their names (and also be more accurate as number of frames can vary under heavy load) Currently using scene frames (11.23 every second) instead of physics frames (56.18 per second) --- .../Region/Framework/Scenes/SimStatsReporter.cs | 63 ++++++++++++++-------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs index 87af311..11c321b 100644 --- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs +++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs @@ -117,12 +117,17 @@ namespace OpenSim.Region.Framework.Scenes private Dictionary m_lastReportedExtraSimStats = new Dictionary(); // Sending a stats update every 3 seconds- - private int statsUpdatesEveryMS = 3000; - private float statsUpdateFactor = 0; + private int m_statsUpdatesEveryMS = 3000; + private float m_statsUpdateFactor = 0; private float m_timeDilation = 0; private int m_fps = 0; /// + /// Number of the last frame on which we processed a stats udpate. + /// + private uint m_lastUpdateFrame; + + /// /// Our nominal fps target, as expected in fps stats when a sim is running normally. /// private float m_nominalReportedFps = 55; @@ -188,12 +193,12 @@ namespace OpenSim.Region.Framework.Scenes { m_scene = scene; m_reportedFpsCorrectionFactor = scene.MinFrameTime * m_nominalReportedFps; - statsUpdateFactor = (float)(statsUpdatesEveryMS / 1000); + m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000); ReportingRegion = scene.RegionInfo; m_objectCapacity = scene.RegionInfo.ObjectCapacity; m_report.AutoReset = true; - m_report.Interval = statsUpdatesEveryMS; + m_report.Interval = m_statsUpdatesEveryMS; m_report.Elapsed += statsHeartBeat; m_report.Enabled = true; @@ -213,9 +218,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void SetUpdateMS(int ms) { - statsUpdatesEveryMS = ms; - statsUpdateFactor = (float)(statsUpdatesEveryMS / 1000); - m_report.Interval = statsUpdatesEveryMS; + m_statsUpdatesEveryMS = ms; + m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000); + m_report.Interval = m_statsUpdatesEveryMS; } private void statsHeartBeat(object sender, EventArgs e) @@ -247,7 +252,7 @@ namespace OpenSim.Region.Framework.Scenes int reportedFPS = (int)(m_fps * m_reportedFpsCorrectionFactor); // save the reported value so there is something available for llGetRegionFPS - lastReportedSimFPS = reportedFPS / statsUpdateFactor; + lastReportedSimFPS = reportedFPS / m_statsUpdateFactor; float physfps = ((m_pfps / 1000)); @@ -279,6 +284,14 @@ namespace OpenSim.Region.Framework.Scenes // 'statsUpdateFactor' is how often stats packets are sent in seconds. Used below to change // values to X-per-second values. + uint thisFrame = m_scene.Frame; + float framesUpdated = (float)(thisFrame - m_lastUpdateFrame); + m_lastUpdateFrame = thisFrame; + + // Avoid div-by-zero if somehow we've not updated any frames. + if (framesUpdated == 0) + framesUpdated = 1; + for (int i = 0; i < 21; i++) { sb[i] = new SimStatsPacket.StatBlock(); @@ -288,13 +301,13 @@ namespace OpenSim.Region.Framework.Scenes sb[0].StatValue = (Single.IsNaN(m_timeDilation)) ? 0.1f : m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor)); sb[1].StatID = (uint) Stats.SimFPS; - sb[1].StatValue = reportedFPS / statsUpdateFactor; + sb[1].StatValue = reportedFPS / m_statsUpdateFactor; sb[2].StatID = (uint) Stats.PhysicsFPS; - sb[2].StatValue = physfps / statsUpdateFactor; + sb[2].StatValue = physfps / m_statsUpdateFactor; sb[3].StatID = (uint) Stats.AgentUpdates; - sb[3].StatValue = (m_agentUpdates / statsUpdateFactor); + sb[3].StatValue = (m_agentUpdates / m_statsUpdateFactor); sb[4].StatID = (uint) Stats.Agents; sb[4].StatValue = m_rootAgents; @@ -309,31 +322,31 @@ namespace OpenSim.Region.Framework.Scenes sb[7].StatValue = m_activePrim; sb[8].StatID = (uint)Stats.FrameMS; - sb[8].StatValue = m_frameMS / statsUpdateFactor; + sb[8].StatValue = m_frameMS / framesUpdated; sb[9].StatID = (uint)Stats.NetMS; - sb[9].StatValue = m_netMS / statsUpdateFactor; + sb[9].StatValue = m_netMS / framesUpdated; sb[10].StatID = (uint)Stats.PhysicsMS; - sb[10].StatValue = m_physicsMS / statsUpdateFactor; + sb[10].StatValue = m_physicsMS / framesUpdated; sb[11].StatID = (uint)Stats.ImageMS ; - sb[11].StatValue = m_imageMS / statsUpdateFactor; + sb[11].StatValue = m_imageMS / framesUpdated; sb[12].StatID = (uint)Stats.OtherMS; - sb[12].StatValue = m_otherMS / statsUpdateFactor; + sb[12].StatValue = m_otherMS / framesUpdated; sb[13].StatID = (uint)Stats.InPacketsPerSecond; - sb[13].StatValue = (m_inPacketsPerSecond / statsUpdateFactor); + sb[13].StatValue = (m_inPacketsPerSecond / m_statsUpdateFactor); sb[14].StatID = (uint)Stats.OutPacketsPerSecond; - sb[14].StatValue = (m_outPacketsPerSecond / statsUpdateFactor); + sb[14].StatValue = (m_outPacketsPerSecond / m_statsUpdateFactor); sb[15].StatID = (uint)Stats.UnAckedBytes; sb[15].StatValue = m_unAckedBytes; sb[16].StatID = (uint)Stats.AgentMS; - sb[16].StatValue = m_agentMS / statsUpdateFactor; + sb[16].StatValue = m_agentMS / framesUpdated; sb[17].StatID = (uint)Stats.PendingDownloads; sb[17].StatValue = m_pendingDownloads; @@ -345,7 +358,7 @@ namespace OpenSim.Region.Framework.Scenes sb[19].StatValue = m_activeScripts; sb[20].StatID = (uint)Stats.ScriptLinesPerSecond; - sb[20].StatValue = m_scriptLinesPerSecond / statsUpdateFactor; + sb[20].StatValue = m_scriptLinesPerSecond / m_statsUpdateFactor; for (int i = 0; i < 21; i++) { @@ -366,7 +379,7 @@ namespace OpenSim.Region.Framework.Scenes // Extra statistics that aren't currently sent to clients lock (m_lastReportedExtraSimStats) { - m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / statsUpdateFactor; + m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / m_statsUpdateFactor; Dictionary physicsStats = m_scene.PhysicsScene.GetStats(); @@ -374,7 +387,13 @@ namespace OpenSim.Region.Framework.Scenes { foreach (KeyValuePair tuple in physicsStats) { - m_lastReportedExtraSimStats[tuple.Key] = tuple.Value / statsUpdateFactor; + // FIXME: An extremely dirty hack to divide MS stats per frame rather than per second + // Need to change things so that stats source can indicate whether they are per second or + // per frame. + if (tuple.Key.EndsWith("MS")) + m_lastReportedExtraSimStats[tuple.Key] = tuple.Value / framesUpdated; + else + m_lastReportedExtraSimStats[tuple.Key] = tuple.Value / m_statsUpdateFactor; } } } -- cgit v1.1 From 655625ab872659cd8aff1fe5b11dc568c91aee6d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 5 Jun 2012 00:17:55 +0100 Subject: Start sending spare frame time MS viewer stat. Make frame time correctly display total frame time, not just non-spare time. This makes it easier to see when components of frame time exceed normal permitted frame time. Currently reflect scene frame times. --- OpenSim/Region/Framework/Scenes/Scene.cs | 90 +++++++++-------- .../Region/Framework/Scenes/SimStatsReporter.cs | 112 ++++++++++++++------- 2 files changed, 124 insertions(+), 78 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 702e322..ae35cb9 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -219,6 +219,7 @@ namespace OpenSim.Region.Framework.Scenes private int backupMS; private int terrainMS; private int landMS; + private int spareMS; /// /// Tick at which the last frame was processed. @@ -1360,43 +1361,41 @@ namespace OpenSim.Region.Framework.Scenes endFrame = Frame + frames; float physicsFPS = 0f; - int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS; - int previousFrameTick; - int maintc; + int previousFrameTick, tmpMS; + int maintc = Util.EnvironmentTickCount(); while (!m_shuttingDown && (endFrame == null || Frame < endFrame)) { - maintc = Util.EnvironmentTickCount(); ++Frame; // m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName); - agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0; + agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = spareMS = 0; try { // Apply taints in terrain module to terrain in physics scene if (Frame % m_update_terrain == 0) { - terMS = Util.EnvironmentTickCount(); + tmpMS = Util.EnvironmentTickCount(); UpdateTerrain(); - terrainMS = Util.EnvironmentTickCountSubtract(terMS); + terrainMS = Util.EnvironmentTickCountSubtract(tmpMS); } - tmpPhysicsMS2 = Util.EnvironmentTickCount(); + tmpMS = Util.EnvironmentTickCount(); if ((Frame % m_update_physics == 0) && m_physics_enabled) m_sceneGraph.UpdatePreparePhysics(); - physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2); + physicsMS2 = Util.EnvironmentTickCountSubtract(tmpMS); // Apply any pending avatar force input to the avatar's velocity - tmpAgentMS = Util.EnvironmentTickCount(); + tmpMS = Util.EnvironmentTickCount(); if (Frame % m_update_entitymovement == 0) m_sceneGraph.UpdateScenePresenceMovement(); - agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS); + agentMS = Util.EnvironmentTickCountSubtract(tmpMS); // Perform the main physics update. This will do the actual work of moving objects and avatars according to their // velocity - tmpPhysicsMS = Util.EnvironmentTickCount(); + tmpMS = Util.EnvironmentTickCount(); if (Frame % m_update_physics == 0) { if (m_physics_enabled) @@ -1405,9 +1404,9 @@ namespace OpenSim.Region.Framework.Scenes if (SynchronizeScene != null) SynchronizeScene(this); } - physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS); + physicsMS = Util.EnvironmentTickCountSubtract(tmpMS); - tmpAgentMS = Util.EnvironmentTickCount(); + tmpMS = Util.EnvironmentTickCount(); // Check if any objects have reached their targets CheckAtTargets(); @@ -1422,29 +1421,29 @@ namespace OpenSim.Region.Framework.Scenes if (Frame % m_update_presences == 0) m_sceneGraph.UpdatePresences(); - agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS); + agentMS += Util.EnvironmentTickCountSubtract(tmpMS); // Delete temp-on-rez stuff if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps) { - tmpTempOnRezMS = Util.EnvironmentTickCount(); + tmpMS = Util.EnvironmentTickCount(); m_cleaningTemps = true; Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; }); - tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS); + tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpMS); } if (Frame % m_update_events == 0) { - evMS = Util.EnvironmentTickCount(); + tmpMS = Util.EnvironmentTickCount(); UpdateEvents(); - eventMS = Util.EnvironmentTickCountSubtract(evMS); + eventMS = Util.EnvironmentTickCountSubtract(tmpMS); } if (Frame % m_update_backup == 0) { - backMS = Util.EnvironmentTickCount(); + tmpMS = Util.EnvironmentTickCount(); UpdateStorageBackup(); - backupMS = Util.EnvironmentTickCountSubtract(backMS); + backupMS = Util.EnvironmentTickCountSubtract(tmpMS); } //if (Frame % m_update_land == 0) @@ -1453,24 +1452,6 @@ namespace OpenSim.Region.Framework.Scenes // UpdateLand(); // landMS = Util.EnvironmentTickCountSubtract(ldMS); //} - - frameMS = Util.EnvironmentTickCountSubtract(maintc); - otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS; - - // if (Frame%m_update_avatars == 0) - // UpdateInWorldTime(); - StatsReporter.AddPhysicsFPS(physicsFPS); - StatsReporter.AddTimeDilation(TimeDilation); - StatsReporter.AddFPS(1); - - // frameMS currently records work frame times, not total frame times (work + any required sleep to - // reach min frame time. - StatsReporter.addFrameMS(frameMS); - - StatsReporter.addAgentMS(agentMS); - StatsReporter.addPhysicsMS(physicsMS + physicsMS2); - StatsReporter.addOtherMS(otherMS); - StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); if (LoginsDisabled && Frame == 20) { @@ -1521,13 +1502,34 @@ namespace OpenSim.Region.Framework.Scenes previousFrameTick = m_lastFrameTick; m_lastFrameTick = Util.EnvironmentTickCount(); - maintc = Util.EnvironmentTickCountSubtract(m_lastFrameTick, maintc); - maintc = (int)(MinFrameTime * 1000) - maintc; + tmpMS = Util.EnvironmentTickCountSubtract(m_lastFrameTick, maintc); + tmpMS = (int)(MinFrameTime * 1000) - tmpMS; - if (maintc > 0) - Thread.Sleep(maintc); + if (tmpMS > 0) + { + Thread.Sleep(tmpMS); + spareMS += tmpMS; + } - // Optionally warn if a frame takes double the amount of time that it should. + frameMS = Util.EnvironmentTickCountSubtract(maintc); + maintc = Util.EnvironmentTickCount(); + + otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS; + + // if (Frame%m_update_avatars == 0) + // UpdateInWorldTime(); + StatsReporter.AddPhysicsFPS(physicsFPS); + StatsReporter.AddTimeDilation(TimeDilation); + StatsReporter.AddFPS(1); + + StatsReporter.addFrameMS(frameMS); + StatsReporter.addAgentMS(agentMS); + StatsReporter.addPhysicsMS(physicsMS + physicsMS2); + StatsReporter.addOtherMS(otherMS); + StatsReporter.AddSpareMS(spareMS); + StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); + + // Optionally warn if a frame takes double the amount of time that it should. if (DebugUpdates && Util.EnvironmentTickCountSubtract( m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2)) diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs index 11c321b..88e0b05 100644 --- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs +++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs @@ -56,10 +56,17 @@ namespace OpenSim.Region.Framework.Scenes public event YourStatsAreWrong OnStatsIncorrect; - private SendStatResult handlerSendStatResult = null; + private SendStatResult handlerSendStatResult; - private YourStatsAreWrong handlerStatsIncorrect = null; + private YourStatsAreWrong handlerStatsIncorrect; + /// + /// These are the IDs of stats sent in the StatsPacket to the viewer. + /// + /// + /// Some of these are not relevant to OpenSimulator since it is architected differently to other simulators + /// (e.g. script instructions aren't executed as part of the frame loop so 'script time' is tricky). + /// public enum Stats : uint { TimeDilation = 0, @@ -83,7 +90,20 @@ namespace OpenSim.Region.Framework.Scenes OutPacketsPerSecond = 18, PendingDownloads = 19, PendingUploads = 20, + VirtualSizeKb = 21, + ResidentSizeKb = 22, + PendingLocalUploads = 23, UnAckedBytes = 24, + PhysicsPinnedTasks = 25, + PhysicsLodTasks = 26, + SimPhysicsStepMs = 27, + SimPhysicsShapeMs = 28, + SimPhysicsOtherMs = 29, + SimPhysicsMemory = 30, + ScriptEps = 31, + SimSpareMs = 32, + SimSleepMs = 33, + SimIoPumpTime = 34 } /// @@ -118,9 +138,9 @@ namespace OpenSim.Region.Framework.Scenes // Sending a stats update every 3 seconds- private int m_statsUpdatesEveryMS = 3000; - private float m_statsUpdateFactor = 0; - private float m_timeDilation = 0; - private int m_fps = 0; + private float m_statsUpdateFactor; + private float m_timeDilation; + private int m_fps; /// /// Number of the last frame on which we processed a stats udpate. @@ -143,41 +163,42 @@ namespace OpenSim.Region.Framework.Scenes private float m_reportedFpsCorrectionFactor = 5; // saved last reported value so there is something available for llGetRegionFPS - private float lastReportedSimFPS = 0; - private float[] lastReportedSimStats = new float[21]; - private float m_pfps = 0; + private float lastReportedSimFPS; + private float[] lastReportedSimStats = new float[22]; + private float m_pfps; /// /// Number of agent updates requested in this stats cycle /// - private int m_agentUpdates = 0; + private int m_agentUpdates; /// /// Number of object updates requested in this stats cycle /// private int m_objectUpdates; - private int m_frameMS = 0; - private int m_netMS = 0; - private int m_agentMS = 0; - private int m_physicsMS = 0; - private int m_imageMS = 0; - private int m_otherMS = 0; + private int m_frameMS; + private int m_spareMS; + private int m_netMS; + private int m_agentMS; + private int m_physicsMS; + private int m_imageMS; + private int m_otherMS; //Ckrinke: (3-21-08) Comment out to remove a compiler warning. Bring back into play when needed. //Ckrinke private int m_scriptMS = 0; - private int m_rootAgents = 0; - private int m_childAgents = 0; - private int m_numPrim = 0; - private int m_inPacketsPerSecond = 0; - private int m_outPacketsPerSecond = 0; - private int m_activePrim = 0; - private int m_unAckedBytes = 0; - private int m_pendingDownloads = 0; - private int m_pendingUploads = 0; - private int m_activeScripts = 0; - private int m_scriptLinesPerSecond = 0; + private int m_rootAgents; + private int m_childAgents; + private int m_numPrim; + private int m_inPacketsPerSecond; + private int m_outPacketsPerSecond; + private int m_activePrim; + private int m_unAckedBytes; + private int m_pendingDownloads; + private int m_pendingUploads = 0; // FIXME: Not currently filled in + private int m_activeScripts; + private int m_scriptLinesPerSecond; private int m_objectCapacity = 45000; @@ -199,7 +220,7 @@ namespace OpenSim.Region.Framework.Scenes m_objectCapacity = scene.RegionInfo.ObjectCapacity; m_report.AutoReset = true; m_report.Interval = m_statsUpdatesEveryMS; - m_report.Elapsed += statsHeartBeat; + m_report.Elapsed += TriggerStatsHeartbeat; m_report.Enabled = true; if (StatsManager.SimExtraStats != null) @@ -208,7 +229,7 @@ namespace OpenSim.Region.Framework.Scenes public void Close() { - m_report.Elapsed -= statsHeartBeat; + m_report.Elapsed -= TriggerStatsHeartbeat; m_report.Close(); } @@ -223,9 +244,23 @@ namespace OpenSim.Region.Framework.Scenes m_report.Interval = m_statsUpdatesEveryMS; } + private void TriggerStatsHeartbeat(object sender, EventArgs args) + { + try + { + statsHeartBeat(sender, args); + } + catch (Exception e) + { + m_log.Warn(string.Format( + "[SIM STATS REPORTER] Update for {0} failed with exception ", + m_scene.RegionInfo.RegionName), e); + } + } + private void statsHeartBeat(object sender, EventArgs e) { - SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[21]; + SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[22]; SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock(); // Know what's not thread safe in Mono... modifying timers. @@ -292,7 +327,7 @@ namespace OpenSim.Region.Framework.Scenes if (framesUpdated == 0) framesUpdated = 1; - for (int i = 0; i < 21; i++) + for (int i = 0; i < 22; i++) { sb[i] = new SimStatsPacket.StatBlock(); } @@ -359,8 +394,11 @@ namespace OpenSim.Region.Framework.Scenes sb[20].StatID = (uint)Stats.ScriptLinesPerSecond; sb[20].StatValue = m_scriptLinesPerSecond / m_statsUpdateFactor; - - for (int i = 0; i < 21; i++) + + sb[21].StatID = (uint)Stats.SimSpareMs; + sb[21].StatValue = m_spareMS / framesUpdated; + + for (int i = 0; i < 22; i++) { lastReportedSimStats[i] = sb[i].StatValue; } @@ -398,11 +436,11 @@ namespace OpenSim.Region.Framework.Scenes } } - resetvalues(); + ResetValues(); } } - private void resetvalues() + private void ResetValues() { m_timeDilation = 0; m_fps = 0; @@ -420,6 +458,7 @@ namespace OpenSim.Region.Framework.Scenes m_physicsMS = 0; m_imageMS = 0; m_otherMS = 0; + m_spareMS = 0; //Ckrinke This variable is not used, so comment to remove compiler warning until it is used. //Ckrinke m_scriptMS = 0; @@ -498,6 +537,11 @@ namespace OpenSim.Region.Framework.Scenes m_frameMS += ms; } + public void AddSpareMS(int ms) + { + m_spareMS += ms; + } + public void addNetMS(int ms) { m_netMS += ms; -- cgit v1.1 From 96d1ba90d7f801c779924ea04656d0fb53ea9d32 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 5 Jun 2012 00:27:51 +0100 Subject: Scale down per frame MS stats to match scaled simulator FPS stat. This makes frame time stats properly tally with fps, which saves confusion and makes it easier to interpret numbers. In some ways this is not so artifical - physics FPS runs at the higher rate. --- OpenSim/Region/Framework/Scenes/SimStatsReporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs index 88e0b05..742d42a 100644 --- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs +++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs @@ -320,7 +320,7 @@ namespace OpenSim.Region.Framework.Scenes // values to X-per-second values. uint thisFrame = m_scene.Frame; - float framesUpdated = (float)(thisFrame - m_lastUpdateFrame); + float framesUpdated = (float)(thisFrame - m_lastUpdateFrame) * m_reportedFpsCorrectionFactor; m_lastUpdateFrame = thisFrame; // Avoid div-by-zero if somehow we've not updated any frames. -- cgit v1.1 From 01280e9b9447f41347f7e22302c9d94503398882 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 5 Jun 2012 00:34:18 +0100 Subject: Remove unused ScenePresence list structure in llGetAgentList() --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index deb68b8..fb0fdc9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5583,7 +5583,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } } - List presenceIds = new List(); World.ForEachRootScenePresence( delegate (ScenePresence ssp) -- cgit v1.1 From 008c6a4610fa7b710a9e2546cc09d9fee57e5795 Mon Sep 17 00:00:00 2001 From: Talun Date: Fri, 1 Jun 2012 00:39:26 +0100 Subject: Mantis 4597 AgentPaused packet is ignored. The packet was actually being handled but not acted on. This change extends the default timeout for paused clients to 5 minutes and makes both the paused and non-paused timeout periods configurable. --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 18 +++++++++++++++--- bin/OpenSimDefaults.ini | 13 +++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index edf91cb..32ba590 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -155,7 +155,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_defaultRTO = 0; private int m_maxRTO = 0; - + private int m_ackTimeout = 0; + private int m_pausedAckTimeout = 0; private bool m_disableFacelights = false; public Socket Server { get { return null; } } @@ -198,11 +199,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_defaultRTO = config.GetInt("DefaultRTO", 0); m_maxRTO = config.GetInt("MaxRTO", 0); m_disableFacelights = config.GetBoolean("DisableFacelights", false); + m_ackTimeout = 1000 * config.GetInt("AckTimeout", 60); + m_pausedAckTimeout = 1000 * config.GetInt("PausedAckTimeout", 300); } else { PrimUpdatesPerCallback = 100; TextureSendLimit = 20; + m_ackTimeout = 1000 * 60; // 1 minute + m_pausedAckTimeout = 1000 * 300; // 5 minutes } #region BinaryStats @@ -491,8 +496,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP return; // Disconnect an agent if no packets are received for some time - //FIXME: Make 60 an .ini setting - if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > 1000 * 60) + int timeoutTicks = m_ackTimeout; + + // Allow more slack if the client is "paused" eg file upload dialogue is open + // Some sort of limit is needed in case the client crashes, loses its network connection + // or some other disaster prevents it from sendung the AgentResume + if (udpClient.IsPaused) + timeoutTicks = m_pausedAckTimeout; + + if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) { m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 27d86e8..c67e45a 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -536,6 +536,19 @@ ; ;DisableFacelights = false + ; The time to wait before disconecting an unresponsive client. + ; The time is in seconds. The default is one minute + ; + ;AckTimeout = 60 + + ; The time to wait before disconecting an unresponsive paused client. + ; A client can be paused when the file selection dialog is open during file upload. + ; This gives extra time to find files via the dialog but will still disconnect if + ; the client crashes or loses its network connection + ; The time is in seconds. The default is five minutes. + ; + ;PausedAckTimeout = 300 + [ClientStack.LindenCaps] ;; Long list of capabilities taken from ;; http://wiki.secondlife.com/wiki/Current_Sim_Capabilities -- cgit v1.1 From 42179578fc5292d9bd12aeccc45948d908c42d1a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 5 Jun 2012 01:33:58 +0100 Subject: Allow fix-phantoms command to appear even if CombineContiguousRegions = false, since this allows one to go back from a megaregion to normal regions. Adapted from a patch by Garmin Kawaguichi in http://opensimulator.org/mantis/view.php?id=6027 Garmin says that fix-phantoms allows one to reset objects when going back from megaregion to normal regions as well as the othe rway around. Thanks! --- .../RegionCombinerModule/RegionCombinerModule.cs | 24 ++++++++++------------ 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 40daf13..3555028 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -61,7 +61,7 @@ namespace OpenSim.Region.RegionCombinerModule /// /// Is this module enabled? /// - private bool enabledYN = false; + private bool m_combineContiguousRegions = false; /// /// This holds the root regions for the megaregions. @@ -79,14 +79,12 @@ namespace OpenSim.Region.RegionCombinerModule public void Initialise(IConfigSource source) { IConfig myConfig = source.Configs["Startup"]; - enabledYN = myConfig.GetBoolean("CombineContiguousRegions", false); + m_combineContiguousRegions = myConfig.GetBoolean("CombineContiguousRegions", false); - if (enabledYN) - { - MainConsole.Instance.Commands.AddCommand( - "RegionCombinerModule", false, "fix-phantoms", "fix-phantoms", - "Fixes phantom objects after an import to megaregions", FixPhantoms); - } + MainConsole.Instance.Commands.AddCommand( + "RegionCombinerModule", false, "fix-phantoms", "fix-phantoms", + "Fixes phantom objects after an import to a megaregion or a change from a megaregion back to normal regions", + FixPhantoms); } public void Close() @@ -95,7 +93,7 @@ namespace OpenSim.Region.RegionCombinerModule public void AddRegion(Scene scene) { - if (enabledYN) + if (m_combineContiguousRegions) scene.RegisterModuleInterface(this); } @@ -105,7 +103,10 @@ namespace OpenSim.Region.RegionCombinerModule public void RegionLoaded(Scene scene) { - if (enabledYN) + lock (m_startingScenes) + m_startingScenes.Add(scene.RegionInfo.originRegionID, scene); + + if (m_combineContiguousRegions) { RegionLoadedDoWork(scene); @@ -208,7 +209,6 @@ namespace OpenSim.Region.RegionCombinerModule { return; } - } } @@ -220,8 +220,6 @@ namespace OpenSim.Region.RegionCombinerModule return; // */ - lock (m_startingScenes) - m_startingScenes.Add(scene.RegionInfo.originRegionID, scene); // Give each region a standard set of non-infinite borders Border northBorder = new Border(); -- cgit v1.1 From a5410c2c19bfef9242d9cfcfc1b4fea67f470fd5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 5 Jun 2012 01:37:40 +0100 Subject: minor: Add user feedback when executing fix-phantoms --- OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 3555028..204c4ff 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -1066,6 +1066,8 @@ namespace OpenSim.Region.RegionCombinerModule foreach (Scene s in scenes) { + MainConsole.Instance.OutputFormat("Fixing phantoms for {0}", s.RegionInfo.RegionName); + s.ForEachSOG(so => so.AbsolutePosition = so.AbsolutePosition); } } -- cgit v1.1 From 6adc810eaaf067e25ac88b023a20543577a2d5fd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 5 Jun 2012 19:40:16 +0100 Subject: Stop accidentally reading 4 Int16s instead of 2 in SIZE section of Terragen file when loaded from a stream. Fixes a bug introduced 2 weeks ago in 67ebe80 Thanks to Plugh for pointing this out. --- OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs index 71c71e6..7a0db26 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs @@ -180,8 +180,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders // fileHeight = sztmp; bs.ReadInt16(); bs.ReadInt16(); - bs.ReadInt16(); - bs.ReadInt16(); break; case "XPTS": // fileWidth = bs.ReadInt16(); -- cgit v1.1 From abf94627f6752c81eec6ebe0412bdcb725a66037 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 6 Jun 2012 02:45:36 +0100 Subject: Ensure closure of bitmap and memory stream with using() statements in WorldViewModule. If this has any effect then it will only be to the map images returned via requests to the /worldview simulator HTTP path (not enabled by default) --- .../OptionalModules/World/WorldView/WorldViewModule.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/OptionalModules/World/WorldView/WorldViewModule.cs b/OpenSim/Region/OptionalModules/World/WorldView/WorldViewModule.cs index 48c242d..1aee39a 100644 --- a/OpenSim/Region/OptionalModules/World/WorldView/WorldViewModule.cs +++ b/OpenSim/Region/OptionalModules/World/WorldView/WorldViewModule.cs @@ -113,14 +113,15 @@ namespace OpenSim.Region.OptionalModules.World.WorldView if (!m_Enabled) return new Byte[0]; - Bitmap bmp = m_Generator.CreateViewImage(pos, rot, fov, width, - height, usetex); - - MemoryStream str = new MemoryStream(); - - bmp.Save(str, ImageFormat.Jpeg); + using (Bitmap bmp = m_Generator.CreateViewImage(pos, rot, fov, width, height, usetex)) + { + using (MemoryStream str = new MemoryStream()) + { + bmp.Save(str, ImageFormat.Jpeg); - return str.ToArray(); + return str.ToArray(); + } + } } } } -- cgit v1.1 From 3b250211803ee5a39888c6c5bd05b60d253a22b6 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Tue, 5 Jun 2012 15:11:45 +0100 Subject: enabling all corners of a sim to be set in one call --- .../CoreModules/World/Estate/EstateManagementCommands.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs index d2bbea3..3b84d57 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs @@ -73,7 +73,7 @@ namespace OpenSim.Region.CoreModules.World.Estate "set terrain heights [] []", "Sets the terrain texture heights on corner # to /, if or are specified, it will only " + "set it on regions with a matching coordinate. Specify -1 in or to wildcard" + - " that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3.", + " that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3, all corners = -1.", consoleSetTerrainHeights); m_module.Scene.AddCommand( @@ -143,6 +143,16 @@ namespace OpenSim.Region.CoreModules.World.Estate switch (corner) { + case -1: + m_module.Scene.RegionInfo.RegionSettings.Elevation1SW = lowValue; + m_module.Scene.RegionInfo.RegionSettings.Elevation2SW = highValue; + m_module.Scene.RegionInfo.RegionSettings.Elevation1NW = lowValue; + m_module.Scene.RegionInfo.RegionSettings.Elevation2NW = highValue; + m_module.Scene.RegionInfo.RegionSettings.Elevation1SE = lowValue; + m_module.Scene.RegionInfo.RegionSettings.Elevation2SE = highValue; + m_module.Scene.RegionInfo.RegionSettings.Elevation1NE = lowValue; + m_module.Scene.RegionInfo.RegionSettings.Elevation2NE = highValue; + break; case 0: m_module.Scene.RegionInfo.RegionSettings.Elevation1SW = lowValue; m_module.Scene.RegionInfo.RegionSettings.Elevation2SW = highValue; -- cgit v1.1 From 2b0de66216ca57cf2eac52e777bb362023f8f30a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 6 Jun 2012 04:11:16 +0100 Subject: Actively dispose of Bitmaps in Warp3D image module and world map module once we've finished with them. This might help with memory leakage issues though I suspect it won't. --- .../CoreModules/World/Warp3DMap/MapImageModule.cs | 76 +++-- .../CoreModules/World/Warp3DMap/TerrainSplat.cs | 380 +++++++++++---------- .../CoreModules/World/WorldMap/WorldMapModule.cs | 7 +- 3 files changed, 248 insertions(+), 215 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs index 4f4e296..3538b46 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs @@ -204,7 +204,10 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap Bitmap bitmap = renderer.Scene.getImage(); if (m_useAntiAliasing) - bitmap = ImageUtils.ResizeImage(bitmap, viewport.Width, viewport.Height); + { + using (Bitmap origBitmap = bitmap) + bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height); + } return bitmap; } @@ -318,8 +321,17 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap uint globalX, globalY; Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out globalX, out globalY); - Bitmap image = TerrainSplat.Splat(heightmap, textureIDs, startHeights, heightRanges, new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain); - warp_Texture texture = new warp_Texture(image); + warp_Texture texture; + + using ( + Bitmap image + = TerrainSplat.Splat( + heightmap, textureIDs, startHeights, heightRanges, + new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain)) + { + texture = new warp_Texture(image); + } + warp_Material material = new warp_Material(texture); material.setReflectivity(50); renderer.Scene.addMaterial("TerrainColor", material); @@ -546,42 +558,46 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap { try { - Bitmap bitmap = (Bitmap)J2kImage.FromStream(stream); - width = bitmap.Width; - height = bitmap.Height; + int pixelBytes; - BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat); - int pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; - - // Sum up the individual channels - unsafe + using (Bitmap bitmap = (Bitmap)J2kImage.FromStream(stream)) { - if (pixelBytes == 4) + width = bitmap.Width; + height = bitmap.Height; + + BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat); + pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; + + // Sum up the individual channels + unsafe { - for (int y = 0; y < height; y++) + if (pixelBytes == 4) { - byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); - - for (int x = 0; x < width; x++) + for (int y = 0; y < height; y++) { - b += row[x * pixelBytes + 0]; - g += row[x * pixelBytes + 1]; - r += row[x * pixelBytes + 2]; - a += row[x * pixelBytes + 3]; + byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); + + for (int x = 0; x < width; x++) + { + b += row[x * pixelBytes + 0]; + g += row[x * pixelBytes + 1]; + r += row[x * pixelBytes + 2]; + a += row[x * pixelBytes + 3]; + } } } - } - else - { - for (int y = 0; y < height; y++) + else { - byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); - - for (int x = 0; x < width; x++) + for (int y = 0; y < height; y++) { - b += row[x * pixelBytes + 0]; - g += row[x * pixelBytes + 1]; - r += row[x * pixelBytes + 2]; + byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); + + for (int x = 0; x < width; x++) + { + b += row[x * pixelBytes + 0]; + g += row[x * pixelBytes + 1]; + r += row[x * pixelBytes + 2]; + } } } } diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs index 7bf675d..91252f7 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs @@ -84,218 +84,234 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap Debug.Assert(heightRanges.Length == 4); Bitmap[] detailTexture = new Bitmap[4]; + Bitmap output = null; + BitmapData outputData = null; - if (textureTerrain) + try { - // Swap empty terrain textureIDs with default IDs - for (int i = 0; i < textureIDs.Length; i++) + if (textureTerrain) { - if (textureIDs[i] == UUID.Zero) - textureIDs[i] = DEFAULT_TERRAIN_DETAIL[i]; - } - - #region Texture Fetching - - if (assetService != null) - { - for (int i = 0; i < 4; i++) + // Swap empty terrain textureIDs with default IDs + for (int i = 0; i < textureIDs.Length; i++) { - AssetBase asset; - UUID cacheID = UUID.Combine(TERRAIN_CACHE_MAGIC, textureIDs[i]); - - // Try to fetch a cached copy of the decoded/resized version of this texture - asset = assetService.GetCached(cacheID.ToString()); - if (asset != null) - { - try - { - using (System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data)) - detailTexture[i] = (Bitmap)Image.FromStream(stream); - } - catch (Exception ex) - { - m_log.Warn("Failed to decode cached terrain texture " + cacheID + - " (textureID: " + textureIDs[i] + "): " + ex.Message); - } - } - - if (detailTexture[i] == null) + if (textureIDs[i] == UUID.Zero) + textureIDs[i] = DEFAULT_TERRAIN_DETAIL[i]; + } + + #region Texture Fetching + + if (assetService != null) + { + for (int i = 0; i < 4; i++) { - // Try to fetch the original JPEG2000 texture, resize if needed, and cache as PNG - asset = assetService.Get(textureIDs[i].ToString()); + AssetBase asset; + UUID cacheID = UUID.Combine(TERRAIN_CACHE_MAGIC, textureIDs[i]); + + // Try to fetch a cached copy of the decoded/resized version of this texture + asset = assetService.GetCached(cacheID.ToString()); if (asset != null) { - try { detailTexture[i] = (Bitmap)CSJ2K.J2kImage.FromBytes(asset.Data); } + try + { + using (System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data)) + detailTexture[i] = (Bitmap)Image.FromStream(stream); + } catch (Exception ex) { - m_log.Warn("Failed to decode terrain texture " + asset.ID + ": " + ex.Message); + m_log.Warn("Failed to decode cached terrain texture " + cacheID + + " (textureID: " + textureIDs[i] + "): " + ex.Message); } } - - if (detailTexture[i] != null) + + if (detailTexture[i] == null) { - Bitmap bitmap = detailTexture[i]; - - // Make sure this texture is the correct size, otherwise resize - if (bitmap.Width != 256 || bitmap.Height != 256) - bitmap = ImageUtils.ResizeImage(bitmap, 256, 256); - - // Save the decoded and resized texture to the cache - byte[] data; - using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) + // Try to fetch the original JPEG2000 texture, resize if needed, and cache as PNG + asset = assetService.Get(textureIDs[i].ToString()); + if (asset != null) { - bitmap.Save(stream, ImageFormat.Png); - data = stream.ToArray(); + try { detailTexture[i] = (Bitmap)CSJ2K.J2kImage.FromBytes(asset.Data); } + catch (Exception ex) + { + m_log.Warn("Failed to decode terrain texture " + asset.ID + ": " + ex.Message); + } } - - // Cache a PNG copy of this terrain texture - AssetBase newAsset = new AssetBase + + if (detailTexture[i] != null) { - Data = data, - Description = "PNG", - Flags = AssetFlags.Collectable, - FullID = cacheID, - ID = cacheID.ToString(), - Local = true, - Name = String.Empty, - Temporary = true, - Type = (sbyte)AssetType.Unknown - }; - newAsset.Metadata.ContentType = "image/png"; - assetService.Store(newAsset); + Bitmap bitmap = detailTexture[i]; + + // Make sure this texture is the correct size, otherwise resize + if (bitmap.Width != 256 || bitmap.Height != 256) + { + using (Bitmap origBitmap = bitmap) + { + bitmap = ImageUtils.ResizeImage(origBitmap, 256, 256); + } + } + + // Save the decoded and resized texture to the cache + byte[] data; + using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) + { + bitmap.Save(stream, ImageFormat.Png); + data = stream.ToArray(); + } + + // Cache a PNG copy of this terrain texture + AssetBase newAsset = new AssetBase + { + Data = data, + Description = "PNG", + Flags = AssetFlags.Collectable, + FullID = cacheID, + ID = cacheID.ToString(), + Local = true, + Name = String.Empty, + Temporary = true, + Type = (sbyte)AssetType.Unknown + }; + newAsset.Metadata.ContentType = "image/png"; + assetService.Store(newAsset); + } } } } + + #endregion Texture Fetching } - - #endregion Texture Fetching - } - - // Fill in any missing textures with a solid color - for (int i = 0; i < 4; i++) - { - if (detailTexture[i] == null) + + // Fill in any missing textures with a solid color + for (int i = 0; i < 4; i++) { - // Create a solid color texture for this layer - detailTexture[i] = new Bitmap(256, 256, PixelFormat.Format24bppRgb); - using (Graphics gfx = Graphics.FromImage(detailTexture[i])) + if (detailTexture[i] == null) { - using (SolidBrush brush = new SolidBrush(DEFAULT_TERRAIN_COLOR[i])) - gfx.FillRectangle(brush, 0, 0, 256, 256); + // Create a solid color texture for this layer + detailTexture[i] = new Bitmap(256, 256, PixelFormat.Format24bppRgb); + using (Graphics gfx = Graphics.FromImage(detailTexture[i])) + { + using (SolidBrush brush = new SolidBrush(DEFAULT_TERRAIN_COLOR[i])) + gfx.FillRectangle(brush, 0, 0, 256, 256); + } } } - } - - #region Layer Map - - float[] layermap = new float[256 * 256]; - - for (int y = 0; y < 256; y++) - { - for (int x = 0; x < 256; x++) - { - float height = heightmap[y * 256 + x]; - - float pctX = (float)x / 255f; - float pctY = (float)y / 255f; - - // Use bilinear interpolation between the four corners of start height and - // height range to select the current values at this position - float startHeight = ImageUtils.Bilinear( - startHeights[0], - startHeights[2], - startHeights[1], - startHeights[3], - pctX, pctY); - startHeight = Utils.Clamp(startHeight, 0f, 255f); - - float heightRange = ImageUtils.Bilinear( - heightRanges[0], - heightRanges[2], - heightRanges[1], - heightRanges[3], - pctX, pctY); - heightRange = Utils.Clamp(heightRange, 0f, 255f); - - // Generate two frequencies of perlin noise based on our global position - // The magic values were taken from http://opensimulator.org/wiki/Terrain_Splatting - Vector3 vec = new Vector3 - ( - ((float)regionPosition.X + x) * 0.20319f, - ((float)regionPosition.Y + y) * 0.20319f, - height * 0.25f - ); - - float lowFreq = Perlin.noise2(vec.X * 0.222222f, vec.Y * 0.222222f) * 6.5f; - float highFreq = Perlin.turbulence2(vec.X, vec.Y, 2f) * 2.25f; - float noise = (lowFreq + highFreq) * 2f; - - // Combine the current height, generated noise, start height, and height range parameters, then scale all of it - float layer = ((height + noise - startHeight) / heightRange) * 4f; - if (Single.IsNaN(layer)) layer = 0f; - layermap[y * 256 + x] = Utils.Clamp(layer, 0f, 3f); - } - } - - #endregion Layer Map - - #region Texture Compositing - - Bitmap output = new Bitmap(256, 256, PixelFormat.Format24bppRgb); - BitmapData outputData = output.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); - - unsafe - { - // Get handles to all of the texture data arrays - BitmapData[] datas = new BitmapData[] - { - detailTexture[0].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[0].PixelFormat), - detailTexture[1].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[1].PixelFormat), - detailTexture[2].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[2].PixelFormat), - detailTexture[3].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[3].PixelFormat) - }; - - int[] comps = new int[] - { - (datas[0].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, - (datas[1].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, - (datas[2].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, - (datas[3].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3 - }; - + + #region Layer Map + + float[] layermap = new float[256 * 256]; + for (int y = 0; y < 256; y++) { for (int x = 0; x < 256; x++) { - float layer = layermap[y * 256 + x]; - - // Select two textures - int l0 = (int)Math.Floor(layer); - int l1 = Math.Min(l0 + 1, 3); - - byte* ptrA = (byte*)datas[l0].Scan0 + y * datas[l0].Stride + x * comps[l0]; - byte* ptrB = (byte*)datas[l1].Scan0 + y * datas[l1].Stride + x * comps[l1]; - byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride + x * 3; - - float aB = *(ptrA + 0); - float aG = *(ptrA + 1); - float aR = *(ptrA + 2); - - float bB = *(ptrB + 0); - float bG = *(ptrB + 1); - float bR = *(ptrB + 2); - - float layerDiff = layer - l0; - - // Interpolate between the two selected textures - *(ptrO + 0) = (byte)Math.Floor(aB + layerDiff * (bB - aB)); - *(ptrO + 1) = (byte)Math.Floor(aG + layerDiff * (bG - aG)); - *(ptrO + 2) = (byte)Math.Floor(aR + layerDiff * (bR - aR)); + float height = heightmap[y * 256 + x]; + + float pctX = (float)x / 255f; + float pctY = (float)y / 255f; + + // Use bilinear interpolation between the four corners of start height and + // height range to select the current values at this position + float startHeight = ImageUtils.Bilinear( + startHeights[0], + startHeights[2], + startHeights[1], + startHeights[3], + pctX, pctY); + startHeight = Utils.Clamp(startHeight, 0f, 255f); + + float heightRange = ImageUtils.Bilinear( + heightRanges[0], + heightRanges[2], + heightRanges[1], + heightRanges[3], + pctX, pctY); + heightRange = Utils.Clamp(heightRange, 0f, 255f); + + // Generate two frequencies of perlin noise based on our global position + // The magic values were taken from http://opensimulator.org/wiki/Terrain_Splatting + Vector3 vec = new Vector3 + ( + ((float)regionPosition.X + x) * 0.20319f, + ((float)regionPosition.Y + y) * 0.20319f, + height * 0.25f + ); + + float lowFreq = Perlin.noise2(vec.X * 0.222222f, vec.Y * 0.222222f) * 6.5f; + float highFreq = Perlin.turbulence2(vec.X, vec.Y, 2f) * 2.25f; + float noise = (lowFreq + highFreq) * 2f; + + // Combine the current height, generated noise, start height, and height range parameters, then scale all of it + float layer = ((height + noise - startHeight) / heightRange) * 4f; + if (Single.IsNaN(layer)) layer = 0f; + layermap[y * 256 + x] = Utils.Clamp(layer, 0f, 3f); } } - + + #endregion Layer Map + + #region Texture Compositing + + output = new Bitmap(256, 256, PixelFormat.Format24bppRgb); + outputData = output.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); + + unsafe + { + // Get handles to all of the texture data arrays + BitmapData[] datas = new BitmapData[] + { + detailTexture[0].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[0].PixelFormat), + detailTexture[1].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[1].PixelFormat), + detailTexture[2].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[2].PixelFormat), + detailTexture[3].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[3].PixelFormat) + }; + + int[] comps = new int[] + { + (datas[0].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, + (datas[1].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, + (datas[2].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, + (datas[3].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3 + }; + + for (int y = 0; y < 256; y++) + { + for (int x = 0; x < 256; x++) + { + float layer = layermap[y * 256 + x]; + + // Select two textures + int l0 = (int)Math.Floor(layer); + int l1 = Math.Min(l0 + 1, 3); + + byte* ptrA = (byte*)datas[l0].Scan0 + y * datas[l0].Stride + x * comps[l0]; + byte* ptrB = (byte*)datas[l1].Scan0 + y * datas[l1].Stride + x * comps[l1]; + byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride + x * 3; + + float aB = *(ptrA + 0); + float aG = *(ptrA + 1); + float aR = *(ptrA + 2); + + float bB = *(ptrB + 0); + float bG = *(ptrB + 1); + float bR = *(ptrB + 2); + + float layerDiff = layer - l0; + + // Interpolate between the two selected textures + *(ptrO + 0) = (byte)Math.Floor(aB + layerDiff * (bB - aB)); + *(ptrO + 1) = (byte)Math.Floor(aG + layerDiff * (bG - aG)); + *(ptrO + 2) = (byte)Math.Floor(aR + layerDiff * (bR - aR)); + } + } + + for (int i = 0; i < 4; i++) + detailTexture[i].UnlockBits(datas[i]); + } + } + finally + { for (int i = 0; i < 4; i++) - detailTexture[i].UnlockBits(datas[i]); + if (detailTexture[i] != null) + detailTexture[i].Dispose(); } output.UnlockBits(outputData); diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 2335bea..c1c6b49 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -1343,14 +1343,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap if (terrain == null) return; + m_log.DebugFormat("[WORLDMAP]: Generating map image for {0}", m_scene.RegionInfo.RegionName); + byte[] data = terrain.WriteJpeg2000Image(); if (data == null) return; byte[] overlay = GenerateOverlay(); - m_log.Debug("[WORLDMAP]: STORING MAPTILE IMAGE"); - UUID terrainImageID = UUID.Random(); UUID parcelImageID = UUID.Zero; @@ -1365,7 +1365,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap asset.Flags = AssetFlags.Maptile; // Store the new one - m_log.DebugFormat("[WORLDMAP]: Storing map tile {0}", asset.ID); + m_log.DebugFormat("[WORLDMAP]: Storing map tile {0} for {1}", asset.ID, m_scene.RegionInfo.RegionName); + m_scene.AssetService.Store(asset); if (overlay != null) -- cgit v1.1 From 53c25a47780b5b1167f8e574dc8e9b935a0d5ddd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 6 Jun 2012 04:15:00 +0100 Subject: Rename MapImageModule for Warp3D to Warp3DImageModule to match its class name and make it easier to distinguish between map image modules. --- .../CoreModules/World/Warp3DMap/MapImageModule.cs | 674 --------------------- .../World/Warp3DMap/Warp3DImageModule.cs | 674 +++++++++++++++++++++ 2 files changed, 674 insertions(+), 674 deletions(-) delete mode 100644 OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs create mode 100644 OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs deleted file mode 100644 index 3538b46..0000000 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs +++ /dev/null @@ -1,674 +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.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Reflection; -using CSJ2K; -using Nini.Config; -using log4net; -using Rednettle.Warp3D; -using OpenMetaverse; -using OpenMetaverse.Imaging; -using OpenMetaverse.Rendering; -using OpenMetaverse.StructuredData; -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Physics.Manager; -using OpenSim.Services.Interfaces; - -using WarpRenderer = global::Warp3D.Warp3D; - -namespace OpenSim.Region.CoreModules.World.Warp3DMap -{ - public class Warp3DImageModule : IMapImageGenerator, INonSharedRegionModule - { - private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3"); - private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 216); - - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private Scene m_scene; - private IRendering m_primMesher; - private IConfigSource m_config; - private Dictionary m_colors = new Dictionary(); - private bool m_useAntiAliasing = false; // TODO: Make this a config option - private bool m_Enabled = false; - - #region IRegionModule Members - - public void Initialise(IConfigSource source) - { - m_config = source; - - IConfig startupConfig = m_config.Configs["Startup"]; - if (startupConfig.GetString("MapImageModule", "MapImageModule") != "Warp3DImageModule") - return; - - m_Enabled = true; - } - - public void AddRegion(Scene scene) - { - if (!m_Enabled) - return; - - m_scene = scene; - - List renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); - if (renderers.Count > 0) - { - m_primMesher = RenderingLoader.LoadRenderer(renderers[0]); - m_log.Debug("[MAPTILE]: Loaded prim mesher " + m_primMesher.ToString()); - } - else - { - m_log.Debug("[MAPTILE]: No prim mesher loaded, prim rendering will be disabled"); - } - - m_scene.RegisterModuleInterface(this); - } - - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - } - - public void Close() - { - } - - public string Name - { - get { return "Warp3DImageModule"; } - } - - public Type ReplaceableInterface - { - get { return null; } - } - - #endregion - - #region IMapImageGenerator Members - - public Bitmap CreateMapTile() - { - Vector3 camPos = new Vector3(127.5f, 127.5f, 221.7025033688163f); - Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, (int)Constants.RegionSize, (int)Constants.RegionSize, (float)Constants.RegionSize, (float)Constants.RegionSize); - return CreateMapTile(viewport, false); - } - - public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures) - { - Viewport viewport = new Viewport(camPos, camDir, fov, (float)Constants.RegionSize, 0.1f, width, height); - return CreateMapTile(viewport, useTextures); - } - - public Bitmap CreateMapTile(Viewport viewport, bool useTextures) - { - bool drawPrimVolume = true; - bool textureTerrain = true; - - try - { - IConfig startupConfig = m_config.Configs["Startup"]; - drawPrimVolume = startupConfig.GetBoolean("DrawPrimOnMapTile", drawPrimVolume); - textureTerrain = startupConfig.GetBoolean("TextureOnMapTile", textureTerrain); - } - catch - { - m_log.Warn("[MAPTILE]: Failed to load StartupConfig"); - } - - m_colors.Clear(); - - int width = viewport.Width; - int height = viewport.Height; - - if (m_useAntiAliasing) - { - width *= 2; - height *= 2; - } - - WarpRenderer renderer = new WarpRenderer(); - renderer.CreateScene(width, height); - renderer.Scene.autoCalcNormals = false; - - #region Camera - - warp_Vector pos = ConvertVector(viewport.Position); - pos.z -= 0.001f; // Works around an issue with the Warp3D camera - warp_Vector lookat = warp_Vector.add(ConvertVector(viewport.Position), ConvertVector(viewport.LookDirection)); - - renderer.Scene.defaultCamera.setPos(pos); - renderer.Scene.defaultCamera.lookAt(lookat); - - if (viewport.Orthographic) - { - renderer.Scene.defaultCamera.isOrthographic = true; - renderer.Scene.defaultCamera.orthoViewWidth = viewport.OrthoWindowWidth; - renderer.Scene.defaultCamera.orthoViewHeight = viewport.OrthoWindowHeight; - } - else - { - float fov = viewport.FieldOfView; - fov *= 1.75f; // FIXME: ??? - renderer.Scene.defaultCamera.setFov(fov); - } - - #endregion Camera - - renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(1.0f, 0.5f, 1f), 0xffffff, 0, 320, 40)); - renderer.Scene.addLight("Light2", new warp_Light(new warp_Vector(-1f, -1f, 1f), 0xffffff, 0, 100, 40)); - - CreateWater(renderer); - CreateTerrain(renderer, textureTerrain); - if (drawPrimVolume) - CreateAllPrims(renderer, useTextures); - - renderer.Render(); - Bitmap bitmap = renderer.Scene.getImage(); - - if (m_useAntiAliasing) - { - using (Bitmap origBitmap = bitmap) - bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height); - } - - return bitmap; - } - - public byte[] WriteJpeg2000Image() - { - try - { - using (Bitmap mapbmp = CreateMapTile()) - return OpenJPEG.EncodeFromImage(mapbmp, true); - } - catch (Exception e) - { - // JPEG2000 encoder failed - m_log.Error("[MAPTILE]: Failed generating terrain map: " + e); - } - - return null; - } - - #endregion - - #region Rendering Methods - - private void CreateWater(WarpRenderer renderer) - { - float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight; - - renderer.AddPlane("Water", 256f * 0.5f); - renderer.Scene.sceneobject("Water").setPos(127.5f, waterHeight, 127.5f); - - renderer.AddMaterial("WaterColor", ConvertColor(WATER_COLOR)); - renderer.Scene.material("WaterColor").setReflectivity(0); // match water color with standard map module thanks lkalif - renderer.Scene.material("WaterColor").setTransparency((byte)((1f - WATER_COLOR.A) * 255f)); - renderer.SetObjectMaterial("Water", "WaterColor"); - } - - private void CreateTerrain(WarpRenderer renderer, bool textureTerrain) - { - ITerrainChannel terrain = m_scene.Heightmap; - float[] heightmap = terrain.GetFloatsSerialised(); - - warp_Object obj = new warp_Object(256 * 256, 255 * 255 * 2); - - for (int y = 0; y < 256; y++) - { - for (int x = 0; x < 256; x++) - { - int v = y * 256 + x; - float height = heightmap[v]; - - warp_Vector pos = ConvertVector(new Vector3(x, y, height)); - obj.addVertex(new warp_Vertex(pos, (float)x / 255f, (float)(255 - y) / 255f)); - } - } - - for (int y = 0; y < 256; y++) - { - for (int x = 0; x < 256; x++) - { - if (x < 255 && y < 255) - { - int v = y * 256 + x; - - // Normal - Vector3 v1 = new Vector3(x, y, heightmap[y * 256 + x]); - Vector3 v2 = new Vector3(x + 1, y, heightmap[y * 256 + x + 1]); - Vector3 v3 = new Vector3(x, y + 1, heightmap[(y + 1) * 256 + x]); - warp_Vector norm = ConvertVector(SurfaceNormal(v1, v2, v3)); - norm = norm.reverse(); - obj.vertex(v).n = norm; - - // Triangle 1 - obj.addTriangle( - v, - v + 1, - v + 256); - - // Triangle 2 - obj.addTriangle( - v + 256 + 1, - v + 256, - v + 1); - } - } - } - - renderer.Scene.addObject("Terrain", obj); - - UUID[] textureIDs = new UUID[4]; - float[] startHeights = new float[4]; - float[] heightRanges = new float[4]; - - RegionSettings regionInfo = m_scene.RegionInfo.RegionSettings; - - textureIDs[0] = regionInfo.TerrainTexture1; - textureIDs[1] = regionInfo.TerrainTexture2; - textureIDs[2] = regionInfo.TerrainTexture3; - textureIDs[3] = regionInfo.TerrainTexture4; - - startHeights[0] = (float)regionInfo.Elevation1SW; - startHeights[1] = (float)regionInfo.Elevation1NW; - startHeights[2] = (float)regionInfo.Elevation1SE; - startHeights[3] = (float)regionInfo.Elevation1NE; - - heightRanges[0] = (float)regionInfo.Elevation2SW; - heightRanges[1] = (float)regionInfo.Elevation2NW; - heightRanges[2] = (float)regionInfo.Elevation2SE; - heightRanges[3] = (float)regionInfo.Elevation2NE; - - uint globalX, globalY; - Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out globalX, out globalY); - - warp_Texture texture; - - using ( - Bitmap image - = TerrainSplat.Splat( - heightmap, textureIDs, startHeights, heightRanges, - new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain)) - { - texture = new warp_Texture(image); - } - - warp_Material material = new warp_Material(texture); - material.setReflectivity(50); - renderer.Scene.addMaterial("TerrainColor", material); - renderer.Scene.material("TerrainColor").setReflectivity(0); // reduces tile seams a bit thanks lkalif - renderer.SetObjectMaterial("Terrain", "TerrainColor"); - } - - private void CreateAllPrims(WarpRenderer renderer, bool useTextures) - { - if (m_primMesher == null) - return; - - m_scene.ForEachSOG( - delegate(SceneObjectGroup group) - { - CreatePrim(renderer, group.RootPart, useTextures); - foreach (SceneObjectPart child in group.Parts) - CreatePrim(renderer, child, useTextures); - } - ); - } - - private void CreatePrim(WarpRenderer renderer, SceneObjectPart prim, - bool useTextures) - { - const float MIN_SIZE = 2f; - - if ((PCode)prim.Shape.PCode != PCode.Prim) - return; - if (prim.Scale.LengthSquared() < MIN_SIZE * MIN_SIZE) - return; - - Primitive omvPrim = prim.Shape.ToOmvPrimitive(prim.OffsetPosition, prim.RotationOffset); - FacetedMesh renderMesh = m_primMesher.GenerateFacetedMesh(omvPrim, DetailLevel.Medium); - if (renderMesh == null) - return; - - warp_Vector primPos = ConvertVector(prim.GetWorldPosition()); - warp_Quaternion primRot = ConvertQuaternion(prim.RotationOffset); - - warp_Matrix m = warp_Matrix.quaternionMatrix(primRot); - - if (prim.ParentID != 0) - { - SceneObjectGroup group = m_scene.SceneGraph.GetGroupByPrim(prim.LocalId); - if (group != null) - m.transform(warp_Matrix.quaternionMatrix(ConvertQuaternion(group.RootPart.RotationOffset))); - } - - warp_Vector primScale = ConvertVector(prim.Scale); - - string primID = prim.UUID.ToString(); - - // Create the prim faces - // TODO: Implement the useTextures flag behavior - for (int i = 0; i < renderMesh.Faces.Count; i++) - { - Face face = renderMesh.Faces[i]; - string meshName = primID + "-Face-" + i.ToString(); - - // Avoid adding duplicate meshes to the scene - if (renderer.Scene.objectData.ContainsKey(meshName)) - { - continue; - } - - warp_Object faceObj = new warp_Object(face.Vertices.Count, face.Indices.Count / 3); - - for (int j = 0; j < face.Vertices.Count; j++) - { - Vertex v = face.Vertices[j]; - - warp_Vector pos = ConvertVector(v.Position); - warp_Vector norm = ConvertVector(v.Normal); - - if (prim.Shape.SculptTexture == UUID.Zero) - norm = norm.reverse(); - warp_Vertex vert = new warp_Vertex(pos, norm, v.TexCoord.X, v.TexCoord.Y); - - faceObj.addVertex(vert); - } - - for (int j = 0; j < face.Indices.Count; j += 3) - { - faceObj.addTriangle( - face.Indices[j + 0], - face.Indices[j + 1], - face.Indices[j + 2]); - } - - Primitive.TextureEntryFace teFace = prim.Shape.Textures.GetFace((uint)i); - Color4 faceColor = GetFaceColor(teFace); - string materialName = GetOrCreateMaterial(renderer, faceColor); - - faceObj.transform(m); - faceObj.setPos(primPos); - faceObj.scaleSelf(primScale.x, primScale.y, primScale.z); - - renderer.Scene.addObject(meshName, faceObj); - - renderer.SetObjectMaterial(meshName, materialName); - } - } - - private Color4 GetFaceColor(Primitive.TextureEntryFace face) - { - Color4 color; - - if (face.TextureID == UUID.Zero) - return face.RGBA; - - if (!m_colors.TryGetValue(face.TextureID, out color)) - { - bool fetched = false; - - // Attempt to fetch the texture metadata - UUID metadataID = UUID.Combine(face.TextureID, TEXTURE_METADATA_MAGIC); - AssetBase metadata = m_scene.AssetService.GetCached(metadataID.ToString()); - if (metadata != null) - { - OSDMap map = null; - try { map = OSDParser.Deserialize(metadata.Data) as OSDMap; } catch { } - - if (map != null) - { - color = map["X-JPEG2000-RGBA"].AsColor4(); - fetched = true; - } - } - - if (!fetched) - { - // Fetch the texture, decode and get the average color, - // then save it to a temporary metadata asset - AssetBase textureAsset = m_scene.AssetService.Get(face.TextureID.ToString()); - if (textureAsset != null) - { - int width, height; - color = GetAverageColor(textureAsset.FullID, textureAsset.Data, out width, out height); - - OSDMap data = new OSDMap { { "X-JPEG2000-RGBA", OSD.FromColor4(color) } }; - metadata = new AssetBase - { - Data = System.Text.Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(data)), - Description = "Metadata for JPEG2000 texture " + face.TextureID.ToString(), - Flags = AssetFlags.Collectable, - FullID = metadataID, - ID = metadataID.ToString(), - Local = true, - Temporary = true, - Name = String.Empty, - Type = (sbyte)AssetType.Unknown - }; - m_scene.AssetService.Store(metadata); - } - else - { - color = new Color4(0.5f, 0.5f, 0.5f, 1.0f); - } - } - - m_colors[face.TextureID] = color; - } - - return color * face.RGBA; - } - - private string GetOrCreateMaterial(WarpRenderer renderer, Color4 color) - { - string name = color.ToString(); - - warp_Material material = renderer.Scene.material(name); - if (material != null) - return name; - - renderer.AddMaterial(name, ConvertColor(color)); - if (color.A < 1f) - renderer.Scene.material(name).setTransparency((byte)((1f - color.A) * 255f)); - return name; - } - - #endregion Rendering Methods - - #region Static Helpers - - private static warp_Vector ConvertVector(Vector3 vector) - { - return new warp_Vector(vector.X, vector.Z, vector.Y); - } - - private static warp_Quaternion ConvertQuaternion(Quaternion quat) - { - return new warp_Quaternion(quat.X, quat.Z, quat.Y, -quat.W); - } - - private static int ConvertColor(Color4 color) - { - int c = warp_Color.getColor((byte)(color.R * 255f), (byte)(color.G * 255f), (byte)(color.B * 255f)); - if (color.A < 1f) - c |= (byte)(color.A * 255f) << 24; - - return c; - } - - private static Vector3 SurfaceNormal(Vector3 c1, Vector3 c2, Vector3 c3) - { - Vector3 edge1 = new Vector3(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z); - Vector3 edge2 = new Vector3(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z); - - Vector3 normal = Vector3.Cross(edge1, edge2); - normal.Normalize(); - - return normal; - } - - public static Color4 GetAverageColor(UUID textureID, byte[] j2kData, out int width, out int height) - { - ulong r = 0; - ulong g = 0; - ulong b = 0; - ulong a = 0; - - using (MemoryStream stream = new MemoryStream(j2kData)) - { - try - { - int pixelBytes; - - using (Bitmap bitmap = (Bitmap)J2kImage.FromStream(stream)) - { - width = bitmap.Width; - height = bitmap.Height; - - BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat); - pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; - - // Sum up the individual channels - unsafe - { - if (pixelBytes == 4) - { - for (int y = 0; y < height; y++) - { - byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); - - for (int x = 0; x < width; x++) - { - b += row[x * pixelBytes + 0]; - g += row[x * pixelBytes + 1]; - r += row[x * pixelBytes + 2]; - a += row[x * pixelBytes + 3]; - } - } - } - else - { - for (int y = 0; y < height; y++) - { - byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); - - for (int x = 0; x < width; x++) - { - b += row[x * pixelBytes + 0]; - g += row[x * pixelBytes + 1]; - r += row[x * pixelBytes + 2]; - } - } - } - } - } - - // Get the averages for each channel - const decimal OO_255 = 1m / 255m; - decimal totalPixels = (decimal)(width * height); - - decimal rm = ((decimal)r / totalPixels) * OO_255; - decimal gm = ((decimal)g / totalPixels) * OO_255; - decimal bm = ((decimal)b / totalPixels) * OO_255; - decimal am = ((decimal)a / totalPixels) * OO_255; - - if (pixelBytes == 3) - am = 1m; - - return new Color4((float)rm, (float)gm, (float)bm, (float)am); - } - catch (Exception ex) - { - m_log.WarnFormat("[MAPTILE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}", textureID, j2kData.Length, ex.Message); - width = 0; - height = 0; - return new Color4(0.5f, 0.5f, 0.5f, 1.0f); - } - } - } - - #endregion Static Helpers - } - - public static class ImageUtils - { - /// - /// Performs bilinear interpolation between four values - /// - /// First, or top left value - /// Second, or top right value - /// Third, or bottom left value - /// Fourth, or bottom right value - /// Interpolation value on the X axis, between 0.0 and 1.0 - /// Interpolation value on fht Y axis, between 0.0 and 1.0 - /// The bilinearly interpolated result - public static float Bilinear(float v00, float v01, float v10, float v11, float xPercent, float yPercent) - { - return Utils.Lerp(Utils.Lerp(v00, v01, xPercent), Utils.Lerp(v10, v11, xPercent), yPercent); - } - - /// - /// Performs a high quality image resize - /// - /// Image to resize - /// New width - /// New height - /// Resized image - public static Bitmap ResizeImage(Image image, int width, int height) - { - Bitmap result = new Bitmap(width, height); - - using (Graphics graphics = Graphics.FromImage(result)) - { - graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; - graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; - graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; - graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; - - graphics.DrawImage(image, 0, 0, result.Width, result.Height); - } - - return result; - } - } -} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs new file mode 100644 index 0000000..3538b46 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs @@ -0,0 +1,674 @@ +/* + * 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.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Reflection; +using CSJ2K; +using Nini.Config; +using log4net; +using Rednettle.Warp3D; +using OpenMetaverse; +using OpenMetaverse.Imaging; +using OpenMetaverse.Rendering; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Physics.Manager; +using OpenSim.Services.Interfaces; + +using WarpRenderer = global::Warp3D.Warp3D; + +namespace OpenSim.Region.CoreModules.World.Warp3DMap +{ + public class Warp3DImageModule : IMapImageGenerator, INonSharedRegionModule + { + private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3"); + private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 216); + + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_scene; + private IRendering m_primMesher; + private IConfigSource m_config; + private Dictionary m_colors = new Dictionary(); + private bool m_useAntiAliasing = false; // TODO: Make this a config option + private bool m_Enabled = false; + + #region IRegionModule Members + + public void Initialise(IConfigSource source) + { + m_config = source; + + IConfig startupConfig = m_config.Configs["Startup"]; + if (startupConfig.GetString("MapImageModule", "MapImageModule") != "Warp3DImageModule") + return; + + m_Enabled = true; + } + + public void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + m_scene = scene; + + List renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); + if (renderers.Count > 0) + { + m_primMesher = RenderingLoader.LoadRenderer(renderers[0]); + m_log.Debug("[MAPTILE]: Loaded prim mesher " + m_primMesher.ToString()); + } + else + { + m_log.Debug("[MAPTILE]: No prim mesher loaded, prim rendering will be disabled"); + } + + m_scene.RegisterModuleInterface(this); + } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + } + + public void Close() + { + } + + public string Name + { + get { return "Warp3DImageModule"; } + } + + public Type ReplaceableInterface + { + get { return null; } + } + + #endregion + + #region IMapImageGenerator Members + + public Bitmap CreateMapTile() + { + Vector3 camPos = new Vector3(127.5f, 127.5f, 221.7025033688163f); + Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, (int)Constants.RegionSize, (int)Constants.RegionSize, (float)Constants.RegionSize, (float)Constants.RegionSize); + return CreateMapTile(viewport, false); + } + + public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures) + { + Viewport viewport = new Viewport(camPos, camDir, fov, (float)Constants.RegionSize, 0.1f, width, height); + return CreateMapTile(viewport, useTextures); + } + + public Bitmap CreateMapTile(Viewport viewport, bool useTextures) + { + bool drawPrimVolume = true; + bool textureTerrain = true; + + try + { + IConfig startupConfig = m_config.Configs["Startup"]; + drawPrimVolume = startupConfig.GetBoolean("DrawPrimOnMapTile", drawPrimVolume); + textureTerrain = startupConfig.GetBoolean("TextureOnMapTile", textureTerrain); + } + catch + { + m_log.Warn("[MAPTILE]: Failed to load StartupConfig"); + } + + m_colors.Clear(); + + int width = viewport.Width; + int height = viewport.Height; + + if (m_useAntiAliasing) + { + width *= 2; + height *= 2; + } + + WarpRenderer renderer = new WarpRenderer(); + renderer.CreateScene(width, height); + renderer.Scene.autoCalcNormals = false; + + #region Camera + + warp_Vector pos = ConvertVector(viewport.Position); + pos.z -= 0.001f; // Works around an issue with the Warp3D camera + warp_Vector lookat = warp_Vector.add(ConvertVector(viewport.Position), ConvertVector(viewport.LookDirection)); + + renderer.Scene.defaultCamera.setPos(pos); + renderer.Scene.defaultCamera.lookAt(lookat); + + if (viewport.Orthographic) + { + renderer.Scene.defaultCamera.isOrthographic = true; + renderer.Scene.defaultCamera.orthoViewWidth = viewport.OrthoWindowWidth; + renderer.Scene.defaultCamera.orthoViewHeight = viewport.OrthoWindowHeight; + } + else + { + float fov = viewport.FieldOfView; + fov *= 1.75f; // FIXME: ??? + renderer.Scene.defaultCamera.setFov(fov); + } + + #endregion Camera + + renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(1.0f, 0.5f, 1f), 0xffffff, 0, 320, 40)); + renderer.Scene.addLight("Light2", new warp_Light(new warp_Vector(-1f, -1f, 1f), 0xffffff, 0, 100, 40)); + + CreateWater(renderer); + CreateTerrain(renderer, textureTerrain); + if (drawPrimVolume) + CreateAllPrims(renderer, useTextures); + + renderer.Render(); + Bitmap bitmap = renderer.Scene.getImage(); + + if (m_useAntiAliasing) + { + using (Bitmap origBitmap = bitmap) + bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height); + } + + return bitmap; + } + + public byte[] WriteJpeg2000Image() + { + try + { + using (Bitmap mapbmp = CreateMapTile()) + return OpenJPEG.EncodeFromImage(mapbmp, true); + } + catch (Exception e) + { + // JPEG2000 encoder failed + m_log.Error("[MAPTILE]: Failed generating terrain map: " + e); + } + + return null; + } + + #endregion + + #region Rendering Methods + + private void CreateWater(WarpRenderer renderer) + { + float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight; + + renderer.AddPlane("Water", 256f * 0.5f); + renderer.Scene.sceneobject("Water").setPos(127.5f, waterHeight, 127.5f); + + renderer.AddMaterial("WaterColor", ConvertColor(WATER_COLOR)); + renderer.Scene.material("WaterColor").setReflectivity(0); // match water color with standard map module thanks lkalif + renderer.Scene.material("WaterColor").setTransparency((byte)((1f - WATER_COLOR.A) * 255f)); + renderer.SetObjectMaterial("Water", "WaterColor"); + } + + private void CreateTerrain(WarpRenderer renderer, bool textureTerrain) + { + ITerrainChannel terrain = m_scene.Heightmap; + float[] heightmap = terrain.GetFloatsSerialised(); + + warp_Object obj = new warp_Object(256 * 256, 255 * 255 * 2); + + for (int y = 0; y < 256; y++) + { + for (int x = 0; x < 256; x++) + { + int v = y * 256 + x; + float height = heightmap[v]; + + warp_Vector pos = ConvertVector(new Vector3(x, y, height)); + obj.addVertex(new warp_Vertex(pos, (float)x / 255f, (float)(255 - y) / 255f)); + } + } + + for (int y = 0; y < 256; y++) + { + for (int x = 0; x < 256; x++) + { + if (x < 255 && y < 255) + { + int v = y * 256 + x; + + // Normal + Vector3 v1 = new Vector3(x, y, heightmap[y * 256 + x]); + Vector3 v2 = new Vector3(x + 1, y, heightmap[y * 256 + x + 1]); + Vector3 v3 = new Vector3(x, y + 1, heightmap[(y + 1) * 256 + x]); + warp_Vector norm = ConvertVector(SurfaceNormal(v1, v2, v3)); + norm = norm.reverse(); + obj.vertex(v).n = norm; + + // Triangle 1 + obj.addTriangle( + v, + v + 1, + v + 256); + + // Triangle 2 + obj.addTriangle( + v + 256 + 1, + v + 256, + v + 1); + } + } + } + + renderer.Scene.addObject("Terrain", obj); + + UUID[] textureIDs = new UUID[4]; + float[] startHeights = new float[4]; + float[] heightRanges = new float[4]; + + RegionSettings regionInfo = m_scene.RegionInfo.RegionSettings; + + textureIDs[0] = regionInfo.TerrainTexture1; + textureIDs[1] = regionInfo.TerrainTexture2; + textureIDs[2] = regionInfo.TerrainTexture3; + textureIDs[3] = regionInfo.TerrainTexture4; + + startHeights[0] = (float)regionInfo.Elevation1SW; + startHeights[1] = (float)regionInfo.Elevation1NW; + startHeights[2] = (float)regionInfo.Elevation1SE; + startHeights[3] = (float)regionInfo.Elevation1NE; + + heightRanges[0] = (float)regionInfo.Elevation2SW; + heightRanges[1] = (float)regionInfo.Elevation2NW; + heightRanges[2] = (float)regionInfo.Elevation2SE; + heightRanges[3] = (float)regionInfo.Elevation2NE; + + uint globalX, globalY; + Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out globalX, out globalY); + + warp_Texture texture; + + using ( + Bitmap image + = TerrainSplat.Splat( + heightmap, textureIDs, startHeights, heightRanges, + new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain)) + { + texture = new warp_Texture(image); + } + + warp_Material material = new warp_Material(texture); + material.setReflectivity(50); + renderer.Scene.addMaterial("TerrainColor", material); + renderer.Scene.material("TerrainColor").setReflectivity(0); // reduces tile seams a bit thanks lkalif + renderer.SetObjectMaterial("Terrain", "TerrainColor"); + } + + private void CreateAllPrims(WarpRenderer renderer, bool useTextures) + { + if (m_primMesher == null) + return; + + m_scene.ForEachSOG( + delegate(SceneObjectGroup group) + { + CreatePrim(renderer, group.RootPart, useTextures); + foreach (SceneObjectPart child in group.Parts) + CreatePrim(renderer, child, useTextures); + } + ); + } + + private void CreatePrim(WarpRenderer renderer, SceneObjectPart prim, + bool useTextures) + { + const float MIN_SIZE = 2f; + + if ((PCode)prim.Shape.PCode != PCode.Prim) + return; + if (prim.Scale.LengthSquared() < MIN_SIZE * MIN_SIZE) + return; + + Primitive omvPrim = prim.Shape.ToOmvPrimitive(prim.OffsetPosition, prim.RotationOffset); + FacetedMesh renderMesh = m_primMesher.GenerateFacetedMesh(omvPrim, DetailLevel.Medium); + if (renderMesh == null) + return; + + warp_Vector primPos = ConvertVector(prim.GetWorldPosition()); + warp_Quaternion primRot = ConvertQuaternion(prim.RotationOffset); + + warp_Matrix m = warp_Matrix.quaternionMatrix(primRot); + + if (prim.ParentID != 0) + { + SceneObjectGroup group = m_scene.SceneGraph.GetGroupByPrim(prim.LocalId); + if (group != null) + m.transform(warp_Matrix.quaternionMatrix(ConvertQuaternion(group.RootPart.RotationOffset))); + } + + warp_Vector primScale = ConvertVector(prim.Scale); + + string primID = prim.UUID.ToString(); + + // Create the prim faces + // TODO: Implement the useTextures flag behavior + for (int i = 0; i < renderMesh.Faces.Count; i++) + { + Face face = renderMesh.Faces[i]; + string meshName = primID + "-Face-" + i.ToString(); + + // Avoid adding duplicate meshes to the scene + if (renderer.Scene.objectData.ContainsKey(meshName)) + { + continue; + } + + warp_Object faceObj = new warp_Object(face.Vertices.Count, face.Indices.Count / 3); + + for (int j = 0; j < face.Vertices.Count; j++) + { + Vertex v = face.Vertices[j]; + + warp_Vector pos = ConvertVector(v.Position); + warp_Vector norm = ConvertVector(v.Normal); + + if (prim.Shape.SculptTexture == UUID.Zero) + norm = norm.reverse(); + warp_Vertex vert = new warp_Vertex(pos, norm, v.TexCoord.X, v.TexCoord.Y); + + faceObj.addVertex(vert); + } + + for (int j = 0; j < face.Indices.Count; j += 3) + { + faceObj.addTriangle( + face.Indices[j + 0], + face.Indices[j + 1], + face.Indices[j + 2]); + } + + Primitive.TextureEntryFace teFace = prim.Shape.Textures.GetFace((uint)i); + Color4 faceColor = GetFaceColor(teFace); + string materialName = GetOrCreateMaterial(renderer, faceColor); + + faceObj.transform(m); + faceObj.setPos(primPos); + faceObj.scaleSelf(primScale.x, primScale.y, primScale.z); + + renderer.Scene.addObject(meshName, faceObj); + + renderer.SetObjectMaterial(meshName, materialName); + } + } + + private Color4 GetFaceColor(Primitive.TextureEntryFace face) + { + Color4 color; + + if (face.TextureID == UUID.Zero) + return face.RGBA; + + if (!m_colors.TryGetValue(face.TextureID, out color)) + { + bool fetched = false; + + // Attempt to fetch the texture metadata + UUID metadataID = UUID.Combine(face.TextureID, TEXTURE_METADATA_MAGIC); + AssetBase metadata = m_scene.AssetService.GetCached(metadataID.ToString()); + if (metadata != null) + { + OSDMap map = null; + try { map = OSDParser.Deserialize(metadata.Data) as OSDMap; } catch { } + + if (map != null) + { + color = map["X-JPEG2000-RGBA"].AsColor4(); + fetched = true; + } + } + + if (!fetched) + { + // Fetch the texture, decode and get the average color, + // then save it to a temporary metadata asset + AssetBase textureAsset = m_scene.AssetService.Get(face.TextureID.ToString()); + if (textureAsset != null) + { + int width, height; + color = GetAverageColor(textureAsset.FullID, textureAsset.Data, out width, out height); + + OSDMap data = new OSDMap { { "X-JPEG2000-RGBA", OSD.FromColor4(color) } }; + metadata = new AssetBase + { + Data = System.Text.Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(data)), + Description = "Metadata for JPEG2000 texture " + face.TextureID.ToString(), + Flags = AssetFlags.Collectable, + FullID = metadataID, + ID = metadataID.ToString(), + Local = true, + Temporary = true, + Name = String.Empty, + Type = (sbyte)AssetType.Unknown + }; + m_scene.AssetService.Store(metadata); + } + else + { + color = new Color4(0.5f, 0.5f, 0.5f, 1.0f); + } + } + + m_colors[face.TextureID] = color; + } + + return color * face.RGBA; + } + + private string GetOrCreateMaterial(WarpRenderer renderer, Color4 color) + { + string name = color.ToString(); + + warp_Material material = renderer.Scene.material(name); + if (material != null) + return name; + + renderer.AddMaterial(name, ConvertColor(color)); + if (color.A < 1f) + renderer.Scene.material(name).setTransparency((byte)((1f - color.A) * 255f)); + return name; + } + + #endregion Rendering Methods + + #region Static Helpers + + private static warp_Vector ConvertVector(Vector3 vector) + { + return new warp_Vector(vector.X, vector.Z, vector.Y); + } + + private static warp_Quaternion ConvertQuaternion(Quaternion quat) + { + return new warp_Quaternion(quat.X, quat.Z, quat.Y, -quat.W); + } + + private static int ConvertColor(Color4 color) + { + int c = warp_Color.getColor((byte)(color.R * 255f), (byte)(color.G * 255f), (byte)(color.B * 255f)); + if (color.A < 1f) + c |= (byte)(color.A * 255f) << 24; + + return c; + } + + private static Vector3 SurfaceNormal(Vector3 c1, Vector3 c2, Vector3 c3) + { + Vector3 edge1 = new Vector3(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z); + Vector3 edge2 = new Vector3(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z); + + Vector3 normal = Vector3.Cross(edge1, edge2); + normal.Normalize(); + + return normal; + } + + public static Color4 GetAverageColor(UUID textureID, byte[] j2kData, out int width, out int height) + { + ulong r = 0; + ulong g = 0; + ulong b = 0; + ulong a = 0; + + using (MemoryStream stream = new MemoryStream(j2kData)) + { + try + { + int pixelBytes; + + using (Bitmap bitmap = (Bitmap)J2kImage.FromStream(stream)) + { + width = bitmap.Width; + height = bitmap.Height; + + BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat); + pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; + + // Sum up the individual channels + unsafe + { + if (pixelBytes == 4) + { + for (int y = 0; y < height; y++) + { + byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); + + for (int x = 0; x < width; x++) + { + b += row[x * pixelBytes + 0]; + g += row[x * pixelBytes + 1]; + r += row[x * pixelBytes + 2]; + a += row[x * pixelBytes + 3]; + } + } + } + else + { + for (int y = 0; y < height; y++) + { + byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); + + for (int x = 0; x < width; x++) + { + b += row[x * pixelBytes + 0]; + g += row[x * pixelBytes + 1]; + r += row[x * pixelBytes + 2]; + } + } + } + } + } + + // Get the averages for each channel + const decimal OO_255 = 1m / 255m; + decimal totalPixels = (decimal)(width * height); + + decimal rm = ((decimal)r / totalPixels) * OO_255; + decimal gm = ((decimal)g / totalPixels) * OO_255; + decimal bm = ((decimal)b / totalPixels) * OO_255; + decimal am = ((decimal)a / totalPixels) * OO_255; + + if (pixelBytes == 3) + am = 1m; + + return new Color4((float)rm, (float)gm, (float)bm, (float)am); + } + catch (Exception ex) + { + m_log.WarnFormat("[MAPTILE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}", textureID, j2kData.Length, ex.Message); + width = 0; + height = 0; + return new Color4(0.5f, 0.5f, 0.5f, 1.0f); + } + } + } + + #endregion Static Helpers + } + + public static class ImageUtils + { + /// + /// Performs bilinear interpolation between four values + /// + /// First, or top left value + /// Second, or top right value + /// Third, or bottom left value + /// Fourth, or bottom right value + /// Interpolation value on the X axis, between 0.0 and 1.0 + /// Interpolation value on fht Y axis, between 0.0 and 1.0 + /// The bilinearly interpolated result + public static float Bilinear(float v00, float v01, float v10, float v11, float xPercent, float yPercent) + { + return Utils.Lerp(Utils.Lerp(v00, v01, xPercent), Utils.Lerp(v10, v11, xPercent), yPercent); + } + + /// + /// Performs a high quality image resize + /// + /// Image to resize + /// New width + /// New height + /// Resized image + public static Bitmap ResizeImage(Image image, int width, int height) + { + Bitmap result = new Bitmap(width, height); + + using (Graphics graphics = Graphics.FromImage(result)) + { + graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; + graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; + graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; + + graphics.DrawImage(image, 0, 0, result.Width, result.Height); + } + + return result; + } + } +} \ No newline at end of file -- cgit v1.1 From 514dd85199331d8246c3a0dfc9cf782f61f48ef6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 6 Jun 2012 04:18:38 +0100 Subject: minor: Change log messages on Warp3DImageModule to show they are from this module --- .../CoreModules/World/Warp3DMap/Warp3DImageModule.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs index 3538b46..9002a9f 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs @@ -54,8 +54,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3"); private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 216); - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; private IRendering m_primMesher; @@ -88,11 +87,11 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap if (renderers.Count > 0) { m_primMesher = RenderingLoader.LoadRenderer(renderers[0]); - m_log.Debug("[MAPTILE]: Loaded prim mesher " + m_primMesher.ToString()); + m_log.DebugFormat("[WARP 3D IMAGE MODULE]: Loaded prim mesher {0}", m_primMesher); } else { - m_log.Debug("[MAPTILE]: No prim mesher loaded, prim rendering will be disabled"); + m_log.Debug("[WARP 3D IMAGE MODULE]: No prim mesher loaded, prim rendering will be disabled"); } m_scene.RegisterModuleInterface(this); @@ -150,7 +149,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap } catch { - m_log.Warn("[MAPTILE]: Failed to load StartupConfig"); + m_log.Warn("[WARP 3D IMAGE MODULE]: Failed to load StartupConfig"); } m_colors.Clear(); @@ -222,7 +221,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap catch (Exception e) { // JPEG2000 encoder failed - m_log.Error("[MAPTILE]: Failed generating terrain map: " + e); + m_log.Error("[WARP 3D IMAGE MODULE]: Failed generating terrain map: ", e); } return null; @@ -619,7 +618,10 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap } catch (Exception ex) { - m_log.WarnFormat("[MAPTILE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}", textureID, j2kData.Length, ex.Message); + m_log.WarnFormat( + "[WARP 3D IMAGE MODULE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}", + textureID, j2kData.Length, ex.Message); + width = 0; height = 0; return new Color4(0.5f, 0.5f, 0.5f, 1.0f); -- cgit v1.1 From 34cb8a2ab3189952cb74a16cf5246a2da3847b7c Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 6 Jun 2012 20:35:00 +0200 Subject: Fix not sending TransferInfo when an asset is not found. This clogs up the sound pipeline in the viewer. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 33 +++++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 9895402..18d8045 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -2777,6 +2777,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + public void SendAssetNotFound(AssetRequestToClient req) + { + TransferInfoPacket Transfer = new TransferInfoPacket(); + Transfer.TransferInfo.ChannelType = 2; + Transfer.TransferInfo.Status = -2; + Transfer.TransferInfo.TargetType = 0; + Transfer.TransferInfo.Params = req.Params; + Transfer.TransferInfo.Size = 0; + Transfer.TransferInfo.TransferID = req.TransferRequestID; + Transfer.Header.Zerocoded = true; + OutPacket(Transfer, ThrottleOutPacketType.Asset); + } + public void SendTexture(AssetBase TextureAsset) { @@ -12181,14 +12194,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// protected void AssetReceived(string id, Object sender, AssetBase asset) { - if (asset == null) - return; - TransferRequestPacket transferRequest = (TransferRequestPacket)sender; UUID requestID = UUID.Zero; byte source = (byte)SourceType.Asset; + AssetRequestToClient req = new AssetRequestToClient(); + + if (asset == null) + { + req.AssetInf = null; + req.AssetRequestSource = source; + req.IsTextureRequest = false; + req.NumPackets = 0; + req.Params = transferRequest.TransferInfo.Params; + req.RequestAssetID = requestID; + req.TransferRequestID = transferRequest.TransferInfo.TransferID; + + SendAssetNotFound(req); + return; + } + if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset) { requestID = new UUID(transferRequest.TransferInfo.Params, 0); @@ -12205,7 +12231,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP return; // The asset is known to exist and is in our cache, so add it to the AssetRequests list - AssetRequestToClient req = new AssetRequestToClient(); req.AssetInf = asset; req.AssetRequestSource = source; req.IsTextureRequest = false; -- cgit v1.1 From e09a74493f374b2fc837596f496b4338c49e074f Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 6 Jun 2012 20:35:37 +0200 Subject: Reverse the logic of a conditional. Clears up a merge artefact. --- .../Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 7db2491..b9897c4 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -430,7 +430,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, // it's actually doing a lot of work. IPEndPoint endPoint = finalDestination.ExternalEndPoint; - if (endPoint != null && endPoint.Address != null) + if (endPoint == null || endPoint.Address == null) { sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); m_entityTransferStateMachine.ResetFromTransit(sp.UUID); -- cgit v1.1 From 67483a6e50e491b65ce5fdbd36e06ba697772b36 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 6 Jun 2012 20:36:47 +0200 Subject: Remove two causes of recursive locking. Merge artefact cleanup. --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index f5b9825..81477e7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -176,16 +176,14 @@ namespace OpenSim.Region.Framework.Scenes /// public void ChangeInventoryOwner(UUID ownerId) { - m_items.LockItemsForWrite(true); - if (0 == Items.Count) - { - m_items.LockItemsForWrite(false); + List items = GetInventoryItems(); + + if (items.Count == 0) return; - } + m_items.LockItemsForWrite(true); HasInventoryChanged = true; m_part.ParentGroup.HasGroupChanged = true; - List items = GetInventoryItems(); foreach (TaskInventoryItem item in items) { if (ownerId != item.OwnerID) @@ -766,8 +764,8 @@ namespace OpenSim.Region.Framework.Scenes { if (item.Name == name) { - return item; m_items.LockItemsForRead(false); + return item; } } m_items.LockItemsForRead(false); -- cgit v1.1 From a12336390feda38cad0814ee62c1bfae43250030 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 6 Jun 2012 20:37:29 +0200 Subject: Remove useless logging of a bare-names stack trace. It's meaningless to a non-programmer and insufficient for a programmer. Add commented debug output and data collection to troubleshoot future locking issues. --- OpenSim/Framework/TaskInventoryDictionary.cs | 89 ++++++++++++++++++---------- 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs index 814758a..4d07746 100644 --- a/OpenSim/Framework/TaskInventoryDictionary.cs +++ b/OpenSim/Framework/TaskInventoryDictionary.cs @@ -52,10 +52,10 @@ namespace OpenSim.Framework private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Thread LockedByThread; - private string WriterStack; +// private string WriterStack; - private Dictionary ReadLockers = - new Dictionary(); +// private Dictionary ReadLockers = +// new Dictionary(); /// /// An advanced lock for inventory data @@ -98,14 +98,25 @@ namespace OpenSim.Framework m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); try { - StackTrace stackTrace = new StackTrace(); // get call stack - StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) + // That call stack is useful for end users only. RealProgrammers need a full dump. Commented. + // StackTrace stackTrace = new StackTrace(); // get call stack + // StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) + // + // // write call stack method names + // foreach (StackFrame stackFrame in stackFrames) + // { + // m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name + // } - // write call stack method names - foreach (StackFrame stackFrame in stackFrames) - { - m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name - } + // The below is far more useful +// System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); +// System.Console.WriteLine("------------------------------------------"); +// foreach (KeyValuePair kvp in ReadLockers) +// { +// System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name); +// System.Console.WriteLine("------------------------------------------"); +// } } catch {} @@ -114,6 +125,16 @@ namespace OpenSim.Framework if (m_itemLock.RecursiveWriteCount > 0) { m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed."); +// try +// { +// System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); +// System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("Locker's call stack:\n" + WriterStack); +// System.Console.WriteLine("------------------------------------------"); +// } +// catch +// {} m_itemLock.ExitWriteLock(); } @@ -123,15 +144,16 @@ namespace OpenSim.Framework if (m_itemLock.IsWriteLockHeld) { m_itemLock = new System.Threading.ReaderWriterLockSlim(); - System.Console.WriteLine("------------------------------------------"); - System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); - System.Console.WriteLine("------------------------------------------"); - System.Console.WriteLine("Locker's call stack:\n" + WriterStack); - System.Console.WriteLine("------------------------------------------"); - LockedByThread = null; - ReadLockers.Clear(); +// System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); +// System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("Locker's call stack:\n" + WriterStack); +// System.Console.WriteLine("------------------------------------------"); +// LockedByThread = null; +// ReadLockers.Clear(); } } +// ReadLockers[Thread.CurrentThread] = Environment.StackTrace; } else { @@ -139,6 +161,8 @@ namespace OpenSim.Framework { m_itemLock.ExitReadLock(); } +// if (m_itemLock.RecursiveReadCount == 0) +// ReadLockers.Remove(Thread.CurrentThread); } } @@ -158,6 +182,7 @@ namespace OpenSim.Framework if (m_itemLock.RecursiveWriteCount > 0) { m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed."); + m_itemLock.ExitWriteLock(); } while (!m_itemLock.TryEnterWriteLock(60000)) @@ -165,30 +190,30 @@ namespace OpenSim.Framework if (m_itemLock.IsWriteLockHeld) { m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); - System.Console.WriteLine("------------------------------------------"); - System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); - System.Console.WriteLine("------------------------------------------"); - System.Console.WriteLine("Locker's call stack:\n" + WriterStack); - System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); +// System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("Locker's call stack:\n" + WriterStack); +// System.Console.WriteLine("------------------------------------------"); } else { m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by a reader. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); - System.Console.WriteLine("------------------------------------------"); - System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); - System.Console.WriteLine("------------------------------------------"); - foreach (KeyValuePair kvp in ReadLockers) - { - System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name); - System.Console.WriteLine("------------------------------------------"); - } +// System.Console.WriteLine("------------------------------------------"); +// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); +// System.Console.WriteLine("------------------------------------------"); +// foreach (KeyValuePair kvp in ReadLockers) +// { +// System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name); +// System.Console.WriteLine("------------------------------------------"); +// } } m_itemLock = new System.Threading.ReaderWriterLockSlim(); - ReadLockers.Clear(); +// ReadLockers.Clear(); } LockedByThread = Thread.CurrentThread; - WriterStack = Environment.StackTrace; +// WriterStack = Environment.StackTrace; } else { -- cgit v1.1 From b02db11c6990986a65e6790b5520b15d1c47e51e Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 6 Jun 2012 20:38:42 +0200 Subject: Remove a null ref when an avatar's attachment gets the avatar velocity while the avatar is logging in or out. Also remove some unlocking calls without matching locking call. Merge artefact cleanup, again. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 5905958..e0b24dc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2498,12 +2498,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - Vector3 vel; + Vector3 vel = Vector3.Zero; if (m_host.ParentGroup.IsAttachment) { ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); - vel = avatar.Velocity; + if (avatar != null) + vel = avatar.Velocity; } else { @@ -10401,7 +10402,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ShoutError("No permissions to track the camera"); return new LSL_Vector(); } - m_host.TaskInventory.LockItemsForRead(false); // ScenePresence presence = World.GetScenePresence(m_host.OwnerID); ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); @@ -10425,7 +10425,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ShoutError("No permissions to track the camera"); return new LSL_Rotation(); } - m_host.TaskInventory.LockItemsForRead(false); // ScenePresence presence = World.GetScenePresence(m_host.OwnerID); ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); -- cgit v1.1 From 98b46d48fefc7801b7c9e496000e9329f4266e5e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 7 Jun 2012 02:44:13 +0100 Subject: Allow the thread watchdog to accept an alarm method that is invoked if the timeout is breached. This alarm can then invoke this to log extra information. This is used in LLUDPServer to show which client was being processed when incoming and outgoing udp watchdog alarms are triggered. --- .../HttpServer/PollServiceRequestManager.cs | 2 + OpenSim/Framework/Watchdog.cs | 40 +++++++------ OpenSim/Region/Application/OpenSim.cs | 10 +++- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 69 ++++++++++++++++++++-- 4 files changed, 96 insertions(+), 25 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index 0062d4e..f96fd1f 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs @@ -66,6 +66,7 @@ namespace OpenSim.Framework.Servers.HttpServer ThreadPriority.Normal, false, true, + null, int.MaxValue); } @@ -75,6 +76,7 @@ namespace OpenSim.Framework.Servers.HttpServer ThreadPriority.Normal, false, true, + null, 1000 * 60 * 10); } diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs index e93e50e..7552cd1 100644 --- a/OpenSim/Framework/Watchdog.cs +++ b/OpenSim/Framework/Watchdog.cs @@ -42,7 +42,7 @@ namespace OpenSim.Framework const double WATCHDOG_INTERVAL_MS = 2500.0d; /// Maximum timeout in milliseconds before a thread is considered dead - const int WATCHDOG_TIMEOUT_MS = 5000; + public const int WATCHDOG_TIMEOUT_MS = 5000; [System.Diagnostics.DebuggerDisplay("{Thread.Name}")] public class ThreadWatchdogInfo @@ -58,7 +58,7 @@ namespace OpenSim.Framework public int FirstTick { get; private set; } /// - /// First time this heartbeat update was invoked + /// Last time this heartbeat update was invoked /// public int LastTick { get; set; } @@ -77,6 +77,11 @@ namespace OpenSim.Framework /// public bool AlarmIfTimeout { get; set; } + /// + /// Method execute if alarm goes off. If null then no alarm method is fired. + /// + public Func AlarmMethod { get; set; } + public ThreadWatchdogInfo(Thread thread, int timeout) { Thread = thread; @@ -87,16 +92,10 @@ namespace OpenSim.Framework } /// - /// This event is called whenever a tracked thread is stopped or - /// has not called UpdateThread() in time - /// - /// The thread that has been identified as dead - /// The last time this thread called UpdateThread() - public delegate void WatchdogTimeout(Thread thread, int lastTick); - - /// This event is called whenever a tracked thread is - /// stopped or has not called UpdateThread() in time - public static event WatchdogTimeout OnWatchdogTimeout; + /// This event is called whenever a tracked thread is + /// stopped or has not called UpdateThread() in time< + /// /summary> + public static event Action OnWatchdogTimeout; private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private static Dictionary m_threads; @@ -123,7 +122,7 @@ namespace OpenSim.Framework public static Thread StartThread( ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout) { - return StartThread(start, name, priority, isBackground, alarmIfTimeout, WATCHDOG_TIMEOUT_MS); + return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, WATCHDOG_TIMEOUT_MS); } /// @@ -135,17 +134,24 @@ namespace OpenSim.Framework /// True to run this thread as a background /// thread, otherwise false /// Trigger an alarm function is we have timed out + /// + /// Alarm method to call if alarmIfTimeout is true and there is a timeout. + /// Normally, this will just return some useful debugging information. + /// /// Number of milliseconds to wait until we issue a warning about timeout. /// The newly created Thread object public static Thread StartThread( - ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, int timeout) + ThreadStart start, string name, ThreadPriority priority, bool isBackground, + bool alarmIfTimeout, Func alarmMethod, int timeout) { Thread thread = new Thread(start); thread.Name = name; thread.Priority = priority; thread.IsBackground = isBackground; - ThreadWatchdogInfo twi = new ThreadWatchdogInfo(thread, timeout) { AlarmIfTimeout = alarmIfTimeout }; + ThreadWatchdogInfo twi + = new ThreadWatchdogInfo(thread, timeout) + { AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod }; m_log.DebugFormat( "[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId); @@ -258,7 +264,7 @@ namespace OpenSim.Framework /// private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) { - WatchdogTimeout callback = OnWatchdogTimeout; + Action callback = OnWatchdogTimeout; if (callback != null) { @@ -296,7 +302,7 @@ namespace OpenSim.Framework if (callbackInfos != null) foreach (ThreadWatchdogInfo callbackInfo in callbackInfos) - callback(callbackInfo.Thread, callbackInfo.LastTick); + callback(callbackInfo); } m_watchdogTimer.Start(); diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 76ac827..caba236 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -438,12 +438,16 @@ namespace OpenSim } } - private void WatchdogTimeoutHandler(System.Threading.Thread thread, int lastTick) + private void WatchdogTimeoutHandler(Watchdog.ThreadWatchdogInfo twi) { int now = Environment.TickCount & Int32.MaxValue; - m_log.ErrorFormat("[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago", - thread.Name, thread.ThreadState, now - lastTick); + m_log.ErrorFormat( + "[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago. {3}", + twi.Thread.Name, + twi.Thread.ThreadState, + now - twi.LastTick, + twi.AlarmMethod != null ? string.Format("Data: {0}", twi.AlarmMethod()) : ""); } #region Console Commands diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 32ba590..e37adb8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -163,6 +163,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_malformedCount = 0; // Guard against a spamming attack + /// + /// Record current outgoing client for monitoring purposes. + /// + private IClientAPI m_currentOutgoingClient; + + /// + /// Recording current incoming client for monitoring purposes. + /// + private IClientAPI m_currentIncomingClient; + public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) : base(listenIP, (int)port) { @@ -244,19 +254,56 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (m_scene == null) throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference"); - m_log.Info("[LLUDPSERVER]: Starting the LLUDP server in " + (m_asyncPacketHandling ? "asynchronous" : "synchronous") + " mode"); + m_log.InfoFormat( + "[LLUDPSERVER]: Starting the LLUDP server in {0} mode", + m_asyncPacketHandling ? "asynchronous" : "synchronous"); base.Start(m_recvBufferSize, m_asyncPacketHandling); // Start the packet processing threads Watchdog.StartThread( - IncomingPacketHandler, "Incoming Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false, true); + IncomingPacketHandler, + string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName), + ThreadPriority.Normal, + false, + true, + GetWatchdogIncomingAlarmData, + Watchdog.WATCHDOG_TIMEOUT_MS); + Watchdog.StartThread( - OutgoingPacketHandler, "Outgoing Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false, true); + OutgoingPacketHandler, + string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName), + ThreadPriority.Normal, + false, + true, + GetWatchdogOutgoingAlarmData, + Watchdog.WATCHDOG_TIMEOUT_MS); m_elapsedMSSinceLastStatReport = Environment.TickCount; } + /// + /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. + /// + /// + private string GetWatchdogIncomingAlarmData() + { + return string.Format( + "Client is {0}", + m_currentIncomingClient != null ? m_currentIncomingClient.Name : "none"); + } + + /// + /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. + /// + /// + private string GetWatchdogOutgoingAlarmData() + { + return string.Format( + "Client is {0}", + m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none"); + } + public new void Stop() { m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName); @@ -1173,6 +1220,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP // client. m_packetSent will be set to true if a packet is sent m_scene.ForEachClient(clientPacketHandler); + m_currentOutgoingClient = null; + // If nothing was sent, sleep for the minimum amount of time before a // token bucket could get more tokens if (!m_packetSent) @@ -1191,6 +1240,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP private void ClientOutgoingPacketHandler(IClientAPI client) { + m_currentOutgoingClient = client; + try { if (client is LLClientView) @@ -1216,8 +1267,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP } catch (Exception ex) { - m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name + - " threw an exception: " + ex.Message, ex); + m_log.Error( + string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex); } } @@ -1243,6 +1294,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP { nticks++; watch1.Start(); + m_currentOutgoingClient = client; + try { if (client is LLClientView) @@ -1344,6 +1397,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Make sure this client is still alive if (m_scene.TryGetClient(udpClient.AgentID, out client)) { + m_currentIncomingClient = client; + try { // Process this packet @@ -1361,6 +1416,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_log.ErrorFormat("[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw an exception", udpClient.AgentID, packet.Type); m_log.Error(e.Message, e); } + finally + { + m_currentIncomingClient = null; + } } else { -- cgit v1.1 From 7550b97e65fa873b42624648747cec3e12a8e689 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 7 Jun 2012 04:00:29 +0100 Subject: Log warning if we try to remove a UDP client that has already been removed. --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index e37adb8..09bb52c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1114,6 +1114,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP client.IsLoggingOut = true; client.Close(); } + else + { + m_log.WarnFormat( + "[LLUDPSERVER]: Tried to remove client with id {0} but not such client in {1}", + udpClient.AgentID, m_scene.RegionInfo.RegionName); + } } private void IncomingPacketHandler() -- cgit v1.1 From a1e857932a2019c3e93e1b708486f37e9bb86b26 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Thu, 7 Jun 2012 10:15:40 -0400 Subject: Make change to fix Windows builds --- OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs index fc8daf3..3171759 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs @@ -107,7 +107,7 @@ namespace OpenSim.Framework.Servers.HttpServer public bool IsSecured { - get { return _context.Secured; } + get { return _context.IsSecured; } } public bool KeepAlive -- cgit v1.1 From d5cc9596838a9335e5e9ed0877d26b802ee6c8e3 Mon Sep 17 00:00:00 2001 From: Talun Date: Thu, 7 Jun 2012 16:00:00 +0100 Subject: Mantis 6044 Building master currently fails. Add missing reference to System.Core Signed-off-by: BlueWall --- prebuild.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/prebuild.xml b/prebuild.xml index 5003ae7..d02f2b9 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -126,6 +126,7 @@ ../../../../bin/ + -- cgit v1.1 From 39cb2063bf7cd771514e4d69da1dab55a6a511a2 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 7 Jun 2012 19:02:43 +0200 Subject: Add collision sounds to the asset set --- bin/assets/AssetSets.xml | 6 + .../CollisionSoundsAssetSet.xml | 341 +++++++++++++++++++++ bin/assets/CollisionSoundsAssetSet/attribution.txt | 8 + .../CollisionSoundsAssetSet/snd_FleshFlesh.ogg | Bin 0 -> 8829 bytes .../CollisionSoundsAssetSet/snd_FleshGlass.ogg | Bin 0 -> 8537 bytes .../CollisionSoundsAssetSet/snd_FleshMetal.ogg | Bin 0 -> 12830 bytes .../CollisionSoundsAssetSet/snd_FleshPlastic.ogg | Bin 0 -> 8858 bytes .../CollisionSoundsAssetSet/snd_FleshRubber.ogg | Bin 0 -> 10037 bytes .../CollisionSoundsAssetSet/snd_FleshStone.ogg | Bin 0 -> 10985 bytes .../CollisionSoundsAssetSet/snd_FleshWood.ogg | Bin 0 -> 8835 bytes .../CollisionSoundsAssetSet/snd_GlassFlesh.ogg | Bin 0 -> 8579 bytes .../CollisionSoundsAssetSet/snd_GlassGlass.ogg | Bin 0 -> 5456 bytes .../CollisionSoundsAssetSet/snd_GlassMetal.ogg | Bin 0 -> 13092 bytes .../CollisionSoundsAssetSet/snd_GlassPlastic.ogg | Bin 0 -> 6797 bytes .../CollisionSoundsAssetSet/snd_GlassRubber.ogg | Bin 0 -> 9760 bytes .../CollisionSoundsAssetSet/snd_GlassStone.ogg | Bin 0 -> 11185 bytes .../CollisionSoundsAssetSet/snd_GlassWood.ogg | Bin 0 -> 7048 bytes .../CollisionSoundsAssetSet/snd_MetalFlesh.ogg | Bin 0 -> 12917 bytes .../CollisionSoundsAssetSet/snd_MetalGlass.ogg | Bin 0 -> 13500 bytes .../CollisionSoundsAssetSet/snd_MetalMetal.ogg | Bin 0 -> 13513 bytes .../CollisionSoundsAssetSet/snd_MetalPlastic.ogg | Bin 0 -> 12814 bytes .../CollisionSoundsAssetSet/snd_MetalRubber.ogg | Bin 0 -> 13008 bytes .../CollisionSoundsAssetSet/snd_MetalStone.ogg | Bin 0 -> 13578 bytes .../CollisionSoundsAssetSet/snd_MetalWood.ogg | Bin 0 -> 13040 bytes .../CollisionSoundsAssetSet/snd_PlasticFlesh.ogg | Bin 0 -> 8510 bytes .../CollisionSoundsAssetSet/snd_PlasticGlass.ogg | Bin 0 -> 6797 bytes .../CollisionSoundsAssetSet/snd_PlasticMetal.ogg | Bin 0 -> 12814 bytes .../CollisionSoundsAssetSet/snd_PlasticPlastic.ogg | Bin 0 -> 6635 bytes .../CollisionSoundsAssetSet/snd_PlasticRubber.ogg | Bin 0 -> 9648 bytes .../CollisionSoundsAssetSet/snd_PlasticStone.ogg | Bin 0 -> 10640 bytes .../CollisionSoundsAssetSet/snd_PlasticWood.ogg | Bin 0 -> 6845 bytes .../CollisionSoundsAssetSet/snd_RubberFlesh.ogg | Bin 0 -> 9758 bytes .../CollisionSoundsAssetSet/snd_RubberGlass.ogg | Bin 0 -> 9871 bytes .../CollisionSoundsAssetSet/snd_RubberMetal.ogg | Bin 0 -> 12797 bytes .../CollisionSoundsAssetSet/snd_RubberPlastic.ogg | Bin 0 -> 9648 bytes .../CollisionSoundsAssetSet/snd_RubberRubber.ogg | Bin 0 -> 9647 bytes .../CollisionSoundsAssetSet/snd_RubberStone.ogg | Bin 0 -> 10850 bytes .../CollisionSoundsAssetSet/snd_RubberWood.ogg | Bin 0 -> 9716 bytes .../CollisionSoundsAssetSet/snd_StoneFlesh.ogg | Bin 0 -> 10896 bytes .../CollisionSoundsAssetSet/snd_StoneGlass.ogg | Bin 0 -> 11188 bytes .../CollisionSoundsAssetSet/snd_StoneMetal.ogg | Bin 0 -> 13517 bytes .../CollisionSoundsAssetSet/snd_StonePlastic.ogg | Bin 0 -> 11196 bytes .../CollisionSoundsAssetSet/snd_StoneRubber.ogg | Bin 0 -> 10885 bytes .../CollisionSoundsAssetSet/snd_StoneStone.ogg | Bin 0 -> 11040 bytes .../CollisionSoundsAssetSet/snd_StoneWood.ogg | Bin 0 -> 10947 bytes .../CollisionSoundsAssetSet/snd_TerrainFlesh.ogg | Bin 0 -> 8750 bytes .../CollisionSoundsAssetSet/snd_TerrainGlass.ogg | Bin 0 -> 8126 bytes .../CollisionSoundsAssetSet/snd_TerrainMetal.ogg | Bin 0 -> 12839 bytes .../CollisionSoundsAssetSet/snd_TerrainPlastic.ogg | Bin 0 -> 7920 bytes .../CollisionSoundsAssetSet/snd_TerrainRubber.ogg | Bin 0 -> 9480 bytes .../CollisionSoundsAssetSet/snd_TerrainStone.ogg | Bin 0 -> 10807 bytes .../CollisionSoundsAssetSet/snd_TerrainWood.ogg | Bin 0 -> 7999 bytes .../CollisionSoundsAssetSet/snd_WoodFlesh.ogg | Bin 0 -> 8827 bytes .../CollisionSoundsAssetSet/snd_WoodGlass.ogg | Bin 0 -> 7057 bytes .../CollisionSoundsAssetSet/snd_WoodMetal.ogg | Bin 0 -> 12818 bytes .../CollisionSoundsAssetSet/snd_WoodPlastic.ogg | Bin 0 -> 6990 bytes .../CollisionSoundsAssetSet/snd_WoodRubber.ogg | Bin 0 -> 9626 bytes .../CollisionSoundsAssetSet/snd_WoodStone.ogg | Bin 0 -> 10931 bytes .../CollisionSoundsAssetSet/snd_WoodWood.ogg | Bin 0 -> 6696 bytes 59 files changed, 355 insertions(+) create mode 100644 bin/assets/CollisionSoundsAssetSet/CollisionSoundsAssetSet.xml create mode 100644 bin/assets/CollisionSoundsAssetSet/attribution.txt create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_FleshFlesh.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_FleshGlass.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_FleshMetal.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_FleshPlastic.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_FleshRubber.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_FleshStone.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_FleshWood.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_GlassFlesh.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_GlassGlass.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_GlassMetal.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_GlassPlastic.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_GlassRubber.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_GlassStone.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_GlassWood.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_MetalFlesh.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_MetalGlass.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_MetalMetal.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_MetalPlastic.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_MetalRubber.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_MetalStone.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_MetalWood.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_PlasticFlesh.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_PlasticGlass.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_PlasticMetal.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_PlasticPlastic.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_PlasticRubber.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_PlasticStone.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_PlasticWood.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_RubberFlesh.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_RubberGlass.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_RubberMetal.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_RubberPlastic.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_RubberRubber.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_RubberStone.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_RubberWood.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_StoneFlesh.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_StoneGlass.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_StoneMetal.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_StonePlastic.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_StoneRubber.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_StoneStone.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_StoneWood.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_TerrainFlesh.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_TerrainGlass.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_TerrainMetal.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_TerrainPlastic.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_TerrainRubber.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_TerrainStone.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_TerrainWood.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_WoodFlesh.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_WoodGlass.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_WoodMetal.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_WoodPlastic.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_WoodRubber.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_WoodStone.ogg create mode 100644 bin/assets/CollisionSoundsAssetSet/snd_WoodWood.ogg diff --git a/bin/assets/AssetSets.xml b/bin/assets/AssetSets.xml index c13ea42..829f845 100644 --- a/bin/assets/AssetSets.xml +++ b/bin/assets/AssetSets.xml @@ -68,6 +68,12 @@ +
+ +
+ + +
diff --git a/bin/assets/CollisionSoundsAssetSet/CollisionSoundsAssetSet.xml b/bin/assets/CollisionSoundsAssetSet/CollisionSoundsAssetSet.xml new file mode 100644 index 0000000..7498ae0 --- /dev/null +++ b/bin/assets/CollisionSoundsAssetSet/CollisionSoundsAssetSet.xml @@ -0,0 +1,341 @@ + + + +
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
diff --git a/bin/assets/CollisionSoundsAssetSet/attribution.txt b/bin/assets/CollisionSoundsAssetSet/attribution.txt new file mode 100644 index 0000000..876419b --- /dev/null +++ b/bin/assets/CollisionSoundsAssetSet/attribution.txt @@ -0,0 +1,8 @@ +thanvannispen - http://www.freesound.org/people/thanvannispen/sounds/30012/ +hoobtastic - http://www.freesound.org/people/hoobtastic/sounds/132627/ +kbnevel - http://www.freesound.org/people/kbnevel/sounds/119859/ +adcbicycle - http://www.freesound.org/people/adcbicycle/sounds/13856/ +adcbicycle - http://www.freesound.org/people/adcbicycle/sounds/13855/ +110110010 - http://www.freesound.org/people/110110010/sounds/66397/ +qubodup - http://www.freesound.org/people/qubodup/sounds/50941/ +vibe_crc - http://www.freesound.org/people/vibe_crc/sounds/59317/ \ No newline at end of file diff --git a/bin/assets/CollisionSoundsAssetSet/snd_FleshFlesh.ogg b/bin/assets/CollisionSoundsAssetSet/snd_FleshFlesh.ogg new file mode 100644 index 0000000..5f3aeb7 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_FleshFlesh.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_FleshGlass.ogg b/bin/assets/CollisionSoundsAssetSet/snd_FleshGlass.ogg new file mode 100644 index 0000000..3a322c6 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_FleshGlass.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_FleshMetal.ogg b/bin/assets/CollisionSoundsAssetSet/snd_FleshMetal.ogg new file mode 100644 index 0000000..edcf17a Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_FleshMetal.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_FleshPlastic.ogg b/bin/assets/CollisionSoundsAssetSet/snd_FleshPlastic.ogg new file mode 100644 index 0000000..acf53e5 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_FleshPlastic.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_FleshRubber.ogg b/bin/assets/CollisionSoundsAssetSet/snd_FleshRubber.ogg new file mode 100644 index 0000000..6373610 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_FleshRubber.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_FleshStone.ogg b/bin/assets/CollisionSoundsAssetSet/snd_FleshStone.ogg new file mode 100644 index 0000000..eccbbb8 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_FleshStone.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_FleshWood.ogg b/bin/assets/CollisionSoundsAssetSet/snd_FleshWood.ogg new file mode 100644 index 0000000..6713380 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_FleshWood.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_GlassFlesh.ogg b/bin/assets/CollisionSoundsAssetSet/snd_GlassFlesh.ogg new file mode 100644 index 0000000..6951d44 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_GlassFlesh.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_GlassGlass.ogg b/bin/assets/CollisionSoundsAssetSet/snd_GlassGlass.ogg new file mode 100644 index 0000000..1806a55 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_GlassGlass.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_GlassMetal.ogg b/bin/assets/CollisionSoundsAssetSet/snd_GlassMetal.ogg new file mode 100644 index 0000000..f147024 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_GlassMetal.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_GlassPlastic.ogg b/bin/assets/CollisionSoundsAssetSet/snd_GlassPlastic.ogg new file mode 100644 index 0000000..204a4c6 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_GlassPlastic.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_GlassRubber.ogg b/bin/assets/CollisionSoundsAssetSet/snd_GlassRubber.ogg new file mode 100644 index 0000000..243f185 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_GlassRubber.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_GlassStone.ogg b/bin/assets/CollisionSoundsAssetSet/snd_GlassStone.ogg new file mode 100644 index 0000000..0852135 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_GlassStone.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_GlassWood.ogg b/bin/assets/CollisionSoundsAssetSet/snd_GlassWood.ogg new file mode 100644 index 0000000..2c13690 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_GlassWood.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_MetalFlesh.ogg b/bin/assets/CollisionSoundsAssetSet/snd_MetalFlesh.ogg new file mode 100644 index 0000000..c11d19f Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_MetalFlesh.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_MetalGlass.ogg b/bin/assets/CollisionSoundsAssetSet/snd_MetalGlass.ogg new file mode 100644 index 0000000..36348e1 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_MetalGlass.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_MetalMetal.ogg b/bin/assets/CollisionSoundsAssetSet/snd_MetalMetal.ogg new file mode 100644 index 0000000..957b3c2 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_MetalMetal.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_MetalPlastic.ogg b/bin/assets/CollisionSoundsAssetSet/snd_MetalPlastic.ogg new file mode 100644 index 0000000..5674907 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_MetalPlastic.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_MetalRubber.ogg b/bin/assets/CollisionSoundsAssetSet/snd_MetalRubber.ogg new file mode 100644 index 0000000..0f9ba2e Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_MetalRubber.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_MetalStone.ogg b/bin/assets/CollisionSoundsAssetSet/snd_MetalStone.ogg new file mode 100644 index 0000000..dc489d8 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_MetalStone.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_MetalWood.ogg b/bin/assets/CollisionSoundsAssetSet/snd_MetalWood.ogg new file mode 100644 index 0000000..de04317 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_MetalWood.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_PlasticFlesh.ogg b/bin/assets/CollisionSoundsAssetSet/snd_PlasticFlesh.ogg new file mode 100644 index 0000000..a9d6983 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_PlasticFlesh.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_PlasticGlass.ogg b/bin/assets/CollisionSoundsAssetSet/snd_PlasticGlass.ogg new file mode 100644 index 0000000..c7dcdf1 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_PlasticGlass.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_PlasticMetal.ogg b/bin/assets/CollisionSoundsAssetSet/snd_PlasticMetal.ogg new file mode 100644 index 0000000..4dd270f Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_PlasticMetal.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_PlasticPlastic.ogg b/bin/assets/CollisionSoundsAssetSet/snd_PlasticPlastic.ogg new file mode 100644 index 0000000..9994745 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_PlasticPlastic.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_PlasticRubber.ogg b/bin/assets/CollisionSoundsAssetSet/snd_PlasticRubber.ogg new file mode 100644 index 0000000..e5c408f Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_PlasticRubber.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_PlasticStone.ogg b/bin/assets/CollisionSoundsAssetSet/snd_PlasticStone.ogg new file mode 100644 index 0000000..9865c6e Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_PlasticStone.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_PlasticWood.ogg b/bin/assets/CollisionSoundsAssetSet/snd_PlasticWood.ogg new file mode 100644 index 0000000..9f921b9 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_PlasticWood.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_RubberFlesh.ogg b/bin/assets/CollisionSoundsAssetSet/snd_RubberFlesh.ogg new file mode 100644 index 0000000..b56f7dc Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_RubberFlesh.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_RubberGlass.ogg b/bin/assets/CollisionSoundsAssetSet/snd_RubberGlass.ogg new file mode 100644 index 0000000..9f44fca Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_RubberGlass.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_RubberMetal.ogg b/bin/assets/CollisionSoundsAssetSet/snd_RubberMetal.ogg new file mode 100644 index 0000000..9ff064a Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_RubberMetal.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_RubberPlastic.ogg b/bin/assets/CollisionSoundsAssetSet/snd_RubberPlastic.ogg new file mode 100644 index 0000000..8e601b1 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_RubberPlastic.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_RubberRubber.ogg b/bin/assets/CollisionSoundsAssetSet/snd_RubberRubber.ogg new file mode 100644 index 0000000..c84f8e5 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_RubberRubber.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_RubberStone.ogg b/bin/assets/CollisionSoundsAssetSet/snd_RubberStone.ogg new file mode 100644 index 0000000..d398f6f Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_RubberStone.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_RubberWood.ogg b/bin/assets/CollisionSoundsAssetSet/snd_RubberWood.ogg new file mode 100644 index 0000000..ebb24e3 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_RubberWood.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_StoneFlesh.ogg b/bin/assets/CollisionSoundsAssetSet/snd_StoneFlesh.ogg new file mode 100644 index 0000000..90275ad Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_StoneFlesh.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_StoneGlass.ogg b/bin/assets/CollisionSoundsAssetSet/snd_StoneGlass.ogg new file mode 100644 index 0000000..b2b33cf Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_StoneGlass.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_StoneMetal.ogg b/bin/assets/CollisionSoundsAssetSet/snd_StoneMetal.ogg new file mode 100644 index 0000000..accdfdf Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_StoneMetal.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_StonePlastic.ogg b/bin/assets/CollisionSoundsAssetSet/snd_StonePlastic.ogg new file mode 100644 index 0000000..15f93b6 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_StonePlastic.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_StoneRubber.ogg b/bin/assets/CollisionSoundsAssetSet/snd_StoneRubber.ogg new file mode 100644 index 0000000..4b756ff Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_StoneRubber.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_StoneStone.ogg b/bin/assets/CollisionSoundsAssetSet/snd_StoneStone.ogg new file mode 100644 index 0000000..88b8033 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_StoneStone.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_StoneWood.ogg b/bin/assets/CollisionSoundsAssetSet/snd_StoneWood.ogg new file mode 100644 index 0000000..4a5b7f3 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_StoneWood.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_TerrainFlesh.ogg b/bin/assets/CollisionSoundsAssetSet/snd_TerrainFlesh.ogg new file mode 100644 index 0000000..1d3038a Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_TerrainFlesh.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_TerrainGlass.ogg b/bin/assets/CollisionSoundsAssetSet/snd_TerrainGlass.ogg new file mode 100644 index 0000000..637fa16 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_TerrainGlass.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_TerrainMetal.ogg b/bin/assets/CollisionSoundsAssetSet/snd_TerrainMetal.ogg new file mode 100644 index 0000000..919c59b Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_TerrainMetal.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_TerrainPlastic.ogg b/bin/assets/CollisionSoundsAssetSet/snd_TerrainPlastic.ogg new file mode 100644 index 0000000..23fa329 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_TerrainPlastic.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_TerrainRubber.ogg b/bin/assets/CollisionSoundsAssetSet/snd_TerrainRubber.ogg new file mode 100644 index 0000000..c18d242 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_TerrainRubber.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_TerrainStone.ogg b/bin/assets/CollisionSoundsAssetSet/snd_TerrainStone.ogg new file mode 100644 index 0000000..6bd9e09 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_TerrainStone.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_TerrainWood.ogg b/bin/assets/CollisionSoundsAssetSet/snd_TerrainWood.ogg new file mode 100644 index 0000000..f405517 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_TerrainWood.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_WoodFlesh.ogg b/bin/assets/CollisionSoundsAssetSet/snd_WoodFlesh.ogg new file mode 100644 index 0000000..02621c2 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_WoodFlesh.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_WoodGlass.ogg b/bin/assets/CollisionSoundsAssetSet/snd_WoodGlass.ogg new file mode 100644 index 0000000..03b7fb5 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_WoodGlass.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_WoodMetal.ogg b/bin/assets/CollisionSoundsAssetSet/snd_WoodMetal.ogg new file mode 100644 index 0000000..e26afae Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_WoodMetal.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_WoodPlastic.ogg b/bin/assets/CollisionSoundsAssetSet/snd_WoodPlastic.ogg new file mode 100644 index 0000000..abe419b Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_WoodPlastic.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_WoodRubber.ogg b/bin/assets/CollisionSoundsAssetSet/snd_WoodRubber.ogg new file mode 100644 index 0000000..30ccc32 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_WoodRubber.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_WoodStone.ogg b/bin/assets/CollisionSoundsAssetSet/snd_WoodStone.ogg new file mode 100644 index 0000000..ad96818 Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_WoodStone.ogg differ diff --git a/bin/assets/CollisionSoundsAssetSet/snd_WoodWood.ogg b/bin/assets/CollisionSoundsAssetSet/snd_WoodWood.ogg new file mode 100644 index 0000000..76ae52c Binary files /dev/null and b/bin/assets/CollisionSoundsAssetSet/snd_WoodWood.ogg differ -- cgit v1.1 From de87e4871b6eb3852e8f7175f637adaf14a74ccf Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 7 Jun 2012 23:35:21 +0100 Subject: Don't send kill object messages to clients when a child agent is closed. --- OpenSim/Region/Framework/Scenes/Scene.cs | 39 +++++++++++++++++--------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index ae35cb9..f291022 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3274,26 +3274,29 @@ namespace OpenSim.Region.Framework.Scenes { m_eventManager.TriggerOnRemovePresence(agentID); - if (AttachmentsModule != null && !isChildAgent && avatar.PresenceType != PresenceType.Npc) + if (!isChildAgent) { - IUserManagement uMan = RequestModuleInterface(); - // Don't save attachments for HG visitors, it - // messes up their inventory. When a HG visitor logs - // out on a foreign grid, their attachments will be - // reloaded in the state they were in when they left - // the home grid. This is best anyway as the visited - // grid may use an incompatible script engine. - if (uMan == null || uMan.IsLocalGridUser(avatar.UUID)) - AttachmentsModule.SaveChangedAttachments(avatar, false); - } - - ForEachClient( - delegate(IClientAPI client) + if (AttachmentsModule != null && avatar.PresenceType != PresenceType.Npc) { - //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway - try { client.SendKillObject(avatar.RegionHandle, new List { avatar.LocalId }); } - catch (NullReferenceException) { } - }); + IUserManagement uMan = RequestModuleInterface(); + // Don't save attachments for HG visitors, it + // messes up their inventory. When a HG visitor logs + // out on a foreign grid, their attachments will be + // reloaded in the state they were in when they left + // the home grid. This is best anyway as the visited + // grid may use an incompatible script engine. + if (uMan == null || uMan.IsLocalGridUser(avatar.UUID)) + AttachmentsModule.SaveChangedAttachments(avatar, false); + } + + ForEachClient( + delegate(IClientAPI client) + { + //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway + try { client.SendKillObject(avatar.RegionHandle, new List { avatar.LocalId }); } + catch (NullReferenceException) { } + }); + } IAgentAssetTransactions agentTransactions = this.RequestModuleInterface(); if (agentTransactions != null) -- cgit v1.1 From 0c5fefacb415fb916ffece839c95c155ec718254 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 7 Jun 2012 23:51:04 +0100 Subject: Record the fact that child agents can have asset transactions. Also change code to grab the agent asset transaction module once. --- .../AssetTransaction/AssetTransactionModule.cs | 15 ++++++----- .../InventoryAccess/InventoryAccessModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 29 +++++++++------------- OpenSim/Region/Framework/Scenes/Scene.cs | 12 ++++----- 4 files changed, 26 insertions(+), 32 deletions(-) diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs index 874693e..7081989 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs @@ -42,8 +42,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction public class AssetTransactionModule : INonSharedRegionModule, IAgentAssetTransactions { -// private static readonly ILog m_log = LogManager.GetLogger( -// MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Scene m_Scene; private bool m_dumpAssetsToFile = false; @@ -209,15 +208,15 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction /// and comes through this method. ///
/// + /// /// /// - public void HandleTaskItemUpdateFromTransaction(IClientAPI remoteClient, - SceneObjectPart part, UUID transactionID, - TaskInventoryItem item) + public void HandleTaskItemUpdateFromTransaction( + IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item) { -// m_log.DebugFormat( -// "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0}", -// item.Name); + m_log.DebugFormat( + "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}", + item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName); AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 69767c1..7d51eed 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -216,7 +216,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } else { - IAgentAssetTransactions agentTransactions = m_Scene.RequestModuleInterface(); + IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule; if (agentTransactions != null) { agentTransactions.HandleItemCreationFromTransaction( diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 79c9309..b59fd05 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -440,10 +440,9 @@ namespace OpenSim.Region.Framework.Scenes } else { - IAgentAssetTransactions agentTransactions = this.RequestModuleInterface(); - if (agentTransactions != null) + if (AgentTransactionsModule != null) { - agentTransactions.HandleItemUpdateFromTransaction(remoteClient, transactionID, item); + AgentTransactionsModule.HandleItemUpdateFromTransaction(remoteClient, transactionID, item); } } } @@ -1532,21 +1531,17 @@ namespace OpenSim.Region.Framework.Scenes // Only look for an uploaded updated asset if we are passed a transaction ID. This is only the // case for updates uploded through UDP. Updates uploaded via a capability (e.g. a script update) // will not pass in a transaction ID in the update message. - if (transactionID != UUID.Zero) + if (transactionID != UUID.Zero && AgentTransactionsModule != null) { - IAgentAssetTransactions agentTransactions = this.RequestModuleInterface(); - if (agentTransactions != null) - { - agentTransactions.HandleTaskItemUpdateFromTransaction( - remoteClient, part, transactionID, currentItem); - - if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) - remoteClient.SendAgentAlertMessage("Notecard saved", false); - else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) - remoteClient.SendAgentAlertMessage("Script saved", false); - else - remoteClient.SendAgentAlertMessage("Item saved", false); - } + AgentTransactionsModule.HandleTaskItemUpdateFromTransaction( + remoteClient, part, transactionID, currentItem); + + if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) + remoteClient.SendAgentAlertMessage("Notecard saved", false); + else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) + remoteClient.SendAgentAlertMessage("Script saved", false); + else + remoteClient.SendAgentAlertMessage("Item saved", false); } // Base ALWAYS has move diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f291022..939c8fa 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -499,6 +499,7 @@ namespace OpenSim.Region.Framework.Scenes public IAttachmentsModule AttachmentsModule { get; set; } public IEntityTransferModule EntityTransferModule { get; private set; } + public IAgentAssetTransactions AgentTransactionsModule { get; private set; } public IAvatarFactoryModule AvatarFactory { @@ -1241,6 +1242,7 @@ namespace OpenSim.Region.Framework.Scenes m_capsModule = RequestModuleInterface(); EntityTransferModule = RequestModuleInterface(); m_groupsModule = RequestModuleInterface(); + AgentTransactionsModule = RequestModuleInterface(); } #endregion @@ -3297,12 +3299,10 @@ namespace OpenSim.Region.Framework.Scenes catch (NullReferenceException) { } }); } - - IAgentAssetTransactions agentTransactions = this.RequestModuleInterface(); - if (agentTransactions != null) - { - agentTransactions.RemoveAgentAssetTransactions(agentID); - } + + // It's possible for child agents to have transactions if changes are being made cross-border. + if (AgentTransactionsModule != null) + AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); } finally { -- cgit v1.1 From b56673c920603022fce9cb479b714f6fbd0f1311 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Jun 2012 00:18:25 +0100 Subject: Fix bug with "kick user" reducing agent counts by 2 instead of 1. This is done by making the kick user command call IClientAPI.Close() rather than routing through Scene.IncomingCloseAgent(), which also called IClientAPI.Close() DisableSimulator for child agents is moved from IncomingCloseAgent() to RemoveClient(), this is not a functional change since IncomingCloseAgent() always ends up calling RemoveClient() --- OpenSim/Region/Application/OpenSim.cs | 4 +-- OpenSim/Region/Framework/Scenes/Scene.cs | 31 ++++++++++++---------- .../Framework/Scenes/SceneCommunicationService.cs | 11 ++++---- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index caba236..1d00522 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -486,10 +486,10 @@ namespace OpenSim else presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n"); - // ...and close on our side - presence.Scene.IncomingCloseAgent(presence.UUID); + presence.ControllingClient.Close(); } } + MainConsole.Instance.Output(""); } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 939c8fa..17503b1 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -940,7 +940,7 @@ namespace OpenSim.Region.Framework.Scenes else { m_log.InfoFormat( - "[INTERGRID]: Got notice about far away Region: {0} at ({1}, {2})", + "[SCENE]: Got notice about far away Region: {0} at ({1}, {2})", otherRegion.RegionName, otherRegion.RegionLocX, otherRegion.RegionLocY); } } @@ -3235,6 +3235,22 @@ namespace OpenSim.Region.Framework.Scenes { isChildAgent = avatar.IsChildAgent; + // Don't do this to root agents, it's not nice for the viewer + if (closeChildAgents && isChildAgent) + { + // Tell a single agent to disconnect from the region. + IEventQueue eq = RequestModuleInterface(); + if (eq != null) + { + eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID); + } + else + { + avatar.ControllingClient.SendShutdownConnectionNotice(); + } + } + + // Only applies to root agents. if (avatar.ParentID != 0) { avatar.StandUp(); @@ -4033,19 +4049,6 @@ namespace OpenSim.Region.Framework.Scenes m_sceneGraph.removeUserCount(true); } - // Don't do this to root agents on logout, it's not nice for the viewer - if (presence.IsChildAgent) - { - // Tell a single agent to disconnect from the region. - IEventQueue eq = RequestModuleInterface(); - if (eq != null) - { - eq.DisableSimulator(RegionInfo.RegionHandle, agentID); - } - else - presence.ControllingClient.SendShutdownConnectionNotice(); - } - presence.ControllingClient.Close(); return true; } diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index b8616e8..eff635b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -84,16 +84,16 @@ namespace OpenSim.Region.Framework.Scenes if (neighbourService != null) neighbour = neighbourService.HelloNeighbour(regionhandle, region); else - m_log.DebugFormat("[SCS]: No neighbour service provided for informing neigbhours of this region"); + m_log.DebugFormat("[SCENE COMMUNICATION SERVICE]: No neighbour service provided for informing neigbhours of this region"); if (neighbour != null) { - m_log.DebugFormat("[INTERGRID]: Successfully informed neighbour {0}-{1} that I'm here", x / Constants.RegionSize, y / Constants.RegionSize); + m_log.DebugFormat("[SCENE COMMUNICATION SERVICE]: Successfully informed neighbour {0}-{1} that I'm here", x / Constants.RegionSize, y / Constants.RegionSize); m_scene.EventManager.TriggerOnRegionUp(neighbour); } else { - m_log.InfoFormat("[INTERGRID]: Failed to inform neighbour {0}-{1} that I'm here.", x / Constants.RegionSize, y / Constants.RegionSize); + m_log.InfoFormat("[SCENE COMMUNICATION SERVICE]: Failed to inform neighbour {0}-{1} that I'm here.", x / Constants.RegionSize, y / Constants.RegionSize); } } @@ -102,7 +102,7 @@ namespace OpenSim.Region.Framework.Scenes //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName); List neighbours = m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID); - m_log.DebugFormat("[INTERGRID]: Informing {0} neighbours that this region is up", neighbours.Count); + m_log.DebugFormat("[SCENE COMMUNICATION SERVICE]: Informing {0} neighbours that this region is up", neighbours.Count); foreach (GridRegion n in neighbours) { InformNeighbourThatRegionUpDelegate d = InformNeighboursThatRegionIsUpAsync; @@ -196,8 +196,7 @@ namespace OpenSim.Region.Framework.Scenes GridRegion destination = m_scene.GridService.GetRegionByPosition(m_regionInfo.ScopeID, (int)x, (int)y); m_log.DebugFormat( - "[INTERGRID]: Sending close agent {0} to region at {1}-{2}", - agentID, destination.RegionCoordX, destination.RegionCoordY); + "[SCENE COMMUNICATION SERVICE]: Sending close agent ID {0} to {1}", agentID, destination.RegionName); m_scene.SimulationService.CloseAgent(destination, agentID); } -- cgit v1.1 From d547bcf8d15bdcb8604cf170dc8ec1e14ad4cdc0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Jun 2012 00:40:38 +0100 Subject: Remove duplicate update of user count in Scene.IncomingCloseAgent() This is already done in Scene.RemoveClient() which IncomingCloseAgent() always ends up calling. --- OpenSim/Region/Framework/Scenes/Scene.cs | 10 ---------- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 8 ++++---- .../Scenes/Tests/ScenePresenceTeleportTests.cs | 23 ++++++++++++++++++++++ 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 17503b1..9048f00 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4039,16 +4039,6 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); if (presence != null) { - // Nothing is removed here, so down count it as such - if (presence.IsChildAgent) - { - m_sceneGraph.removeUserCount(false); - } - else - { - m_sceneGraph.removeUserCount(true); - } - presence.ControllingClient.Close(); return true; } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index ddf1550..82a4f64 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -703,10 +703,10 @@ namespace OpenSim.Region.Framework.Scenes public int GetChildAgentCount() { // some network situations come in where child agents get closed twice. - if (m_numChildAgents < 0) - { - m_numChildAgents = 0; - } +// if (m_numChildAgents < 0) +// { +// m_numChildAgents = 0; +// } return m_numChildAgents; } diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index ccfe4ff..a407f01 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -97,6 +97,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(sp.AbsolutePosition, Is.EqualTo(teleportPosition)); + Assert.That(scene.GetRootAgentCount(), Is.EqualTo(1)); + Assert.That(scene.GetChildAgentCount(), Is.EqualTo(0)); + // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera // position instead). // Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); @@ -158,6 +161,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(sceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName)); Assert.That(sceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition)); + Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(0)); + Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0)); + Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(1)); + Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0)); + // TODO: Add assertions to check correct circuit details in both scenes. // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera @@ -235,6 +243,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(sceneASp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneA.RegionInfo.RegionName)); Assert.That(sceneASp.AbsolutePosition, Is.EqualTo(preTeleportPosition)); + Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(1)); + Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0)); + Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(0)); + Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0)); + // TODO: Add assertions to check correct circuit details in both scenes. // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera @@ -306,6 +319,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(sceneASp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneA.RegionInfo.RegionName)); Assert.That(sceneASp.AbsolutePosition, Is.EqualTo(preTeleportPosition)); + Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(1)); + Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0)); + Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(0)); + Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0)); + // TODO: Add assertions to check correct circuit details in both scenes. // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera @@ -382,6 +400,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(afterSceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName)); Assert.That(afterSceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition)); + Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(0)); + Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(1)); + Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(1)); + Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0)); + // TODO: Add assertions to check correct circuit details in both scenes. // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera -- cgit v1.1 From 5c162ccd57639f0c711d9940ecdd3e2804d26304 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Jun 2012 00:59:39 +0100 Subject: Go back to calling IncomingCloseAgent() in the "kick user" command for consistency instead of IClientAPI.Close() directly. This no longer double counts child agent removals --- OpenSim/Region/Application/OpenSim.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 1d00522..9c38ebe 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -486,7 +486,7 @@ namespace OpenSim else presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n"); - presence.ControllingClient.Close(); + presence.Scene.IncomingCloseAgent(presence.UUID); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 82a4f64..a59758f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -702,12 +702,6 @@ namespace OpenSim.Region.Framework.Scenes public int GetChildAgentCount() { - // some network situations come in where child agents get closed twice. -// if (m_numChildAgents < 0) -// { -// m_numChildAgents = 0; -// } - return m_numChildAgents; } -- cgit v1.1 From 30f4a33f01751d151ae3923b48e6e98083791140 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Jun 2012 01:24:44 +0100 Subject: Don't make duplicate call to ScenePresence.Close() separately in ETM.DoTeleport() if an agent needs closing. This is always done as part of Scene.RemoveClient() Also refactors try/catching in Scene.RemoveClient() to log NREs instead of silently discarding, since these are useful symptoms of problems. --- .../EntityTransfer/EntityTransferModule.cs | 1 - OpenSim/Region/Framework/Scenes/Scene.cs | 149 ++++++++++----------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- .../Scenes/Tests/ScenePresenceAgentTests.cs | 4 +- 4 files changed, 74 insertions(+), 82 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index f2926ea..7d82060 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -644,7 +644,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // an agent cannot teleport back to this region if it has teleported away. Thread.Sleep(2000); - sp.Close(); sp.Scene.IncomingCloseAgent(sp.UUID); } else diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 9048f00..7afde38 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3231,10 +3231,23 @@ namespace OpenSim.Region.Framework.Scenes // CheckHeartbeat(); bool isChildAgent = false; ScenePresence avatar = GetScenePresence(agentID); - if (avatar != null) + + if (avatar == null) + { + m_log.WarnFormat( + "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID); + + return; + } + + try { isChildAgent = avatar.IsChildAgent; + m_log.DebugFormat( + "[SCENE]: Removing {0} agent {1} {2} from {3}", + (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName); + // Don't do this to root agents, it's not nice for the viewer if (closeChildAgents && isChildAgent) { @@ -3256,99 +3269,77 @@ namespace OpenSim.Region.Framework.Scenes avatar.StandUp(); } - try - { - m_log.DebugFormat( - "[SCENE]: Removing {0} agent {1} {2} from region {3}", - (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName); - - m_sceneGraph.removeUserCount(!isChildAgent); - - // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop - // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI - if (closeChildAgents && CapsModule != null) - CapsModule.RemoveCaps(agentID); + m_sceneGraph.removeUserCount(!isChildAgent); - // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever - // this method is doing is HORRIBLE!!! - avatar.Scene.NeedSceneCacheClear(avatar.UUID); + // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop + // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI + if (closeChildAgents && CapsModule != null) + CapsModule.RemoveCaps(agentID); - if (closeChildAgents && !avatar.IsChildAgent) - { - List regions = avatar.KnownRegionHandles; - regions.Remove(RegionInfo.RegionHandle); - m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); - } + // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever + // this method is doing is HORRIBLE!!! + avatar.Scene.NeedSceneCacheClear(avatar.UUID); - m_eventManager.TriggerClientClosed(agentID, this); - } - catch (NullReferenceException) + if (closeChildAgents && !isChildAgent) { - // We don't know which count to remove it from - // Avatar is already disposed :/ + List regions = avatar.KnownRegionHandles; + regions.Remove(RegionInfo.RegionHandle); + m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); } - try + m_eventManager.TriggerClientClosed(agentID, this); + m_eventManager.TriggerOnRemovePresence(agentID); + + if (!isChildAgent) { - m_eventManager.TriggerOnRemovePresence(agentID); - - if (!isChildAgent) + if (AttachmentsModule != null && avatar.PresenceType != PresenceType.Npc) { - if (AttachmentsModule != null && avatar.PresenceType != PresenceType.Npc) - { - IUserManagement uMan = RequestModuleInterface(); - // Don't save attachments for HG visitors, it - // messes up their inventory. When a HG visitor logs - // out on a foreign grid, their attachments will be - // reloaded in the state they were in when they left - // the home grid. This is best anyway as the visited - // grid may use an incompatible script engine. - if (uMan == null || uMan.IsLocalGridUser(avatar.UUID)) - AttachmentsModule.SaveChangedAttachments(avatar, false); - } - - ForEachClient( - delegate(IClientAPI client) - { - //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway - try { client.SendKillObject(avatar.RegionHandle, new List { avatar.LocalId }); } - catch (NullReferenceException) { } - }); + IUserManagement uMan = RequestModuleInterface(); + // Don't save attachments for HG visitors, it + // messes up their inventory. When a HG visitor logs + // out on a foreign grid, their attachments will be + // reloaded in the state they were in when they left + // the home grid. This is best anyway as the visited + // grid may use an incompatible script engine. + if (uMan == null || uMan.IsLocalGridUser(avatar.UUID)) + AttachmentsModule.SaveChangedAttachments(avatar, false); } - // It's possible for child agents to have transactions if changes are being made cross-border. - if (AgentTransactionsModule != null) - AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); - } - finally - { - // Always clean these structures up so that any failure above doesn't cause them to remain in the - // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering - // the same cleanup exception continually. - // TODO: This should probably extend to the whole method, but we don't want to also catch the NRE - // since this would hide the underlying failure and other associated problems. - m_sceneGraph.RemoveScenePresence(agentID); - m_clientManager.Remove(agentID); + ForEachClient( + delegate(IClientAPI client) + { + //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway + try { client.SendKillObject(avatar.RegionHandle, new List { avatar.LocalId }); } + catch (NullReferenceException) { } + }); } - try - { - avatar.Close(); - } - catch (NullReferenceException) - { - //We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway. - } - catch (Exception e) - { - m_log.ErrorFormat("[SCENE] Scene.cs:RemoveClient exception {0}{1}", e.Message, e.StackTrace); - } + // It's possible for child agents to have transactions if changes are being made cross-border. + if (AgentTransactionsModule != null) + AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); + + avatar.Close(); m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); -// CleanDroppedAttachments(); - //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); - //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); } + catch (Exception e) + { + m_log.Error( + string.Format("[SCENE]: Exception removing {0} from {1}, ", avatar.Name, RegionInfo.RegionName), e); + } + finally + { + // Always clean these structures up so that any failure above doesn't cause them to remain in the + // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering + // the same cleanup exception continually. + // TODO: This should probably extend to the whole method, but we don't want to also catch the NRE + // since this would hide the underlying failure and other associated problems. + m_sceneGraph.RemoveScenePresence(agentID); + m_clientManager.Remove(agentID); + } + + //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); + //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); } /// diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 3adafc1..029e0d7 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3416,7 +3416,7 @@ namespace OpenSim.Region.Framework.Scenes public void Close() { - if (!IsChildAgent) + if (!IsChildAgent && m_scene.AttachmentsModule != null) m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false); // Clear known regions diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index 1aa48d7..02c45ef 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs @@ -101,7 +101,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests public void TestCloseAgent() { TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); +// TestHelpers.EnableLogging(); TestScene scene = new SceneHelpers().SetupScene(); ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); @@ -114,6 +114,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(scene.GetScenePresence(sp.UUID), Is.Null); Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null); Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(0)); + +// TestHelpers.DisableLogging(); } [Test] -- cgit v1.1 From d71c6dea7e5bfe827a9d723d972a9eec4cb77826 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Jun 2012 01:43:58 +0100 Subject: Store already retrieve IClientAPI in IncomingPacket structure for later use rather than doing another retrieve on dequeue. Instead of checking whether the client still exists by trying to retrieve again from the client manager, this patch gets it back from IncomingPacket and checks the IClientAPI.IsActive state. --- .../ClientStack/Linden/UDP/IncomingPacket.cs | 5 +++-- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 26 +++++++++++----------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs index 90b3ede..1b8535c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs @@ -39,7 +39,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public sealed class IncomingPacket { /// Client this packet came from - public LLUDPClient Client; + public LLClientView Client; + /// Packet data that has been received public Packet Packet; @@ -48,7 +49,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// /// Reference to the client this packet came from /// Packet data - public IncomingPacket(LLUDPClient client, Packet packet) + public IncomingPacket(LLClientView client, Packet packet) { Client = client; Packet = packet; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 09bb52c..55bda63 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -879,7 +879,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion Ping Check Handling // Inbox insertion - packetInbox.Enqueue(new IncomingPacket(udpClient, packet)); + packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet)); } #region BinaryStats @@ -1386,22 +1386,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion - private void ProcessInPacket(object state) + private void ProcessInPacket(IncomingPacket incomingPacket) { - IncomingPacket incomingPacket = (IncomingPacket)state; Packet packet = incomingPacket.Packet; - LLUDPClient udpClient = incomingPacket.Client; - IClientAPI client; + LLClientView client = incomingPacket.Client; // Sanity check - if (packet == null || udpClient == null) + if (packet == null || client == null) { - m_log.WarnFormat("[LLUDPSERVER]: Processing a packet with incomplete state. Packet=\"{0}\", UDPClient=\"{1}\"", - packet, udpClient); + m_log.WarnFormat("[LLUDPSERVER]: Processing a packet with incomplete state. Packet=\"{0}\", Client=\"{1}\"", + packet, client); } - // Make sure this client is still alive - if (m_scene.TryGetClient(udpClient.AgentID, out client)) + if (client.IsActive) { m_currentIncomingClient = client; @@ -1419,8 +1416,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP catch (Exception e) { // Don't let a failure in an individual client thread crash the whole sim. - m_log.ErrorFormat("[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw an exception", udpClient.AgentID, packet.Type); - m_log.Error(e.Message, e); + m_log.Error( + string.Format( + "[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw ", + client.Name, packet.Type), + e); } finally { @@ -1431,7 +1431,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { m_log.DebugFormat( "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", - packet.Type, udpClient.AgentID, m_scene.RegionInfo.RegionName); + packet.Type, client.Name, m_scene.RegionInfo.RegionName); } } -- cgit v1.1 From d73805d7f488e45a00a2d25c08876d400083d27f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Jun 2012 01:51:28 +0100 Subject: Remove null checks at top of LLUDPServer.ProcessInPacket(). Neither packet nor client are ever null. --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 55bda63..a292a6c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1391,13 +1391,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP Packet packet = incomingPacket.Packet; LLClientView client = incomingPacket.Client; - // Sanity check - if (packet == null || client == null) - { - m_log.WarnFormat("[LLUDPSERVER]: Processing a packet with incomplete state. Packet=\"{0}\", Client=\"{1}\"", - packet, client); - } - if (client.IsActive) { m_currentIncomingClient = client; @@ -1442,4 +1435,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP RemoveClient(((LLClientView)client).UDPClient); } } -} +} \ No newline at end of file -- cgit v1.1 From 5f4f9f02309b7df4d1bdcc560cee96d266c48a07 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Jun 2012 03:12:23 +0100 Subject: Add regression test for client logout due to ack timeout. --- OpenSim/Framework/Statistics/StatsManager.cs | 17 +- OpenSim/Region/Application/OpenSimBase.cs | 2 - .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 10 +- .../Linden/UDP/Tests/BasicCircuitTests.cs | 175 +++++++++++---------- .../Linden/UDP/Tests/TestLLUDPServer.cs | 9 ++ 5 files changed, 105 insertions(+), 108 deletions(-) diff --git a/OpenSim/Framework/Statistics/StatsManager.cs b/OpenSim/Framework/Statistics/StatsManager.cs index 43159ef..436ce2f 100644 --- a/OpenSim/Framework/Statistics/StatsManager.cs +++ b/OpenSim/Framework/Statistics/StatsManager.cs @@ -34,14 +34,12 @@ namespace OpenSim.Framework.Statistics { private static AssetStatsCollector assetStats; private static UserStatsCollector userStats; - private static SimExtraStatsCollector simExtraStats; + private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector(); public static AssetStatsCollector AssetStats { get { return assetStats; } } public static UserStatsCollector UserStats { get { return userStats; } } public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } } - private StatsManager() {} - /// /// Start collecting statistics related to assets. /// Should only be called once. @@ -63,16 +61,5 @@ namespace OpenSim.Framework.Statistics return userStats; } - - /// - /// Start collecting extra sim statistics apart from those collected for the client. - /// Should only be called once. - /// - public static SimExtraStatsCollector StartCollectingSimExtraStats() - { - simExtraStats = new SimExtraStatsCollector(); - - return simExtraStats; - } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 045e8d2..9a0fa70 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -223,8 +223,6 @@ namespace OpenSim base.StartupSpecific(); - m_stats = StatsManager.StartCollectingSimExtraStats(); - // Create a ModuleLoader instance m_moduleLoader = new ModuleLoader(m_config.Source); diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index a292a6c..58a3b1c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -147,11 +147,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_elapsed500MSOutgoingPacketHandler; /// Flag to signal when clients should check for resends - private bool m_resendUnacked; + protected bool m_resendUnacked; + /// Flag to signal when clients should send ACKs - private bool m_sendAcks; + protected bool m_sendAcks; + /// Flag to signal when clients should send pings - private bool m_sendPing; + protected bool m_sendPing; private int m_defaultRTO = 0; private int m_maxRTO = 0; @@ -1244,7 +1246,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Watchdog.RemoveThread(); } - private void ClientOutgoingPacketHandler(IClientAPI client) + protected void ClientOutgoingPacketHandler(IClientAPI client) { m_currentOutgoingClient = client; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs index 1321470..45d0e2a 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs @@ -45,6 +45,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests [TestFixture] public class BasicCircuitTests { + private Scene m_scene; + private TestLLUDPServer m_udpServer; + [TestFixtureSetUp] public void FixtureInit() { @@ -61,83 +64,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; } -// /// -// /// Add a client for testing -// /// -// /// -// /// -// /// -// /// Agent circuit manager used in setting up the stack -// protected void SetupStack( -// IScene scene, out TestLLUDPServer testLLUDPServer, out TestLLPacketServer testPacketServer, -// out AgentCircuitManager acm) -// { -// IConfigSource configSource = new IniConfigSource(); -// ClientStackUserSettings userSettings = new ClientStackUserSettings(); -// testLLUDPServer = new TestLLUDPServer(); -// acm = new AgentCircuitManager(); -// -// uint port = 666; -// testLLUDPServer.Initialise(null, ref port, 0, false, configSource, acm); -// testPacketServer = new TestLLPacketServer(testLLUDPServer, userSettings); -// testLLUDPServer.LocalScene = scene; -// } - -// /// -// /// Set up a client for tests which aren't concerned with this process itself and where only one client is being -// /// tested -// /// -// /// -// /// -// /// -// /// -// protected void AddClient( -// uint circuitCode, EndPoint epSender, TestLLUDPServer testLLUDPServer, AgentCircuitManager acm) -// { -// UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001"); -// UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002"); -// -// AddClient(circuitCode, epSender, myAgentUuid, mySessionUuid, testLLUDPServer, acm); -// } - -// /// -// /// Set up a client for tests which aren't concerned with this process itself -// /// -// /// -// /// -// /// -// /// -// /// -// /// -// protected void AddClient( -// uint circuitCode, EndPoint epSender, UUID agentId, UUID sessionId, -// TestLLUDPServer testLLUDPServer, AgentCircuitManager acm) -// { -// AgentCircuitData acd = new AgentCircuitData(); -// acd.AgentID = agentId; -// acd.SessionID = sessionId; -// -// UseCircuitCodePacket uccp = new UseCircuitCodePacket(); -// -// UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock -// = new UseCircuitCodePacket.CircuitCodeBlock(); -// uccpCcBlock.Code = circuitCode; -// uccpCcBlock.ID = agentId; -// uccpCcBlock.SessionID = sessionId; -// uccp.CircuitCode = uccpCcBlock; -// -// acm.AddNewCircuit(circuitCode, acd); -// -// testLLUDPServer.LoadReceive(uccp, epSender); -// testLLUDPServer.ReceiveData(null); -// } + [SetUp] + public void SetUp() + { + m_scene = new SceneHelpers().SetupScene(); + } /// /// Build an object name packet for test purposes /// /// /// - protected ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName) + private ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName) { ObjectNamePacket onp = new ObjectNamePacket(); ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock(); @@ -148,6 +86,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests return onp; } + + private void AddUdpServer() + { + AddUdpServer(new IniConfigSource()); + } + + private void AddUdpServer(IniConfigSource configSource) + { + uint port = 0; + AgentCircuitManager acm = m_scene.AuthenticateHandler; + + m_udpServer = new TestLLUDPServer(IPAddress.Any, ref port, 0, false, configSource, acm); + m_udpServer.AddScene(m_scene); + } + + /// + /// Used by tests that aren't testing this stage. + /// + private ScenePresence AddClient() + { + UUID myAgentUuid = TestHelpers.ParseTail(0x1); + UUID mySessionUuid = TestHelpers.ParseTail(0x2); + uint myCircuitCode = 123456; + IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999); + + UseCircuitCodePacket uccp = new UseCircuitCodePacket(); + + UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock + = new UseCircuitCodePacket.CircuitCodeBlock(); + uccpCcBlock.Code = myCircuitCode; + uccpCcBlock.ID = myAgentUuid; + uccpCcBlock.SessionID = mySessionUuid; + uccp.CircuitCode = uccpCcBlock; + + byte[] uccpBytes = uccp.ToBytes(); + UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length); + upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor. + Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length); + + AgentCircuitData acd = new AgentCircuitData(); + acd.AgentID = myAgentUuid; + acd.SessionID = mySessionUuid; + + m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd); + + m_udpServer.PacketReceived(upb); + + return m_scene.GetScenePresence(myAgentUuid); + } /// /// Test adding a client to the stack @@ -158,19 +145,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests TestHelpers.InMethod(); // XmlConfigurator.Configure(); - TestScene scene = new SceneHelpers().SetupScene(); - uint myCircuitCode = 123456; + AddUdpServer(); + UUID myAgentUuid = TestHelpers.ParseTail(0x1); UUID mySessionUuid = TestHelpers.ParseTail(0x2); + uint myCircuitCode = 123456; IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999); - uint port = 0; - AgentCircuitManager acm = scene.AuthenticateHandler; - - TestLLUDPServer llUdpServer - = new TestLLUDPServer(IPAddress.Any, ref port, 0, false, new IniConfigSource(), acm); - llUdpServer.AddScene(scene); - UseCircuitCodePacket uccp = new UseCircuitCodePacket(); UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock @@ -185,26 +166,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor. Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length); - llUdpServer.PacketReceived(upb); + m_udpServer.PacketReceived(upb); // Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet - Assert.That(scene.GetScenePresence(myAgentUuid), Is.Null); + Assert.That(m_scene.GetScenePresence(myAgentUuid), Is.Null); AgentCircuitData acd = new AgentCircuitData(); acd.AgentID = myAgentUuid; acd.SessionID = mySessionUuid; - acm.AddNewCircuit(myCircuitCode, acd); + m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd); - llUdpServer.PacketReceived(upb); + m_udpServer.PacketReceived(upb); // Should succeed now - ScenePresence sp = scene.GetScenePresence(myAgentUuid); + ScenePresence sp = m_scene.GetScenePresence(myAgentUuid); Assert.That(sp.UUID, Is.EqualTo(myAgentUuid)); - Assert.That(llUdpServer.PacketsSent.Count, Is.EqualTo(1)); + Assert.That(m_udpServer.PacketsSent.Count, Is.EqualTo(1)); - Packet packet = llUdpServer.PacketsSent[0]; + Packet packet = m_udpServer.PacketsSent[0]; Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket))); PacketAckPacket ackPacket = packet as PacketAckPacket; @@ -212,6 +193,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests Assert.That(ackPacket.Packets[0].ID, Is.EqualTo(0)); } + [Test] + public void TestLogoutClientDueToAck() + { + TestHelpers.InMethod(); + TestHelpers.EnableLogging(); + + IniConfigSource ics = new IniConfigSource(); + IConfig config = ics.AddConfig("ClientStack.LindenUDP"); + config.Set("AckTimeout", -1); + AddUdpServer(ics); + + ScenePresence sp = AddClient(); + m_udpServer.ClientOutgoingPacketHandler(sp.ControllingClient, true, false, false); + + ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID); + Assert.That(spAfterAckTimeout, Is.Null); + + TestHelpers.DisableLogging(); + } + // /// // /// Test removing a client from the stack // /// diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs index 0302385..27b9e5b 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs @@ -59,6 +59,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests PacketsSent.Add(packet); } + public void ClientOutgoingPacketHandler(IClientAPI client, bool resendUnacked, bool sendAcks, bool sendPing) + { + m_resendUnacked = resendUnacked; + m_sendAcks = sendAcks; + m_sendPing = sendPing; + + ClientOutgoingPacketHandler(client); + } + //// /// //// /// The chunks of data to pass to the LLUDPServer when it calls EndReceive //// /// -- cgit v1.1 From c215b1ad169cb8c3add70622f610e980ee9cfa31 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Jun 2012 03:53:03 +0100 Subject: If logging a client out due to ack timeout, do this asynchronously rather than synchronously on the outgoing packet loop. This is the same async behaviour as normal logouts. This is necessary because the event queue will sleep the thread for 5 seconds on an ack timeout logout as the client isn't around to pick up the final event queue messages. --- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 26 +++++++++++++++------- .../Linden/UDP/Tests/BasicCircuitTests.cs | 4 ++-- OpenSim/Tools/pCampBot/Bot.cs | 3 +++ 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 58a3b1c..e1fccb5 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -539,8 +539,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null); } - public void HandleUnacked(LLUDPClient udpClient) + public void HandleUnacked(LLClientView client) { + LLUDPClient udpClient = client.UDPClient; + if (!udpClient.IsConnected) return; @@ -553,12 +555,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (udpClient.IsPaused) timeoutTicks = m_pausedAckTimeout; - if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) + if (!client.IsLoggingOut && + (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) { m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); - RemoveClient(udpClient); + return; } @@ -1113,8 +1116,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP IClientAPI client; if (m_scene.TryGetClient(udpClient.AgentID, out client)) { + // We must set IsLoggingOut synchronously so that we can stop the packet loop reinvoking this method. client.IsLoggingOut = true; - client.Close(); + + // 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 => client.Close()); } else { @@ -1254,12 +1262,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (client is LLClientView) { - LLUDPClient udpClient = ((LLClientView)client).UDPClient; + LLClientView llClient = (LLClientView)client; + LLUDPClient udpClient = llClient.UDPClient; if (udpClient.IsConnected) { if (m_resendUnacked) - HandleUnacked(udpClient); + HandleUnacked(llClient); if (m_sendAcks) SendAcks(udpClient); @@ -1308,7 +1317,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (client is LLClientView) { - LLUDPClient udpClient = ((LLClientView)client).UDPClient; + LLClientView llClient = (LLClientView)client; + LLUDPClient udpClient = llClient.UDPClient; if (udpClient.IsConnected) { @@ -1317,7 +1327,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP nticksUnack++; watch2.Start(); - HandleUnacked(udpClient); + HandleUnacked(llClient); watch2.Stop(); avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack); diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs index 45d0e2a..109a8e1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs @@ -197,7 +197,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests public void TestLogoutClientDueToAck() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); IniConfigSource ics = new IniConfigSource(); IConfig config = ics.AddConfig("ClientStack.LindenUDP"); @@ -210,7 +210,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID); Assert.That(spAfterAckTimeout, Is.Null); - TestHelpers.DisableLogging(); +// TestHelpers.DisableLogging(); } // /// diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index b6cd287..daaa3c0 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs @@ -480,6 +480,9 @@ namespace pCampBot public void Objects_NewPrim(object sender, PrimEventArgs args) { +// if (Name.EndsWith("4")) +// throw new Exception("Aaargh"); + Primitive prim = args.Prim; if (prim != null) -- cgit v1.1 From f94b92df4646162c0a8f37dd3373c6c2a20c66e3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Jun 2012 04:12:22 +0100 Subject: Instead of retrieving the known client again in LLUDPServer.RemoveClient(), check the IsLoggingOut flag instead. This is slightly better thread-race wise --- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 31 +++++++--------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index e1fccb5..7f86491 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -560,7 +560,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); - RemoveClient(udpClient); + RemoveClient(client); return; } @@ -1110,26 +1110,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP return client; } - private void RemoveClient(LLUDPClient udpClient) + private void RemoveClient(IClientAPI client) { - // Remove this client from the scene - IClientAPI client; - if (m_scene.TryGetClient(udpClient.AgentID, out client)) - { - // We must set IsLoggingOut synchronously so that we can stop the packet loop reinvoking this method. - client.IsLoggingOut = true; + // We must set IsLoggingOut synchronously so that we can stop the packet loop reinvoking this method. + client.IsLoggingOut = true; - // 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 => client.Close()); - } - else - { - m_log.WarnFormat( - "[LLUDPSERVER]: Tried to remove client with id {0} but not such client in {1}", - udpClient.AgentID, m_scene.RegionInfo.RegionName); - } + // 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 => client.Close()); } private void IncomingPacketHandler() @@ -1443,8 +1432,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected void LogoutHandler(IClientAPI client) { client.SendLogoutPacket(); - if (client.IsActive) - RemoveClient(((LLClientView)client).UDPClient); + if (!client.IsLoggingOut) + RemoveClient(client); } } } \ No newline at end of file -- cgit v1.1 From 794d184c253d1967535e4040682a70b729dc3ccb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Jun 2012 04:32:51 +0100 Subject: Stop sending a DisableSimulator packet in LLClientView.Close(), which is a duplicate for child agents and unnecessary for root agents. Close() already calls Scene.RemoveClient() which sends the right eq or udp DisableSimulator message to child agents. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 4d6081c..74b9c6d 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -494,10 +494,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP "[CLIENT]: Close has been called for {0} attached to scene {1}", Name, m_scene.RegionInfo.RegionName); - // Send the STOP packet - DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); - OutPacket(disable, ThrottleOutPacketType.Unknown); - IsActive = false; // Shutdown the image manager -- cgit v1.1 From 817f2d341d30c7df1556071c9cc8b4c4a5588cb5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Jun 2012 23:36:53 +0100 Subject: Fix regression in 5f4f9f0 (Fri Jun 8 2012) which stopped "show stats" and json stats from working --- OpenSim/Region/Application/OpenSimBase.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 9a0fa70..3271555 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -223,6 +223,8 @@ namespace OpenSim base.StartupSpecific(); + m_stats = StatsManager.SimExtraStats; + // Create a ModuleLoader instance m_moduleLoader = new ModuleLoader(m_config.Source); -- cgit v1.1 From 08cd5d2503d23bda54622d9110c7146b6a8648ff Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 9 Jun 2012 00:33:17 +0100 Subject: Add documentation to AllowGodFunctions setting in [LL-Functions] --- bin/OpenSimDefaults.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index c67e45a..0e1a3af 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -1153,6 +1153,8 @@ ; currently unused ; AllowosConsoleCommand=false + ; Are god functions such as llSetObjectPermMask() allowed? If true then gods and only gods have access to these functions. + ; If false then gods cannot execute these functions either. AllowGodFunctions = false ; Maximum number of llListen events we allow over the entire region. -- cgit v1.1 From 1f3218e53f01ee20eefbd484810f8d5ec8190a31 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 9 Jun 2012 01:11:15 +0100 Subject: Create avatar entries necessary to stop new v3 avatars being clouds (pants, shape, etc.) by default in grid mode. This only affects avatars created through the "create user" console command or createuser XMLRPC. This matches the default setting for standalone --- bin/Robust.ini.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index 1c04ab5..f70d13b 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -166,7 +166,7 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ;; This switch creates the minimum set of body parts and avatar entries for a viewer 2 ;; to show a default "Ruth" avatar rather than a cloud for a newly created user. ;; Default is false - ; CreateDefaultAvatarEntries = false + CreateDefaultAvatarEntries = true ;; Allow the service to process HTTP createuser calls. ;; Default is false. -- cgit v1.1 From a8a9d13dc07bc9e23ebf439cbea5ece6ae002315 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 9 Jun 2012 05:11:08 +0100 Subject: Bind ~ and ! operators in LSL tighter in order to resolve issues in LSL where these aren't evaluated propertly. Addresses http://opensimulator.org/mantis/view.php?id=3268 --- .../ScriptEngine/Shared/CodeTools/lsl.parser.cs | 7954 ++++++++++---------- 1 file changed, 3966 insertions(+), 3988 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.parser.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.parser.cs index ca56cd6..8428c96 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.parser.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.parser.cs @@ -6338,494 +6338,488 @@ public yyLSLSyntax 16,0,488,1,74, 1253,1,328,1302,1, 1048,2014,16,0,488, -1,82,2015,16,0, -488,1,1840,2016,16, -0,488,1,1591,2017, -16,0,488,1,1341, -2018,16,0,488,1, -1096,1312,1,93,1318, -1,352,1349,1,107, -2019,16,0,488,1, -1114,1343,1,118,2020, -16,0,488,1,1123, -2021,16,0,488,1, -371,1365,1,1628,2022, -16,0,488,1,375, -1376,1,1882,2023,16, -0,488,1,377,1381, -1,379,1386,1,380, -1391,1,883,2024,16, -0,488,1,373,1409, -1,130,2025,16,0, -488,1,143,2026,16, -0,488,1,387,2027, -16,0,488,1,2664, -2028,16,0,488,1, -1159,2029,16,0,488, -1,157,2030,16,0, -488,1,1413,2031,16, -0,488,1,1665,2032, -16,0,488,1,412, -2033,16,0,488,1, -1377,2034,16,0,488, -1,172,2035,16,0, -488,1,1939,2036,16, -0,488,1,437,2037, -16,0,488,1,188, -2038,16,0,488,1, -942,2039,16,0,488, -1,1195,2040,16,0, -488,1,1449,2041,16, -0,488,1,1701,2042, -16,0,488,1,447, -1511,1,205,2043,16, -0,488,1,827,2044, -16,0,488,1,223, -2045,16,0,488,1, -476,1543,1,477,1549, -1,1231,2046,16,0, -488,1,479,1559,1, -480,1564,1,1485,2047, -16,0,488,1,1737, -2048,16,0,488,1, -242,2049,16,0,488, -1,478,1583,1,1001, -1588,1,1002,1593,1, -19,2050,19,225,1, -19,2051,5,176,1, -256,2052,16,0,223, -1,1261,2053,16,0, -223,1,1011,1102,1, -1012,2054,16,0,455, -1,2458,876,1,262, -1119,1,1267,2055,16, -0,455,1,2021,718, -1,1521,2056,16,0, -455,1,1775,2057,16, -0,223,1,2029,725, -1,2030,731,1,2031, -736,1,2032,741,1, -2033,746,1,277,2058, -16,0,223,1,2035, -752,1,2037,757,1, -2039,762,1,32,2059, -16,0,223,1,2464, -899,1,2293,2060,16, -0,223,1,2043,774, -1,2045,779,1,2299, -2061,16,0,455,1, -41,2062,16,0,223, -1,42,2063,16,0, -455,1,40,1177,1, -44,1183,1,43,2064, -16,0,223,1,1804, -2065,16,0,223,1, -48,1190,1,49,1196, -1,47,1184,1,51, -1206,1,52,2066,16, -0,223,1,50,1201, -1,305,1211,1,1096, -1312,1,1515,2067,16, -0,223,1,2318,2068, -16,0,223,1,283, -1172,1,63,1222,1, -66,1228,1,67,1233, -1,68,1238,1,69, -1243,1,70,1248,1, -71,2069,16,0,223, -1,73,2070,16,0, -455,1,74,1253,1, -1013,1258,1,76,2071, -16,0,223,1,1834, -2072,16,0,223,1, -2337,2073,16,0,223, -1,79,2074,16,0, -223,1,1335,2075,16, -0,223,1,299,2076, -16,0,223,1,82, -2077,16,0,455,1, -1840,2078,16,0,455, -1,1297,2079,16,0, -223,1,85,2080,16, -0,223,1,1341,2081, -16,0,455,1,89, -2082,16,0,223,1, -1303,2083,16,0,455, -1,509,2084,16,0, -223,1,93,1318,1, -322,2085,16,0,223, -1,97,2086,16,0, -223,1,2041,768,1, -1555,2087,16,0,455, -1,827,2088,16,0, -455,1,102,2089,16, -0,223,1,1860,821, -1,1803,787,1,2364, -827,1,107,2090,16, -0,455,1,1114,1343, -1,112,2091,16,0, -223,1,1117,2092,16, -0,223,1,352,1349, -1,1873,835,1,118, -2093,16,0,455,1, -1123,2094,16,0,455, -1,371,1365,1,515, -2095,16,0,455,1, -1377,2096,16,0,455, -1,124,2097,16,0, -223,1,1882,2098,16, -0,455,1,377,1381, -1,379,1386,1,380, -1391,1,130,2099,16, -0,455,1,346,2100, -16,0,223,1,2075, -2101,16,0,223,1, -373,1409,1,387,2102, -16,0,455,1,137, -2103,16,0,223,1, -143,2104,16,0,455, -1,1901,2105,16,0, -223,1,1048,2106,16, -0,455,1,2658,2107, -16,0,223,1,1153, -2108,16,0,223,1, -375,1376,1,151,2109, -16,0,223,1,1407, -2110,16,0,223,1, -1659,2111,16,0,223, -1,2413,2112,16,0, -223,1,1159,2113,16, -0,455,1,381,2114, -16,0,223,1,157, -2115,16,0,455,1, -1413,2116,16,0,455, -1,883,2117,16,0, -455,1,1371,2118,16, -0,223,1,328,1302, -1,2105,814,1,2106, -2119,16,0,223,1, -166,2120,16,0,223, -1,525,2121,16,0, -223,1,1622,2122,16, -0,223,1,406,2123, -16,0,223,1,1574, -799,1,172,2124,16, -0,455,1,1931,861, -1,412,2125,16,0, -455,1,1933,2126,16, -0,223,1,1876,2127, -16,0,223,1,431, -2128,16,0,223,1, -1585,2129,16,0,223, -1,182,2130,16,0, -223,1,1628,2131,16, -0,455,1,1189,2132, -16,0,223,1,437, -2133,16,0,455,1, -1591,2134,16,0,455, -1,188,2135,16,0, -455,1,1695,2136,16, -0,223,1,2198,2137, -16,0,223,1,1195, -2138,16,0,455,1, -1449,2139,16,0,455, -1,1701,2140,16,0, -455,1,447,2141,16, -0,223,1,199,2142, -16,0,223,1,2459, -882,1,1958,2143,16, -0,223,1,2462,889, -1,1657,894,1,205, -2144,16,0,455,1, -459,2145,16,0,223, -1,462,2146,16,0, -223,1,1665,2147,16, -0,455,1,217,2148, -16,0,223,1,2227, -908,1,942,2149,16, -0,455,1,1225,2150, -16,0,223,1,223, -2151,16,0,455,1, -1479,2152,16,0,223, -1,1731,2153,16,0, -223,1,477,1549,1, -1231,2154,16,0,455, +1,82,1280,1,1840, +2015,16,0,488,1, +1591,2016,16,0,488, +1,1341,2017,16,0, +488,1,1096,1312,1, +93,1318,1,352,1349, +1,107,1338,1,1114, +1343,1,118,2018,16, +0,488,1,1123,2019, +16,0,488,1,371, +1365,1,1628,2020,16, +0,488,1,375,1376, +1,1882,2021,16,0, +488,1,377,1381,1, +379,1386,1,380,1391, +1,883,2022,16,0, +488,1,373,1409,1, +130,2023,16,0,488, +1,143,2024,16,0, +488,1,387,2025,16, +0,488,1,2664,2026, +16,0,488,1,1159, +2027,16,0,488,1, +157,2028,16,0,488, +1,1413,2029,16,0, +488,1,1665,2030,16, +0,488,1,412,2031, +16,0,488,1,1377, +2032,16,0,488,1, +172,2033,16,0,488, +1,1939,2034,16,0, +488,1,437,2035,16, +0,488,1,188,2036, +16,0,488,1,942, +2037,16,0,488,1, +1195,2038,16,0,488, +1,1449,2039,16,0, +488,1,1701,2040,16, +0,488,1,447,1511, +1,205,2041,16,0, +488,1,827,2042,16, +0,488,1,223,2043, +16,0,488,1,476, +1543,1,477,1549,1, +1231,2044,16,0,488, 1,479,1559,1,480, -1564,1,1485,2155,16, -0,455,1,1737,2156, -16,0,455,1,1989, -916,1,1990,2157,16, -0,223,1,1443,2158, -16,0,223,1,236, -2159,16,0,223,1, -2136,842,1,2664,2160, -16,0,455,1,476, -1543,1,242,2161,16, -0,455,1,478,1583, -1,1939,2162,16,0, -455,1,1001,1588,1, -1002,1593,1,1756,2163, -16,0,223,1,20, -2164,19,442,1,20, -2165,5,84,1,1011, -1102,1,1012,2166,16, -0,440,1,1013,1258, -1,262,1119,1,1267, -2167,16,0,440,1, -515,2168,16,0,440, -1,1521,2169,16,0, -440,1,525,1216,1, -283,1172,1,2299,2170, -16,0,440,1,42, -2171,16,0,440,1, -40,1177,1,44,1183, -1,47,1184,1,1303, -2172,16,0,440,1, -1555,2173,16,0,440, -1,50,1201,1,48, +1564,1,1485,2045,16, +0,488,1,1737,2046, +16,0,488,1,242, +2047,16,0,488,1, +478,1583,1,1001,1588, +1,1002,1593,1,19, +2048,19,225,1,19, +2049,5,176,1,256, +2050,16,0,223,1, +1261,2051,16,0,223, +1,1011,1102,1,1012, +2052,16,0,455,1, +2458,876,1,262,1119, +1,1267,2053,16,0, +455,1,2021,718,1, +1521,2054,16,0,455, +1,1775,2055,16,0, +223,1,2029,725,1, +2030,731,1,2031,736, +1,2032,741,1,2033, +746,1,277,2056,16, +0,223,1,2035,752, +1,2037,757,1,2039, +762,1,32,2057,16, +0,223,1,2464,899, +1,2293,2058,16,0, +223,1,2043,774,1, +2045,779,1,2299,2059, +16,0,455,1,41, +2060,16,0,223,1, +42,2061,16,0,455, +1,40,1177,1,44, +1183,1,43,2062,16, +0,223,1,1804,2063, +16,0,223,1,48, 1190,1,49,1196,1, -51,1206,1,63,1222, -1,305,1211,1,66, +47,1184,1,51,1206, +1,52,2064,16,0, +223,1,50,1201,1, +305,1211,1,1096,1312, +1,1515,2065,16,0, +223,1,2318,2066,16, +0,223,1,283,1172, +1,63,1222,1,66, 1228,1,67,1233,1, 68,1238,1,69,1243, -1,70,1248,1,73, -2174,16,0,440,1, -74,1253,1,328,2175, -16,0,440,1,1048, -2176,16,0,440,1, -82,2177,16,0,440, -1,1840,2178,16,0, -440,1,1591,2179,16, -0,440,1,1341,2180, -16,0,440,1,1096, -1312,1,93,1318,1, -352,2181,16,0,440, -1,107,2182,16,0, -440,1,1114,1343,1, -118,2183,16,0,440, -1,1123,2184,16,0, -440,1,371,1365,1, -1628,2185,16,0,440, -1,375,1376,1,1882, -2186,16,0,440,1, -377,1381,1,379,1386, -1,380,1391,1,883, -2187,16,0,440,1, -373,1409,1,130,2188, -16,0,440,1,143, -2189,16,0,440,1, -387,2190,16,0,440, -1,2664,2191,16,0, -440,1,1159,2192,16, -0,440,1,157,2193, -16,0,440,1,1413, -2194,16,0,440,1, -1665,2195,16,0,440, -1,412,2196,16,0, -440,1,1377,2197,16, -0,440,1,172,2198, -16,0,440,1,1939, -2199,16,0,440,1, -437,2200,16,0,440, -1,188,2201,16,0, -440,1,942,2202,16, -0,440,1,1195,2203, -16,0,440,1,1449, -2204,16,0,440,1, -1701,2205,16,0,440, -1,447,1511,1,205, -2206,16,0,440,1, -827,2207,16,0,440, -1,223,2208,16,0, -440,1,476,1543,1, -477,1549,1,1231,2209, -16,0,440,1,479, +1,70,1248,1,71, +2067,16,0,223,1, +73,2068,16,0,455, +1,74,1253,1,1013, +1258,1,76,2069,16, +0,223,1,1834,2070, +16,0,223,1,2337, +2071,16,0,223,1, +79,2072,16,0,223, +1,1335,2073,16,0, +223,1,299,2074,16, +0,223,1,82,1280, +1,1840,2075,16,0, +455,1,1297,2076,16, +0,223,1,85,2077, +16,0,223,1,1341, +2078,16,0,455,1, +89,2079,16,0,223, +1,1303,2080,16,0, +455,1,509,2081,16, +0,223,1,93,1318, +1,322,2082,16,0, +223,1,97,2083,16, +0,223,1,2041,768, +1,1555,2084,16,0, +455,1,827,2085,16, +0,455,1,102,2086, +16,0,223,1,1860, +821,1,1803,787,1, +2364,827,1,107,1338, +1,1114,1343,1,112, +2087,16,0,223,1, +1117,2088,16,0,223, +1,352,1349,1,1873, +835,1,118,2089,16, +0,455,1,1123,2090, +16,0,455,1,371, +1365,1,515,2091,16, +0,455,1,1377,2092, +16,0,455,1,124, +2093,16,0,223,1, +1882,2094,16,0,455, +1,377,1381,1,379, +1386,1,380,1391,1, +130,2095,16,0,455, +1,346,2096,16,0, +223,1,2075,2097,16, +0,223,1,373,1409, +1,387,2098,16,0, +455,1,137,2099,16, +0,223,1,143,2100, +16,0,455,1,1901, +2101,16,0,223,1, +1048,2102,16,0,455, +1,2658,2103,16,0, +223,1,1153,2104,16, +0,223,1,375,1376, +1,151,2105,16,0, +223,1,1407,2106,16, +0,223,1,1659,2107, +16,0,223,1,2413, +2108,16,0,223,1, +1159,2109,16,0,455, +1,381,2110,16,0, +223,1,157,2111,16, +0,455,1,1413,2112, +16,0,455,1,883, +2113,16,0,455,1, +1371,2114,16,0,223, +1,328,1302,1,2105, +814,1,2106,2115,16, +0,223,1,166,2116, +16,0,223,1,525, +2117,16,0,223,1, +1622,2118,16,0,223, +1,406,2119,16,0, +223,1,1574,799,1, +172,2120,16,0,455, +1,1931,861,1,412, +2121,16,0,455,1, +1933,2122,16,0,223, +1,1876,2123,16,0, +223,1,431,2124,16, +0,223,1,1585,2125, +16,0,223,1,182, +2126,16,0,223,1, +1628,2127,16,0,455, +1,1189,2128,16,0, +223,1,437,2129,16, +0,455,1,1591,2130, +16,0,455,1,188, +2131,16,0,455,1, +1695,2132,16,0,223, +1,2198,2133,16,0, +223,1,1195,2134,16, +0,455,1,1449,2135, +16,0,455,1,1701, +2136,16,0,455,1, +447,2137,16,0,223, +1,199,2138,16,0, +223,1,2459,882,1, +1958,2139,16,0,223, +1,2462,889,1,1657, +894,1,205,2140,16, +0,455,1,459,2141, +16,0,223,1,462, +2142,16,0,223,1, +1665,2143,16,0,455, +1,217,2144,16,0, +223,1,2227,908,1, +942,2145,16,0,455, +1,1225,2146,16,0, +223,1,223,2147,16, +0,455,1,1479,2148, +16,0,223,1,1731, +2149,16,0,223,1, +477,1549,1,1231,2150, +16,0,455,1,479, 1559,1,480,1564,1, -1485,2210,16,0,440, -1,1737,2211,16,0, -440,1,242,2212,16, -0,440,1,478,1583, -1,1001,1588,1,1002, -1593,1,21,2213,19, -432,1,21,2214,5, +1485,2151,16,0,455, +1,1737,2152,16,0, +455,1,1989,916,1, +1990,2153,16,0,223, +1,1443,2154,16,0, +223,1,236,2155,16, +0,223,1,2136,842, +1,2664,2156,16,0, +455,1,476,1543,1, +242,2157,16,0,455, +1,478,1583,1,1939, +2158,16,0,455,1, +1001,1588,1,1002,1593, +1,1756,2159,16,0, +223,1,20,2160,19, +442,1,20,2161,5, 84,1,1011,1102,1, -1012,2215,16,0,430, +1012,2162,16,0,440, 1,1013,1258,1,262, -1119,1,1267,2216,16, -0,430,1,515,2217, -16,0,430,1,1521, -2218,16,0,430,1, +1119,1,1267,2163,16, +0,440,1,515,2164, +16,0,440,1,1521, +2165,16,0,440,1, 525,1216,1,283,1172, -1,2299,2219,16,0, -430,1,42,2220,16, -0,430,1,40,1177, +1,2299,2166,16,0, +440,1,42,2167,16, +0,440,1,40,1177, 1,44,1183,1,47, -1184,1,1303,2221,16, -0,430,1,1555,2222, -16,0,430,1,50, +1184,1,1303,2168,16, +0,440,1,1555,2169, +16,0,440,1,50, 1201,1,48,1190,1, 49,1196,1,51,1206, 1,63,1222,1,305, 1211,1,66,1228,1, 67,1233,1,68,1238, 1,69,1243,1,70, -1248,1,73,2223,16, -0,430,1,74,1253, -1,328,2224,16,0, -430,1,1048,2225,16, -0,430,1,82,2226, -16,0,430,1,1840, -2227,16,0,430,1, -1591,2228,16,0,430, -1,1341,2229,16,0, -430,1,1096,1312,1, -93,1318,1,352,2230, -16,0,430,1,107, +1248,1,73,2170,16, +0,440,1,74,1253, +1,328,2171,16,0, +440,1,1048,2172,16, +0,440,1,82,1280, +1,1840,2173,16,0, +440,1,1591,2174,16, +0,440,1,1341,2175, +16,0,440,1,1096, +1312,1,93,1318,1, +352,2176,16,0,440, +1,107,1338,1,1114, +1343,1,118,2177,16, +0,440,1,1123,2178, +16,0,440,1,371, +1365,1,1628,2179,16, +0,440,1,375,1376, +1,1882,2180,16,0, +440,1,377,1381,1, +379,1386,1,380,1391, +1,883,2181,16,0, +440,1,373,1409,1, +130,2182,16,0,440, +1,143,2183,16,0, +440,1,387,2184,16, +0,440,1,2664,2185, +16,0,440,1,1159, +2186,16,0,440,1, +157,2187,16,0,440, +1,1413,2188,16,0, +440,1,1665,2189,16, +0,440,1,412,2190, +16,0,440,1,1377, +2191,16,0,440,1, +172,2192,16,0,440, +1,1939,2193,16,0, +440,1,437,2194,16, +0,440,1,188,2195, +16,0,440,1,942, +2196,16,0,440,1, +1195,2197,16,0,440, +1,1449,2198,16,0, +440,1,1701,2199,16, +0,440,1,447,1511, +1,205,2200,16,0, +440,1,827,2201,16, +0,440,1,223,2202, +16,0,440,1,476, +1543,1,477,1549,1, +1231,2203,16,0,440, +1,479,1559,1,480, +1564,1,1485,2204,16, +0,440,1,1737,2205, +16,0,440,1,242, +2206,16,0,440,1, +478,1583,1,1001,1588, +1,1002,1593,1,21, +2207,19,432,1,21, +2208,5,84,1,1011, +1102,1,1012,2209,16, +0,430,1,1013,1258, +1,262,1119,1,1267, +2210,16,0,430,1, +515,2211,16,0,430, +1,1521,2212,16,0, +430,1,525,1216,1, +283,1172,1,2299,2213, +16,0,430,1,42, +2214,16,0,430,1, +40,1177,1,44,1183, +1,47,1184,1,1303, +2215,16,0,430,1, +1555,2216,16,0,430, +1,50,1201,1,48, +1190,1,49,1196,1, +51,1206,1,63,1222, +1,305,1211,1,66, +1228,1,67,1233,1, +68,1238,1,69,1243, +1,70,1248,1,73, +2217,16,0,430,1, +74,1253,1,328,2218, +16,0,430,1,1048, +2219,16,0,430,1, +82,1280,1,1840,2220, +16,0,430,1,1591, +2221,16,0,430,1, +1341,2222,16,0,430, +1,1096,1312,1,93, +1318,1,352,2223,16, +0,430,1,107,1338, +1,1114,1343,1,118, +2224,16,0,430,1, +1123,2225,16,0,430, +1,371,1365,1,1628, +2226,16,0,430,1, +375,1376,1,1882,2227, +16,0,430,1,377, +1381,1,379,1386,1, +380,1391,1,883,2228, +16,0,430,1,373, +1409,1,130,2229,16, +0,430,1,143,2230, +16,0,430,1,387, 2231,16,0,430,1, -1114,1343,1,118,2232, -16,0,430,1,1123, -2233,16,0,430,1, -371,1365,1,1628,2234, -16,0,430,1,375, -1376,1,1882,2235,16, -0,430,1,377,1381, -1,379,1386,1,380, -1391,1,883,2236,16, -0,430,1,373,1409, -1,130,2237,16,0, -430,1,143,2238,16, -0,430,1,387,2239, -16,0,430,1,2664, -2240,16,0,430,1, -1159,2241,16,0,430, -1,157,2242,16,0, -430,1,1413,2243,16, -0,430,1,1665,2244, -16,0,430,1,412, -2245,16,0,430,1, -1377,2246,16,0,430, -1,172,2247,16,0, -430,1,1939,2248,16, -0,430,1,437,2249, -16,0,430,1,188, -2250,16,0,430,1, -942,2251,16,0,430, -1,1195,2252,16,0, -430,1,1449,2253,16, -0,430,1,1701,2254, -16,0,430,1,447, -1511,1,205,2255,16, -0,430,1,827,2256, -16,0,430,1,223, -2257,16,0,430,1, -476,1543,1,477,1549, -1,1231,2258,16,0, -430,1,479,1559,1, -480,1564,1,1485,2259, -16,0,430,1,1737, -2260,16,0,430,1, -242,2261,16,0,430, -1,478,1583,1,1001, -1588,1,1002,1593,1, -22,2262,19,383,1, -22,2263,5,84,1, -1011,1102,1,1012,2264, -16,0,381,1,1013, -1258,1,262,1119,1, -1267,2265,16,0,381, -1,515,2266,16,0, -381,1,1521,2267,16, -0,381,1,525,1216, -1,283,1172,1,2299, -2268,16,0,381,1, -42,2269,16,0,381, -1,40,1177,1,44, -1183,1,47,1184,1, -1303,2270,16,0,381, -1,1555,2271,16,0, -381,1,50,1201,1, -48,1190,1,49,1196, -1,51,1206,1,63, -1222,1,305,1211,1, -66,1228,1,67,1233, -1,68,1238,1,69, -1243,1,70,1248,1, -73,2272,16,0,381, -1,74,1253,1,328, -2273,16,0,381,1, -1048,2274,16,0,381, -1,82,2275,16,0, -381,1,1840,2276,16, -0,381,1,1591,2277, -16,0,381,1,1341, -2278,16,0,381,1, -1096,1312,1,93,1318, -1,352,2279,16,0, -381,1,107,2280,16, -0,381,1,1114,1343, -1,118,2281,16,0, -381,1,1123,2282,16, +2664,2232,16,0,430, +1,1159,2233,16,0, +430,1,157,2234,16, +0,430,1,1413,2235, +16,0,430,1,1665, +2236,16,0,430,1, +412,2237,16,0,430, +1,1377,2238,16,0, +430,1,172,2239,16, +0,430,1,1939,2240, +16,0,430,1,437, +2241,16,0,430,1, +188,2242,16,0,430, +1,942,2243,16,0, +430,1,1195,2244,16, +0,430,1,1449,2245, +16,0,430,1,1701, +2246,16,0,430,1, +447,1511,1,205,2247, +16,0,430,1,827, +2248,16,0,430,1, +223,2249,16,0,430, +1,476,1543,1,477, +1549,1,1231,2250,16, +0,430,1,479,1559, +1,480,1564,1,1485, +2251,16,0,430,1, +1737,2252,16,0,430, +1,242,2253,16,0, +430,1,478,1583,1, +1001,1588,1,1002,1593, +1,22,2254,19,383, +1,22,2255,5,84, +1,1011,1102,1,1012, +2256,16,0,381,1, +1013,1258,1,262,1119, +1,1267,2257,16,0, +381,1,515,2258,16, +0,381,1,1521,2259, +16,0,381,1,525, +1216,1,283,1172,1, +2299,2260,16,0,381, +1,42,2261,16,0, +381,1,40,1177,1, +44,1183,1,47,1184, +1,1303,2262,16,0, +381,1,1555,2263,16, +0,381,1,50,1201, +1,48,1190,1,49, +1196,1,51,1206,1, +63,1222,1,305,1211, +1,66,1228,1,67, +1233,1,68,1238,1, +69,1243,1,70,1248, +1,73,2264,16,0, +381,1,74,1253,1, +328,2265,16,0,381, +1,1048,2266,16,0, +381,1,82,1280,1, +1840,2267,16,0,381, +1,1591,2268,16,0, +381,1,1341,2269,16, +0,381,1,1096,1312, +1,93,1318,1,352, +2270,16,0,381,1, +107,1338,1,1114,1343, +1,118,2271,16,0, +381,1,1123,2272,16, 0,381,1,371,1365, -1,1628,2283,16,0, +1,1628,2273,16,0, 381,1,375,1376,1, -1882,2284,16,0,381, +1882,2274,16,0,381, 1,377,1381,1,379, 1386,1,380,1391,1, -883,2285,16,0,381, +883,2275,16,0,381, 1,373,1409,1,130, -2286,16,0,381,1, -143,2287,16,0,381, -1,387,2288,16,0, -381,1,2664,2289,16, -0,381,1,1159,2290, +2276,16,0,381,1, +143,2277,16,0,381, +1,387,2278,16,0, +381,1,2664,2279,16, +0,381,1,1159,2280, 16,0,381,1,157, -2291,16,0,381,1, -1413,2292,16,0,381, -1,1665,2293,16,0, -381,1,412,2294,16, -0,381,1,1377,2295, +2281,16,0,381,1, +1413,2282,16,0,381, +1,1665,2283,16,0, +381,1,412,2284,16, +0,381,1,1377,2285, 16,0,381,1,172, -2296,16,0,381,1, -1939,2297,16,0,381, -1,437,2298,16,0, -381,1,188,2299,16, -0,381,1,942,2300, +2286,16,0,381,1, +1939,2287,16,0,381, +1,437,2288,16,0, +381,1,188,2289,16, +0,381,1,942,2290, 16,0,381,1,1195, -2301,16,0,381,1, -1449,2302,16,0,381, -1,1701,2303,16,0, +2291,16,0,381,1, +1449,2292,16,0,381, +1,1701,2293,16,0, 381,1,447,1511,1, -205,2304,16,0,381, -1,827,2305,16,0, -381,1,223,2306,16, +205,2294,16,0,381, +1,827,2295,16,0, +381,1,223,2296,16, 0,381,1,476,1543, 1,477,1549,1,1231, -2307,16,0,381,1, +2297,16,0,381,1, 479,1559,1,480,1564, -1,1485,2308,16,0, -381,1,1737,2309,16, -0,381,1,242,2310, +1,1485,2298,16,0, +381,1,1737,2299,16, +0,381,1,242,2300, 16,0,381,1,478, 1583,1,1001,1588,1, -1002,1593,1,23,2311, -19,504,1,23,2312, -5,38,1,1901,2313, +1002,1593,1,23,2301, +19,504,1,23,2302, +5,38,1,1901,2303, 16,0,502,1,2075, -2314,16,0,502,1, +2304,16,0,502,1, 1860,821,1,1803,787, -1,1804,2315,16,0, -502,1,2413,2316,16, -0,502,1,2198,2317, +1,1804,2305,16,0, +502,1,2413,2306,16, +0,502,1,2198,2307, 16,0,502,1,1873, 835,1,1657,894,1, -1989,916,1,1990,2318, +1989,916,1,1990,2308, 16,0,502,1,1775, -2319,16,0,502,1, -32,2320,16,0,502, +2309,16,0,502,1, +32,2310,16,0,502, 1,2105,814,1,2106, -2321,16,0,502,1, +2311,16,0,502,1, 2364,827,1,2227,908, -1,2337,2322,16,0, +1,2337,2312,16,0, 502,1,2021,718,1, 2458,876,1,2459,882, 1,2462,889,1,2136, @@ -6838,1207 +6832,1195 @@ public yyLSLSyntax 861,1,2041,768,1, 2043,774,1,2045,779, 1,1574,799,1,1958, -2323,16,0,502,1, -24,2324,19,177,1, -24,2325,5,5,1, -44,2326,16,0,175, -1,377,2327,16,0, -540,1,40,2328,16, -0,674,1,63,2329, +2313,16,0,502,1, +24,2314,19,177,1, +24,2315,5,5,1, +44,2316,16,0,175, +1,377,2317,16,0, +540,1,40,2318,16, +0,674,1,63,2319, 16,0,196,1,373, -2330,16,0,536,1, -25,2331,19,291,1, -25,2332,5,177,1, -256,2333,16,0,545, -1,1261,2334,16,0, +2320,16,0,536,1, +25,2321,19,291,1, +25,2322,5,177,1, +256,2323,16,0,545, +1,1261,2324,16,0, 545,1,1011,1102,1, -1012,2335,16,0,289, +1012,2325,16,0,289, 1,2458,876,1,262, -1119,1,1267,2336,16, +1119,1,1267,2326,16, 0,289,1,2021,718, -1,1521,2337,16,0, -289,1,1775,2338,16, +1,1521,2327,16,0, +289,1,1775,2328,16, 0,545,1,2029,725, 1,2030,731,1,2031, 736,1,2032,741,1, -2033,746,1,277,2339, +2033,746,1,277,2329, 16,0,545,1,2035, 752,1,2037,757,1, -2039,762,1,32,2340, +2039,762,1,32,2330, 16,0,545,1,2464, -899,1,2293,2341,16, +899,1,2293,2331,16, 0,545,1,2043,774, 1,2045,779,1,2299, -2342,16,0,289,1, -41,2343,16,0,545, -1,42,2344,16,0, +2332,16,0,289,1, +41,2333,16,0,545, +1,42,2334,16,0, 289,1,40,1177,1, -44,1183,1,43,2345, +44,1183,1,43,2335, 16,0,545,1,1804, -2346,16,0,545,1, +2336,16,0,545,1, 48,1190,1,49,1196, 1,47,1184,1,51, -1206,1,52,2347,16, +1206,1,52,2337,16, 0,545,1,50,1201, 1,305,1211,1,1096, -1312,1,1515,2348,16, -0,545,1,2318,2349, +1312,1,1515,2338,16, +0,545,1,2318,2339, 16,0,545,1,62, -2350,16,0,545,1, +2340,16,0,545,1, 63,1222,1,66,1228, 1,67,1233,1,68, 1238,1,69,1243,1, -70,1248,1,71,2351, +70,1248,1,71,2341, 16,0,545,1,283, -1172,1,73,2352,16, +1172,1,73,2342,16, 0,289,1,74,1253, 1,1013,1258,1,76, -2353,16,0,545,1, -1834,2354,16,0,545, -1,2337,2355,16,0, -545,1,79,2356,16, -0,545,1,1335,2357, +2343,16,0,545,1, +1834,2344,16,0,545, +1,2337,2345,16,0, +545,1,79,2346,16, +0,545,1,1335,2347, 16,0,545,1,299, -2358,16,0,545,1, -82,2359,16,0,289, -1,1840,2360,16,0, -289,1,1297,2361,16, -0,545,1,85,2362, -16,0,545,1,1341, -2363,16,0,289,1, -89,2364,16,0,545, -1,1303,2365,16,0, -289,1,509,2366,16, -0,545,1,93,1318, -1,322,2367,16,0, -545,1,97,2368,16, -0,545,1,2041,768, -1,1555,2369,16,0, -289,1,827,2370,16, -0,289,1,102,2371, -16,0,545,1,1860, -821,1,1803,787,1, -2364,827,1,107,2372, -16,0,289,1,1114, -1343,1,112,2373,16, -0,545,1,1117,2374, -16,0,545,1,352, -1349,1,1873,835,1, -118,1355,1,1123,2375, -16,0,289,1,371, -1365,1,515,2376,16, -0,289,1,1377,2377, -16,0,289,1,124, -2378,16,0,545,1, -1882,2379,16,0,289, -1,377,1381,1,379, -1386,1,380,1391,1, -130,1414,1,346,2380, -16,0,545,1,2075, +2348,16,0,545,1, +82,1280,1,1840,2349, +16,0,289,1,1297, +2350,16,0,545,1, +85,2351,16,0,545, +1,1341,2352,16,0, +289,1,89,2353,16, +0,545,1,1303,2354, +16,0,289,1,509, +2355,16,0,545,1, +93,1318,1,322,2356, +16,0,545,1,97, +2357,16,0,545,1, +2041,768,1,1555,2358, +16,0,289,1,827, +2359,16,0,289,1, +102,2360,16,0,545, +1,1860,821,1,1803, +787,1,2364,827,1, +107,1338,1,1114,1343, +1,112,2361,16,0, +545,1,1117,2362,16, +0,545,1,352,1349, +1,1873,835,1,118, +1355,1,1123,2363,16, +0,289,1,371,1365, +1,515,2364,16,0, +289,1,1377,2365,16, +0,289,1,124,2366, +16,0,545,1,1882, +2367,16,0,289,1, +377,1381,1,379,1386, +1,380,1391,1,130, +1414,1,346,2368,16, +0,545,1,2075,2369, +16,0,545,1,373, +1409,1,387,2370,16, +0,289,1,137,2371, +16,0,545,1,143, +2372,16,0,289,1, +1901,2373,16,0,545, +1,1048,1344,1,2658, +2374,16,0,545,1, +1153,2375,16,0,545, +1,375,1376,1,151, +2376,16,0,545,1, +1407,2377,16,0,545, +1,1659,2378,16,0, +545,1,2413,2379,16, +0,545,1,1159,2380, +16,0,289,1,381, 2381,16,0,545,1, -373,1409,1,387,2382, -16,0,289,1,137, -2383,16,0,545,1, -143,2384,16,0,289, -1,1901,2385,16,0, -545,1,1048,1344,1, -2658,2386,16,0,545, -1,1153,2387,16,0, -545,1,375,1376,1, -151,2388,16,0,545, -1,1407,2389,16,0, -545,1,1659,2390,16, -0,545,1,2413,2391, -16,0,545,1,1159, -2392,16,0,289,1, -381,2393,16,0,545, -1,157,2394,16,0, -289,1,1413,2395,16, -0,289,1,883,2396, -16,0,289,1,1371, -2397,16,0,545,1, -328,1302,1,2105,814, -1,2106,2398,16,0, -545,1,166,2399,16, -0,545,1,525,2400, -16,0,545,1,1622, -2401,16,0,545,1, -406,2402,16,0,545, -1,1574,799,1,172, -1469,1,1931,861,1, -412,2403,16,0,289, -1,1933,2404,16,0, -545,1,1876,2405,16, -0,545,1,431,2406, -16,0,545,1,1585, -2407,16,0,545,1, -182,2408,16,0,545, -1,1628,2409,16,0, -289,1,1189,2410,16, -0,545,1,437,2411, -16,0,289,1,1591, -2412,16,0,289,1, -188,1518,1,1695,2413, -16,0,545,1,2198, -2414,16,0,545,1, -1195,2415,16,0,289, -1,1449,2416,16,0, -289,1,1701,2417,16, -0,289,1,447,2418, -16,0,545,1,199, -2419,16,0,545,1, -2459,882,1,1958,2420, -16,0,545,1,2462, -889,1,1657,894,1, -205,2421,16,0,289, -1,459,2422,16,0, -545,1,462,2423,16, -0,545,1,1665,2424, -16,0,289,1,217, -2425,16,0,545,1, -2227,908,1,942,1490, -1,1225,2426,16,0, -545,1,223,2427,16, -0,289,1,1479,2428, -16,0,545,1,1731, -2429,16,0,545,1, -477,1549,1,1231,2430, -16,0,289,1,479, -1559,1,480,1564,1, -1485,2431,16,0,289, -1,1737,2432,16,0, -289,1,1989,916,1, -1990,2433,16,0,545, -1,1443,2434,16,0, -545,1,236,2435,16, -0,545,1,2136,842, -1,2664,2436,16,0, -289,1,476,1543,1, -242,2437,16,0,289, -1,478,1583,1,1939, -2438,16,0,289,1, -1001,1588,1,1002,1593, -1,1756,2439,16,0, -545,1,26,2440,19, -308,1,26,2441,5, -84,1,1011,1102,1, -1012,2442,16,0,306, -1,1013,1258,1,262, -1119,1,1267,2443,16, -0,306,1,515,2444, -16,0,660,1,1521, -2445,16,0,306,1, -525,1216,1,283,1172, -1,2299,2446,16,0, -306,1,42,2447,16, -0,306,1,40,1177, -1,44,1183,1,47, -1184,1,1303,2448,16, -0,306,1,1555,2449, -16,0,306,1,50, -1201,1,48,1190,1, -49,1196,1,51,1206, -1,63,1222,1,305, -1211,1,66,1228,1, -67,1233,1,68,1238, -1,69,1243,1,70, -1248,1,73,2450,16, -0,306,1,74,1253, -1,328,1302,1,1048, -1344,1,82,2451,16, -0,306,1,1840,2452, -16,0,306,1,1591, -2453,16,0,306,1, -1341,2454,16,0,306, -1,1096,1312,1,93, -1318,1,352,1349,1, -107,2455,16,0,306, -1,1114,1343,1,118, -1355,1,1123,2456,16, -0,306,1,371,1365, -1,1628,2457,16,0, -306,1,375,1376,1, -1882,2458,16,0,306, -1,377,1381,1,379, -1386,1,380,1391,1, -883,2459,16,0,306, -1,373,1409,1,130, -1414,1,143,2460,16, -0,306,1,387,2461, -16,0,306,1,2664, -2462,16,0,306,1, -1159,2463,16,0,306, -1,157,2464,16,0, -306,1,1413,2465,16, -0,306,1,1665,2466, -16,0,306,1,412, -2467,16,0,306,1, -1377,2468,16,0,306, -1,172,1469,1,1939, -2469,16,0,306,1, -437,2470,16,0,588, -1,188,1518,1,942, -1490,1,1195,2471,16, -0,306,1,1449,2472, -16,0,306,1,1701, -2473,16,0,306,1, -447,1511,1,205,2474, -16,0,306,1,827, -2475,16,0,306,1, -223,2476,16,0,306, -1,476,1543,1,477, -1549,1,1231,2477,16, -0,306,1,479,1559, +157,2382,16,0,289, +1,1413,2383,16,0, +289,1,883,2384,16, +0,289,1,1371,2385, +16,0,545,1,328, +1302,1,2105,814,1, +2106,2386,16,0,545, +1,166,2387,16,0, +545,1,525,2388,16, +0,545,1,1622,2389, +16,0,545,1,406, +2390,16,0,545,1, +1574,799,1,172,1469, +1,1931,861,1,412, +2391,16,0,289,1, +1933,2392,16,0,545, +1,1876,2393,16,0, +545,1,431,2394,16, +0,545,1,1585,2395, +16,0,545,1,182, +2396,16,0,545,1, +1628,2397,16,0,289, +1,1189,2398,16,0, +545,1,437,2399,16, +0,289,1,1591,2400, +16,0,289,1,188, +1518,1,1695,2401,16, +0,545,1,2198,2402, +16,0,545,1,1195, +2403,16,0,289,1, +1449,2404,16,0,289, +1,1701,2405,16,0, +289,1,447,2406,16, +0,545,1,199,2407, +16,0,545,1,2459, +882,1,1958,2408,16, +0,545,1,2462,889, +1,1657,894,1,205, +2409,16,0,289,1, +459,2410,16,0,545, +1,462,2411,16,0, +545,1,1665,2412,16, +0,289,1,217,2413, +16,0,545,1,2227, +908,1,942,1490,1, +1225,2414,16,0,545, +1,223,2415,16,0, +289,1,1479,2416,16, +0,545,1,1731,2417, +16,0,545,1,477, +1549,1,1231,2418,16, +0,289,1,479,1559, 1,480,1564,1,1485, -2478,16,0,306,1, -1737,2479,16,0,306, -1,242,2480,16,0, -306,1,478,1583,1, -1001,1588,1,1002,1593, -1,27,2481,19,598, -1,27,2482,5,95, -1,256,2483,16,0, -596,1,1261,2484,16, -0,596,1,509,2485, -16,0,596,1,1515, -2486,16,0,596,1, -2021,718,1,1775,2487, -16,0,596,1,2029, -725,1,2030,731,1, -2031,736,1,2032,741, -1,2033,746,1,277, -2488,16,0,596,1, -2035,752,1,2037,757, -1,2039,762,1,32, -2489,16,0,596,1, -2041,768,1,2293,2490, -16,0,596,1,2043, -774,1,2045,779,1, -41,2491,16,0,596, -1,1297,2492,16,0, -596,1,43,2493,16, -0,596,1,1803,787, -1,1804,2494,16,0, -596,1,299,2495,16, -0,596,1,52,2496, -16,0,596,1,2318, -2497,16,0,596,1, -62,2498,16,0,596, -1,2075,2499,16,0, -596,1,1574,799,1, -71,2500,16,0,596, -1,76,2501,16,0, -596,1,1834,2502,16, -0,596,1,2337,2503, -16,0,596,1,79, -2504,16,0,596,1, -1335,2505,16,0,596, -1,322,2506,16,0, -596,1,85,2507,16, -0,596,1,89,2508, -16,0,596,1,346, -2509,16,0,596,1, -2105,814,1,2106,2510, -16,0,596,1,97, -2511,16,0,596,1, -1860,821,1,2364,827, -1,102,2512,16,0, -596,1,112,2513,16, -0,596,1,1117,2514, -16,0,596,1,1873, -835,1,1876,2515,16, -0,596,1,124,2516, -16,0,596,1,2136, -842,1,381,2517,16, -0,596,1,525,2518, -16,0,596,1,137, +2419,16,0,289,1, +1737,2420,16,0,289, +1,1989,916,1,1990, +2421,16,0,545,1, +1443,2422,16,0,545, +1,236,2423,16,0, +545,1,2136,842,1, +2664,2424,16,0,289, +1,476,1543,1,242, +2425,16,0,289,1, +478,1583,1,1939,2426, +16,0,289,1,1001, +1588,1,1002,1593,1, +1756,2427,16,0,545, +1,26,2428,19,308, +1,26,2429,5,84, +1,1011,1102,1,1012, +2430,16,0,306,1, +1013,1258,1,262,1119, +1,1267,2431,16,0, +306,1,515,2432,16, +0,660,1,1521,2433, +16,0,306,1,525, +1216,1,283,1172,1, +2299,2434,16,0,306, +1,42,2435,16,0, +306,1,40,1177,1, +44,1183,1,47,1184, +1,1303,2436,16,0, +306,1,1555,2437,16, +0,306,1,50,1201, +1,48,1190,1,49, +1196,1,51,1206,1, +63,1222,1,305,1211, +1,66,1228,1,67, +1233,1,68,1238,1, +69,1243,1,70,1248, +1,73,2438,16,0, +306,1,74,1253,1, +328,1302,1,1048,1344, +1,82,1280,1,1840, +2439,16,0,306,1, +1591,2440,16,0,306, +1,1341,2441,16,0, +306,1,1096,1312,1, +93,1318,1,352,1349, +1,107,1338,1,1114, +1343,1,118,1355,1, +1123,2442,16,0,306, +1,371,1365,1,1628, +2443,16,0,306,1, +375,1376,1,1882,2444, +16,0,306,1,377, +1381,1,379,1386,1, +380,1391,1,883,2445, +16,0,306,1,373, +1409,1,130,1414,1, +143,2446,16,0,306, +1,387,2447,16,0, +306,1,2664,2448,16, +0,306,1,1159,2449, +16,0,306,1,157, +2450,16,0,306,1, +1413,2451,16,0,306, +1,1665,2452,16,0, +306,1,412,2453,16, +0,306,1,1377,2454, +16,0,306,1,172, +1469,1,1939,2455,16, +0,306,1,437,2456, +16,0,588,1,188, +1518,1,942,1490,1, +1195,2457,16,0,306, +1,1449,2458,16,0, +306,1,1701,2459,16, +0,306,1,447,1511, +1,205,2460,16,0, +306,1,827,2461,16, +0,306,1,223,2462, +16,0,306,1,476, +1543,1,477,1549,1, +1231,2463,16,0,306, +1,479,1559,1,480, +1564,1,1485,2464,16, +0,306,1,1737,2465, +16,0,306,1,242, +2466,16,0,306,1, +478,1583,1,1001,1588, +1,1002,1593,1,27, +2467,19,598,1,27, +2468,5,95,1,256, +2469,16,0,596,1, +1261,2470,16,0,596, +1,509,2471,16,0, +596,1,1515,2472,16, +0,596,1,2021,718, +1,1775,2473,16,0, +596,1,2029,725,1, +2030,731,1,2031,736, +1,2032,741,1,2033, +746,1,277,2474,16, +0,596,1,2035,752, +1,2037,757,1,2039, +762,1,32,2475,16, +0,596,1,2041,768, +1,2293,2476,16,0, +596,1,2043,774,1, +2045,779,1,41,2477, +16,0,596,1,1297, +2478,16,0,596,1, +43,2479,16,0,596, +1,1803,787,1,1804, +2480,16,0,596,1, +299,2481,16,0,596, +1,52,2482,16,0, +596,1,2318,2483,16, +0,596,1,62,2484, +16,0,596,1,2075, +2485,16,0,596,1, +1574,799,1,71,2486, +16,0,596,1,76, +2487,16,0,596,1, +1834,2488,16,0,596, +1,2337,2489,16,0, +596,1,79,2490,16, +0,596,1,1335,2491, +16,0,596,1,322, +2492,16,0,596,1, +85,2493,16,0,596, +1,89,2494,16,0, +596,1,346,2495,16, +0,596,1,2105,814, +1,2106,2496,16,0, +596,1,97,2497,16, +0,596,1,1860,821, +1,2364,827,1,102, +2498,16,0,596,1, +112,2499,16,0,596, +1,1117,2500,16,0, +596,1,1873,835,1, +1876,2501,16,0,596, +1,124,2502,16,0, +596,1,2136,842,1, +381,2503,16,0,596, +1,525,2504,16,0, +596,1,137,2505,16, +0,596,1,1901,2506, +16,0,596,1,2658, +2507,16,0,596,1, +1153,2508,16,0,596, +1,151,2509,16,0, +596,1,1407,2510,16, +0,596,1,1659,2511, +16,0,596,1,2413, +2512,16,0,596,1, +406,2513,16,0,596, +1,1371,2514,16,0, +596,1,166,2515,16, +0,596,1,1622,2516, +16,0,596,1,1931, +861,1,1933,2517,16, +0,596,1,431,2518, +16,0,596,1,1585, 2519,16,0,596,1, -1901,2520,16,0,596, -1,2658,2521,16,0, -596,1,1153,2522,16, -0,596,1,151,2523, -16,0,596,1,1407, +182,2520,16,0,596, +1,1189,2521,16,0, +596,1,1443,2522,16, +0,596,1,1695,2523, +16,0,596,1,2198, 2524,16,0,596,1, -1659,2525,16,0,596, -1,2413,2526,16,0, -596,1,406,2527,16, -0,596,1,1371,2528, -16,0,596,1,166, +447,2525,16,0,596, +1,2458,876,1,2459, +882,1,1958,2526,16, +0,596,1,2462,889, +1,1657,894,1,2464, +899,1,199,2527,16, +0,596,1,459,2528, +16,0,596,1,462, 2529,16,0,596,1, -1622,2530,16,0,596, -1,1931,861,1,1933, +217,2530,16,0,596, +1,2227,908,1,1225, 2531,16,0,596,1, -431,2532,16,0,596, -1,1585,2533,16,0, -596,1,182,2534,16, -0,596,1,1189,2535, -16,0,596,1,1443, -2536,16,0,596,1, -1695,2537,16,0,596, -1,2198,2538,16,0, -596,1,447,2539,16, -0,596,1,2458,876, -1,2459,882,1,1958, -2540,16,0,596,1, -2462,889,1,1657,894, -1,2464,899,1,199, -2541,16,0,596,1, -459,2542,16,0,596, -1,462,2543,16,0, -596,1,217,2544,16, -0,596,1,2227,908, -1,1225,2545,16,0, -596,1,1479,2546,16, -0,596,1,1731,2547, -16,0,596,1,1989, -916,1,1990,2548,16, -0,596,1,236,2549, -16,0,596,1,1756, -2550,16,0,596,1, -28,2551,19,629,1, -28,2552,5,60,1, -328,1302,1,223,1533, -1,1096,1312,1,118, -1355,1,883,1397,1, -525,1216,1,1001,1588, -1,130,1414,1,459, -1688,1,1114,1343,1, -352,1349,1,447,1511, -1,464,1683,1,1011, -1102,1,1013,1258,1, -242,1578,1,143,1419, -1,40,1177,1,41, -1659,1,42,1662,1, -479,1559,1,44,1183, -1,481,1646,1,373, -1409,1,47,1184,1, -157,1443,1,49,1196, -1,50,1201,1,48, -1190,1,379,1386,1, -380,1391,1,51,1206, -1,476,1543,1,371, -1365,1,478,1583,1, -1048,1344,1,375,1376, -1,172,1469,1,262, -1119,1,283,1172,1, -63,1222,1,67,1233, -1,68,1238,1,69, -1243,1,66,1228,1, -461,2553,16,0,627, -1,74,1253,1,377, -1381,1,1002,1593,1, -70,1248,1,188,1518, -1,82,1280,1,305, -1211,1,477,1549,1, -827,1331,1,93,1318, -1,480,1564,1,205, -1523,1,942,1490,1, -107,1338,1,29,2554, -19,280,1,29,2555, -5,84,1,1011,1102, -1,1012,2556,16,0, -278,1,1013,1258,1, -262,1119,1,1267,2557, -16,0,278,1,515, -2558,16,0,278,1, -1521,2559,16,0,278, -1,525,1216,1,283, -1172,1,2299,2560,16, -0,278,1,42,2561, -16,0,278,1,40, -1177,1,44,1183,1, -47,1184,1,1303,2562, -16,0,278,1,1555, -2563,16,0,278,1, -50,1201,1,48,1190, -1,49,1196,1,51, -1206,1,63,1222,1, -305,1211,1,66,1228, +1479,2532,16,0,596, +1,1731,2533,16,0, +596,1,1989,916,1, +1990,2534,16,0,596, +1,236,2535,16,0, +596,1,1756,2536,16, +0,596,1,28,2537, +19,629,1,28,2538, +5,60,1,328,1302, +1,223,1533,1,1096, +1312,1,118,1355,1, +883,1397,1,525,1216, +1,1001,1588,1,130, +1414,1,459,1688,1, +1114,1343,1,352,1349, +1,447,1511,1,464, +1683,1,1011,1102,1, +1013,1258,1,242,1578, +1,143,1419,1,40, +1177,1,41,1659,1, +42,1662,1,479,1559, +1,44,1183,1,481, +1646,1,373,1409,1, +47,1184,1,157,1443, +1,49,1196,1,50, +1201,1,48,1190,1, +379,1386,1,380,1391, +1,51,1206,1,476, +1543,1,371,1365,1, +478,1583,1,1048,1344, +1,375,1376,1,172, +1469,1,262,1119,1, +283,1172,1,63,1222, 1,67,1233,1,68, 1238,1,69,1243,1, -70,1248,1,73,2564, -16,0,278,1,74, -1253,1,328,1302,1, -1048,1344,1,82,2565, -16,0,278,1,1840, -2566,16,0,278,1, -1591,2567,16,0,278, -1,1341,2568,16,0, -278,1,1096,1312,1, -93,1318,1,352,1349, -1,107,2569,16,0, -278,1,1114,1343,1, -118,1355,1,1123,2570, -16,0,278,1,371, -1365,1,1628,2571,16, -0,278,1,375,1376, -1,1882,2572,16,0, -278,1,377,1381,1, -379,1386,1,380,1391, -1,883,2573,16,0, -278,1,373,1409,1, -130,1414,1,143,1419, -1,387,2574,16,0, -278,1,2664,2575,16, -0,278,1,1159,2576, -16,0,278,1,157, -1443,1,1413,2577,16, -0,278,1,1665,2578, -16,0,278,1,412, -2579,16,0,278,1, -1377,2580,16,0,278, -1,172,1469,1,1939, -2581,16,0,278,1, -437,2582,16,0,278, -1,188,1518,1,942, -1490,1,1195,2583,16, -0,278,1,1449,2584, -16,0,278,1,1701, -2585,16,0,278,1, -447,1511,1,205,2586, -16,0,278,1,827, -2587,16,0,278,1, -223,2588,16,0,278, -1,476,1543,1,477, -1549,1,1231,2589,16, -0,278,1,479,1559, -1,480,1564,1,1485, -2590,16,0,278,1, -1737,2591,16,0,278, -1,242,2592,16,0, -278,1,478,1583,1, -1001,1588,1,1002,1593, -1,30,2593,19,268, -1,30,2594,5,84, +66,1228,1,461,2539, +16,0,627,1,74, +1253,1,377,1381,1, +1002,1593,1,70,1248, +1,188,1518,1,82, +1280,1,305,1211,1, +477,1549,1,827,1331, +1,93,1318,1,480, +1564,1,205,1523,1, +942,1490,1,107,1338, +1,29,2540,19,280, +1,29,2541,5,84, 1,1011,1102,1,1012, -2595,16,0,266,1, +2542,16,0,278,1, 1013,1258,1,262,1119, -1,1267,2596,16,0, -266,1,515,2597,16, -0,266,1,1521,2598, -16,0,266,1,525, +1,1267,2543,16,0, +278,1,515,2544,16, +0,278,1,1521,2545, +16,0,278,1,525, 1216,1,283,1172,1, -2299,2599,16,0,266, -1,42,2600,16,0, -266,1,40,1177,1, +2299,2546,16,0,278, +1,42,2547,16,0, +278,1,40,1177,1, 44,1183,1,47,1184, -1,1303,2601,16,0, -266,1,1555,2602,16, -0,266,1,50,1201, +1,1303,2548,16,0, +278,1,1555,2549,16, +0,278,1,50,1201, 1,48,1190,1,49, 1196,1,51,1206,1, 63,1222,1,305,1211, 1,66,1228,1,67, 1233,1,68,1238,1, 69,1243,1,70,1248, -1,73,2603,16,0, -266,1,74,1253,1, +1,73,2550,16,0, +278,1,74,1253,1, 328,1302,1,1048,1344, -1,82,2604,16,0, -266,1,1840,2605,16, -0,266,1,1591,2606, -16,0,266,1,1341, -2607,16,0,266,1, -1096,1312,1,93,1318, -1,352,1349,1,107, -2608,16,0,266,1, -1114,1343,1,118,1355, -1,1123,2609,16,0, -266,1,371,1365,1, -1628,2610,16,0,266, -1,375,1376,1,1882, -2611,16,0,266,1, -377,1381,1,379,1386, -1,380,1391,1,883, -2612,16,0,266,1, -373,1409,1,130,1414, -1,143,1419,1,387, -2613,16,0,266,1, -2664,2614,16,0,266, -1,1159,2615,16,0, -266,1,157,1443,1, -1413,2616,16,0,266, -1,1665,2617,16,0, -266,1,412,2618,16, -0,266,1,1377,2619, -16,0,266,1,172, -1469,1,1939,2620,16, -0,266,1,437,2621, -16,0,266,1,188, -1518,1,942,1490,1, -1195,2622,16,0,266, -1,1449,2623,16,0, -266,1,1701,2624,16, -0,266,1,447,1511, -1,205,2625,16,0, -266,1,827,2626,16, -0,266,1,223,2627, -16,0,266,1,476, -1543,1,477,1549,1, -1231,2628,16,0,266, -1,479,1559,1,480, -1564,1,1485,2629,16, -0,266,1,1737,2630, -16,0,266,1,242, -2631,16,0,266,1, -478,1583,1,1001,1588, -1,1002,1593,1,31, -2632,19,253,1,31, -2633,5,84,1,1011, -1102,1,1012,2634,16, -0,251,1,1013,1258, -1,262,1119,1,1267, -2635,16,0,251,1, -515,2636,16,0,251, -1,1521,2637,16,0, -251,1,525,1216,1, -283,1172,1,2299,2638, -16,0,251,1,42, -2639,16,0,251,1, -40,1177,1,44,1183, -1,47,1184,1,1303, -2640,16,0,251,1, -1555,2641,16,0,251, -1,50,1201,1,48, -1190,1,49,1196,1, -51,1206,1,63,1222, -1,305,1211,1,66, -1228,1,67,1233,1, -68,1238,1,69,1243, -1,70,1248,1,73, -2642,16,0,251,1, -74,1253,1,328,1302, -1,1048,1344,1,82, -2643,16,0,251,1, -1840,2644,16,0,251, -1,1591,2645,16,0, -251,1,1341,2646,16, -0,251,1,1096,1312, -1,93,1318,1,352, -1349,1,107,2647,16, -0,251,1,1114,1343, -1,118,1355,1,1123, -2648,16,0,251,1, -371,1365,1,1628,2649, -16,0,251,1,375, -1376,1,1882,2650,16, -0,251,1,377,1381, -1,379,1386,1,380, -1391,1,883,2651,16, -0,251,1,373,1409, -1,130,1414,1,143, -2652,16,0,251,1, -387,2653,16,0,251, -1,2664,2654,16,0, -251,1,1159,2655,16, -0,251,1,157,2656, -16,0,251,1,1413, -2657,16,0,251,1, -1665,2658,16,0,251, -1,412,2659,16,0, -251,1,1377,2660,16, -0,251,1,172,1469, -1,1939,2661,16,0, -251,1,437,2662,16, -0,251,1,188,1518, +1,82,1280,1,1840, +2551,16,0,278,1, +1591,2552,16,0,278, +1,1341,2553,16,0, +278,1,1096,1312,1, +93,1318,1,352,1349, +1,107,1338,1,1114, +1343,1,118,1355,1, +1123,2554,16,0,278, +1,371,1365,1,1628, +2555,16,0,278,1, +375,1376,1,1882,2556, +16,0,278,1,377, +1381,1,379,1386,1, +380,1391,1,883,2557, +16,0,278,1,373, +1409,1,130,1414,1, +143,1419,1,387,2558, +16,0,278,1,2664, +2559,16,0,278,1, +1159,2560,16,0,278, +1,157,1443,1,1413, +2561,16,0,278,1, +1665,2562,16,0,278, +1,412,2563,16,0, +278,1,1377,2564,16, +0,278,1,172,1469, +1,1939,2565,16,0, +278,1,437,2566,16, +0,278,1,188,1518, 1,942,1490,1,1195, -2663,16,0,251,1, -1449,2664,16,0,251, -1,1701,2665,16,0, -251,1,447,1511,1, -205,2666,16,0,251, -1,827,2667,16,0, -251,1,223,2668,16, -0,251,1,476,1543, +2567,16,0,278,1, +1449,2568,16,0,278, +1,1701,2569,16,0, +278,1,447,1511,1, +205,2570,16,0,278, +1,827,2571,16,0, +278,1,223,2572,16, +0,278,1,476,1543, 1,477,1549,1,1231, -2669,16,0,251,1, +2573,16,0,278,1, 479,1559,1,480,1564, -1,1485,2670,16,0, -251,1,1737,2671,16, -0,251,1,242,2672, -16,0,251,1,478, +1,1485,2574,16,0, +278,1,1737,2575,16, +0,278,1,242,2576, +16,0,278,1,478, 1583,1,1001,1588,1, -1002,1593,1,32,2673, -19,246,1,32,2674, +1002,1593,1,30,2577, +19,268,1,30,2578, 5,84,1,1011,1102, -1,1012,2675,16,0, -244,1,1013,1258,1, -262,1119,1,1267,2676, -16,0,244,1,515, -2677,16,0,244,1, -1521,2678,16,0,244, +1,1012,2579,16,0, +266,1,1013,1258,1, +262,1119,1,1267,2580, +16,0,266,1,515, +2581,16,0,266,1, +1521,2582,16,0,266, 1,525,1216,1,283, -1172,1,2299,2679,16, -0,244,1,42,2680, -16,0,244,1,40, +1172,1,2299,2583,16, +0,266,1,42,2584, +16,0,266,1,40, 1177,1,44,1183,1, -47,1184,1,1303,2681, -16,0,244,1,1555, -2682,16,0,244,1, +47,1184,1,1303,2585, +16,0,266,1,1555, +2586,16,0,266,1, 50,1201,1,48,1190, 1,49,1196,1,51, 1206,1,63,1222,1, 305,1211,1,66,1228, 1,67,1233,1,68, 1238,1,69,1243,1, -70,1248,1,73,2683, -16,0,244,1,74, +70,1248,1,73,2587, +16,0,266,1,74, 1253,1,328,1302,1, -1048,1344,1,82,2684, -16,0,244,1,1840, -2685,16,0,244,1, -1591,2686,16,0,244, -1,1341,2687,16,0, -244,1,1096,1312,1, -93,1318,1,352,1349, -1,107,2688,16,0, -244,1,1114,1343,1, -118,1355,1,1123,2689, -16,0,244,1,371, -1365,1,1628,2690,16, -0,244,1,375,1376, -1,1882,2691,16,0, -244,1,377,1381,1, -379,1386,1,380,1391, -1,883,2692,16,0, -244,1,373,1409,1, -130,1414,1,143,2693, -16,0,244,1,387, -2694,16,0,244,1, -2664,2695,16,0,244, -1,1159,2696,16,0, -244,1,157,2697,16, -0,244,1,1413,2698, -16,0,244,1,1665, -2699,16,0,244,1, -412,2700,16,0,244, -1,1377,2701,16,0, -244,1,172,1469,1, -1939,2702,16,0,244, -1,437,2703,16,0, -244,1,188,1518,1, -942,1490,1,1195,2704, -16,0,244,1,1449, -2705,16,0,244,1, -1701,2706,16,0,244, -1,447,1511,1,205, -2707,16,0,244,1, -827,2708,16,0,244, -1,223,2709,16,0, -244,1,476,1543,1, -477,1549,1,1231,2710, -16,0,244,1,479, -1559,1,480,1564,1, -1485,2711,16,0,244, -1,1737,2712,16,0, -244,1,242,2713,16, -0,244,1,478,1583, -1,1001,1588,1,1002, -1593,1,33,2714,19, -332,1,33,2715,5, -84,1,1011,1102,1, -1012,2716,16,0,330, -1,1013,1258,1,262, -1119,1,1267,2717,16, -0,330,1,515,2718, -16,0,330,1,1521, -2719,16,0,330,1, -525,1216,1,283,1172, -1,2299,2720,16,0, -330,1,42,2721,16, -0,330,1,40,1177, -1,44,1183,1,47, -1184,1,1303,2722,16, -0,330,1,1555,2723, -16,0,330,1,50, -1201,1,48,1190,1, -49,1196,1,51,1206, -1,63,1222,1,305, -1211,1,66,1228,1, -67,1233,1,68,1238, -1,69,1243,1,70, -1248,1,73,2724,16, -0,330,1,74,1253, -1,328,1302,1,1048, -1344,1,82,2725,16, -0,330,1,1840,2726, -16,0,330,1,1591, -2727,16,0,330,1, -1341,2728,16,0,330, -1,1096,1312,1,93, -1318,1,352,1349,1, -107,2729,16,0,330, +1048,1344,1,82,1280, +1,1840,2588,16,0, +266,1,1591,2589,16, +0,266,1,1341,2590, +16,0,266,1,1096, +1312,1,93,1318,1, +352,1349,1,107,1338, 1,1114,1343,1,118, -1355,1,1123,2730,16, -0,330,1,371,1365, -1,1628,2731,16,0, -330,1,375,1376,1, -1882,2732,16,0,330, +1355,1,1123,2591,16, +0,266,1,371,1365, +1,1628,2592,16,0, +266,1,375,1376,1, +1882,2593,16,0,266, 1,377,1381,1,379, 1386,1,380,1391,1, -883,2733,16,0,330, +883,2594,16,0,266, 1,373,1409,1,130, 1414,1,143,1419,1, -387,2734,16,0,330, -1,2664,2735,16,0, -330,1,1159,2736,16, -0,330,1,157,1443, -1,1413,2737,16,0, -330,1,1665,2738,16, -0,330,1,412,2739, -16,0,330,1,1377, -2740,16,0,330,1, -172,1469,1,1939,2741, -16,0,330,1,437, -2742,16,0,330,1, +387,2595,16,0,266, +1,2664,2596,16,0, +266,1,1159,2597,16, +0,266,1,157,1443, +1,1413,2598,16,0, +266,1,1665,2599,16, +0,266,1,412,2600, +16,0,266,1,1377, +2601,16,0,266,1, +172,1469,1,1939,2602, +16,0,266,1,437, +2603,16,0,266,1, 188,1518,1,942,1490, -1,1195,2743,16,0, -330,1,1449,2744,16, -0,330,1,1701,2745, -16,0,330,1,447, -1511,1,205,2746,16, -0,330,1,827,2747, -16,0,330,1,223, -2748,16,0,330,1, +1,1195,2604,16,0, +266,1,1449,2605,16, +0,266,1,1701,2606, +16,0,266,1,447, +1511,1,205,2607,16, +0,266,1,827,2608, +16,0,266,1,223, +2609,16,0,266,1, 476,1543,1,477,1549, -1,1231,2749,16,0, -330,1,479,1559,1, -480,1564,1,1485,2750, -16,0,330,1,1737, -2751,16,0,330,1, -242,1578,1,478,1583, -1,1001,1588,1,1002, -1593,1,34,2752,19, -322,1,34,2753,5, -84,1,1011,1102,1, -1012,2754,16,0,320, -1,1013,1258,1,262, -1119,1,1267,2755,16, -0,320,1,515,2756, -16,0,320,1,1521, -2757,16,0,320,1, -525,1216,1,283,1172, -1,2299,2758,16,0, -320,1,42,2759,16, -0,320,1,40,1177, -1,44,1183,1,47, -1184,1,1303,2760,16, -0,320,1,1555,2761, -16,0,320,1,50, -1201,1,48,1190,1, -49,1196,1,51,1206, -1,63,1222,1,305, -1211,1,66,1228,1, -67,1233,1,68,1238, -1,69,1243,1,70, -1248,1,73,2762,16, -0,320,1,74,1253, -1,328,1302,1,1048, -1344,1,82,2763,16, -0,320,1,1840,2764, -16,0,320,1,1591, -2765,16,0,320,1, -1341,2766,16,0,320, +1,1231,2610,16,0, +266,1,479,1559,1, +480,1564,1,1485,2611, +16,0,266,1,1737, +2612,16,0,266,1, +242,2613,16,0,266, +1,478,1583,1,1001, +1588,1,1002,1593,1, +31,2614,19,253,1, +31,2615,5,84,1, +1011,1102,1,1012,2616, +16,0,251,1,1013, +1258,1,262,1119,1, +1267,2617,16,0,251, +1,515,2618,16,0, +251,1,1521,2619,16, +0,251,1,525,1216, +1,283,1172,1,2299, +2620,16,0,251,1, +42,2621,16,0,251, +1,40,1177,1,44, +1183,1,47,1184,1, +1303,2622,16,0,251, +1,1555,2623,16,0, +251,1,50,1201,1, +48,1190,1,49,1196, +1,51,1206,1,63, +1222,1,305,1211,1, +66,1228,1,67,1233, +1,68,1238,1,69, +1243,1,70,1248,1, +73,2624,16,0,251, +1,74,1253,1,328, +1302,1,1048,1344,1, +82,1280,1,1840,2625, +16,0,251,1,1591, +2626,16,0,251,1, +1341,2627,16,0,251, 1,1096,1312,1,93, 1318,1,352,1349,1, -107,2767,16,0,320, +107,1338,1,1114,1343, +1,118,1355,1,1123, +2628,16,0,251,1, +371,1365,1,1628,2629, +16,0,251,1,375, +1376,1,1882,2630,16, +0,251,1,377,1381, +1,379,1386,1,380, +1391,1,883,2631,16, +0,251,1,373,1409, +1,130,1414,1,143, +2632,16,0,251,1, +387,2633,16,0,251, +1,2664,2634,16,0, +251,1,1159,2635,16, +0,251,1,157,2636, +16,0,251,1,1413, +2637,16,0,251,1, +1665,2638,16,0,251, +1,412,2639,16,0, +251,1,1377,2640,16, +0,251,1,172,1469, +1,1939,2641,16,0, +251,1,437,2642,16, +0,251,1,188,1518, +1,942,1490,1,1195, +2643,16,0,251,1, +1449,2644,16,0,251, +1,1701,2645,16,0, +251,1,447,1511,1, +205,2646,16,0,251, +1,827,2647,16,0, +251,1,223,2648,16, +0,251,1,476,1543, +1,477,1549,1,1231, +2649,16,0,251,1, +479,1559,1,480,1564, +1,1485,2650,16,0, +251,1,1737,2651,16, +0,251,1,242,2652, +16,0,251,1,478, +1583,1,1001,1588,1, +1002,1593,1,32,2653, +19,246,1,32,2654, +5,84,1,1011,1102, +1,1012,2655,16,0, +244,1,1013,1258,1, +262,1119,1,1267,2656, +16,0,244,1,515, +2657,16,0,244,1, +1521,2658,16,0,244, +1,525,1216,1,283, +1172,1,2299,2659,16, +0,244,1,42,2660, +16,0,244,1,40, +1177,1,44,1183,1, +47,1184,1,1303,2661, +16,0,244,1,1555, +2662,16,0,244,1, +50,1201,1,48,1190, +1,49,1196,1,51, +1206,1,63,1222,1, +305,1211,1,66,1228, +1,67,1233,1,68, +1238,1,69,1243,1, +70,1248,1,73,2663, +16,0,244,1,74, +1253,1,328,1302,1, +1048,1344,1,82,1280, +1,1840,2664,16,0, +244,1,1591,2665,16, +0,244,1,1341,2666, +16,0,244,1,1096, +1312,1,93,1318,1, +352,1349,1,107,1338, 1,1114,1343,1,118, -1355,1,1123,2768,16, -0,320,1,371,1365, -1,1628,2769,16,0, -320,1,375,1376,1, -1882,2770,16,0,320, +1355,1,1123,2667,16, +0,244,1,371,1365, +1,1628,2668,16,0, +244,1,375,1376,1, +1882,2669,16,0,244, 1,377,1381,1,379, 1386,1,380,1391,1, -883,2771,16,0,320, +883,2670,16,0,244, 1,373,1409,1,130, -1414,1,143,1419,1, -387,2772,16,0,320, -1,2664,2773,16,0, -320,1,1159,2774,16, -0,320,1,157,1443, -1,1413,2775,16,0, -320,1,1665,2776,16, -0,320,1,412,2777, -16,0,320,1,1377, -2778,16,0,320,1, -172,1469,1,1939,2779, -16,0,320,1,437, -2780,16,0,320,1, -188,1518,1,942,1490, -1,1195,2781,16,0, -320,1,1449,2782,16, -0,320,1,1701,2783, -16,0,320,1,447, -1511,1,205,1523,1, -827,2784,16,0,320, -1,223,1533,1,476, -1543,1,477,1549,1, -1231,2785,16,0,320, -1,479,1559,1,480, -1564,1,1485,2786,16, -0,320,1,1737,2787, -16,0,320,1,242, -1578,1,478,1583,1, +1414,1,143,2671,16, +0,244,1,387,2672, +16,0,244,1,2664, +2673,16,0,244,1, +1159,2674,16,0,244, +1,157,2675,16,0, +244,1,1413,2676,16, +0,244,1,1665,2677, +16,0,244,1,412, +2678,16,0,244,1, +1377,2679,16,0,244, +1,172,1469,1,1939, +2680,16,0,244,1, +437,2681,16,0,244, +1,188,1518,1,942, +1490,1,1195,2682,16, +0,244,1,1449,2683, +16,0,244,1,1701, +2684,16,0,244,1, +447,1511,1,205,2685, +16,0,244,1,827, +2686,16,0,244,1, +223,2687,16,0,244, +1,476,1543,1,477, +1549,1,1231,2688,16, +0,244,1,479,1559, +1,480,1564,1,1485, +2689,16,0,244,1, +1737,2690,16,0,244, +1,242,2691,16,0, +244,1,478,1583,1, 1001,1588,1,1002,1593, -1,35,2788,19,311, -1,35,2789,5,84, +1,33,2692,19,332, +1,33,2693,5,84, 1,1011,1102,1,1012, -2790,16,0,309,1, +2694,16,0,330,1, 1013,1258,1,262,1119, -1,1267,2791,16,0, -309,1,515,2792,16, -0,309,1,1521,2793, -16,0,309,1,525, +1,1267,2695,16,0, +330,1,515,2696,16, +0,330,1,1521,2697, +16,0,330,1,525, 1216,1,283,1172,1, -2299,2794,16,0,309, -1,42,2795,16,0, -309,1,40,1177,1, +2299,2698,16,0,330, +1,42,2699,16,0, +330,1,40,1177,1, 44,1183,1,47,1184, -1,1303,2796,16,0, -309,1,1555,2797,16, -0,309,1,50,1201, +1,1303,2700,16,0, +330,1,1555,2701,16, +0,330,1,50,1201, 1,48,1190,1,49, 1196,1,51,1206,1, 63,1222,1,305,1211, 1,66,1228,1,67, 1233,1,68,1238,1, 69,1243,1,70,1248, -1,73,2798,16,0, -309,1,74,1253,1, +1,73,2702,16,0, +330,1,74,1253,1, 328,1302,1,1048,1344, -1,82,2799,16,0, -309,1,1840,2800,16, -0,309,1,1591,2801, -16,0,309,1,1341, -2802,16,0,309,1, -1096,1312,1,93,1318, -1,352,1349,1,107, -2803,16,0,309,1, -1114,1343,1,118,1355, -1,1123,2804,16,0, -309,1,371,1365,1, -1628,2805,16,0,309, -1,375,1376,1,1882, -2806,16,0,309,1, -377,1381,1,379,1386, -1,380,1391,1,883, -2807,16,0,309,1, -373,1409,1,130,1414, -1,143,1419,1,387, -2808,16,0,309,1, -2664,2809,16,0,309, -1,1159,2810,16,0, -309,1,157,1443,1, -1413,2811,16,0,309, -1,1665,2812,16,0, -309,1,412,2813,16, -0,309,1,1377,2814, -16,0,309,1,172, -1469,1,1939,2815,16, -0,309,1,437,2816, -16,0,309,1,188, -1518,1,942,1490,1, -1195,2817,16,0,309, -1,1449,2818,16,0, -309,1,1701,2819,16, -0,309,1,447,1511, -1,205,1523,1,827, -2820,16,0,309,1, -223,2821,16,0,309, +1,82,1280,1,1840, +2703,16,0,330,1, +1591,2704,16,0,330, +1,1341,2705,16,0, +330,1,1096,1312,1, +93,1318,1,352,1349, +1,107,1338,1,1114, +1343,1,118,1355,1, +1123,2706,16,0,330, +1,371,1365,1,1628, +2707,16,0,330,1, +375,1376,1,1882,2708, +16,0,330,1,377, +1381,1,379,1386,1, +380,1391,1,883,2709, +16,0,330,1,373, +1409,1,130,1414,1, +143,1419,1,387,2710, +16,0,330,1,2664, +2711,16,0,330,1, +1159,2712,16,0,330, +1,157,1443,1,1413, +2713,16,0,330,1, +1665,2714,16,0,330, +1,412,2715,16,0, +330,1,1377,2716,16, +0,330,1,172,1469, +1,1939,2717,16,0, +330,1,437,2718,16, +0,330,1,188,1518, +1,942,1490,1,1195, +2719,16,0,330,1, +1449,2720,16,0,330, +1,1701,2721,16,0, +330,1,447,1511,1, +205,2722,16,0,330, +1,827,2723,16,0, +330,1,223,2724,16, +0,330,1,476,1543, +1,477,1549,1,1231, +2725,16,0,330,1, +479,1559,1,480,1564, +1,1485,2726,16,0, +330,1,1737,2727,16, +0,330,1,242,1578, +1,478,1583,1,1001, +1588,1,1002,1593,1, +34,2728,19,322,1, +34,2729,5,84,1, +1011,1102,1,1012,2730, +16,0,320,1,1013, +1258,1,262,1119,1, +1267,2731,16,0,320, +1,515,2732,16,0, +320,1,1521,2733,16, +0,320,1,525,1216, +1,283,1172,1,2299, +2734,16,0,320,1, +42,2735,16,0,320, +1,40,1177,1,44, +1183,1,47,1184,1, +1303,2736,16,0,320, +1,1555,2737,16,0, +320,1,50,1201,1, +48,1190,1,49,1196, +1,51,1206,1,63, +1222,1,305,1211,1, +66,1228,1,67,1233, +1,68,1238,1,69, +1243,1,70,1248,1, +73,2738,16,0,320, +1,74,1253,1,328, +1302,1,1048,1344,1, +82,1280,1,1840,2739, +16,0,320,1,1591, +2740,16,0,320,1, +1341,2741,16,0,320, +1,1096,1312,1,93, +1318,1,352,1349,1, +107,1338,1,1114,1343, +1,118,1355,1,1123, +2742,16,0,320,1, +371,1365,1,1628,2743, +16,0,320,1,375, +1376,1,1882,2744,16, +0,320,1,377,1381, +1,379,1386,1,380, +1391,1,883,2745,16, +0,320,1,373,1409, +1,130,1414,1,143, +1419,1,387,2746,16, +0,320,1,2664,2747, +16,0,320,1,1159, +2748,16,0,320,1, +157,1443,1,1413,2749, +16,0,320,1,1665, +2750,16,0,320,1, +412,2751,16,0,320, +1,1377,2752,16,0, +320,1,172,1469,1, +1939,2753,16,0,320, +1,437,2754,16,0, +320,1,188,1518,1, +942,1490,1,1195,2755, +16,0,320,1,1449, +2756,16,0,320,1, +1701,2757,16,0,320, +1,447,1511,1,205, +1523,1,827,2758,16, +0,320,1,223,1533, 1,476,1543,1,477, -1549,1,1231,2822,16, -0,309,1,479,1559, +1549,1,1231,2759,16, +0,320,1,479,1559, 1,480,1564,1,1485, -2823,16,0,309,1, -1737,2824,16,0,309, +2760,16,0,320,1, +1737,2761,16,0,320, 1,242,1578,1,478, 1583,1,1001,1588,1, -1002,1593,1,36,2825, -19,216,1,36,2826, -5,94,1,256,2827, -16,0,214,1,1261, +1002,1593,1,35,2762, +19,311,1,35,2763, +5,84,1,1011,1102, +1,1012,2764,16,0, +309,1,1013,1258,1, +262,1119,1,1267,2765, +16,0,309,1,515, +2766,16,0,309,1, +1521,2767,16,0,309, +1,525,1216,1,283, +1172,1,2299,2768,16, +0,309,1,42,2769, +16,0,309,1,40, +1177,1,44,1183,1, +47,1184,1,1303,2770, +16,0,309,1,1555, +2771,16,0,309,1, +50,1201,1,48,1190, +1,49,1196,1,51, +1206,1,63,1222,1, +305,1211,1,66,1228, +1,67,1233,1,68, +1238,1,69,1243,1, +70,1248,1,73,2772, +16,0,309,1,74, +1253,1,328,1302,1, +1048,1344,1,82,1280, +1,1840,2773,16,0, +309,1,1591,2774,16, +0,309,1,1341,2775, +16,0,309,1,1096, +1312,1,93,1318,1, +352,1349,1,107,1338, +1,1114,1343,1,118, +1355,1,1123,2776,16, +0,309,1,371,1365, +1,1628,2777,16,0, +309,1,375,1376,1, +1882,2778,16,0,309, +1,377,1381,1,379, +1386,1,380,1391,1, +883,2779,16,0,309, +1,373,1409,1,130, +1414,1,143,1419,1, +387,2780,16,0,309, +1,2664,2781,16,0, +309,1,1159,2782,16, +0,309,1,157,1443, +1,1413,2783,16,0, +309,1,1665,2784,16, +0,309,1,412,2785, +16,0,309,1,1377, +2786,16,0,309,1, +172,1469,1,1939,2787, +16,0,309,1,437, +2788,16,0,309,1, +188,1518,1,942,1490, +1,1195,2789,16,0, +309,1,1449,2790,16, +0,309,1,1701,2791, +16,0,309,1,447, +1511,1,205,1523,1, +827,2792,16,0,309, +1,223,2793,16,0, +309,1,476,1543,1, +477,1549,1,1231,2794, +16,0,309,1,479, +1559,1,480,1564,1, +1485,2795,16,0,309, +1,1737,2796,16,0, +309,1,242,1578,1, +478,1583,1,1001,1588, +1,1002,1593,1,36, +2797,19,216,1,36, +2798,5,94,1,256, +2799,16,0,214,1, +1261,2800,16,0,214, +1,509,2801,16,0, +214,1,1515,2802,16, +0,214,1,2021,718, +1,1775,2803,16,0, +214,1,2029,725,1, +2030,731,1,2031,736, +1,2032,741,1,2033, +746,1,277,2804,16, +0,214,1,2035,752, +1,2037,757,1,2039, +762,1,32,2805,16, +0,214,1,2041,768, +1,2293,2806,16,0, +214,1,2043,774,1, +2045,779,1,41,2807, +16,0,214,1,1297, +2808,16,0,214,1, +43,2809,16,0,214, +1,1803,787,1,1804, +2810,16,0,214,1, +299,2811,16,0,214, +1,52,2812,16,0, +214,1,2318,2813,16, +0,214,1,2075,2814, +16,0,214,1,1574, +799,1,71,2815,16, +0,214,1,76,2816, +16,0,214,1,1834, +2817,16,0,214,1, +2337,2818,16,0,214, +1,79,2819,16,0, +214,1,1335,2820,16, +0,214,1,322,2821, +16,0,214,1,85, +2822,16,0,214,1, +89,2823,16,0,214, +1,346,2824,16,0, +214,1,2105,814,1, +2106,2825,16,0,214, +1,97,2826,16,0, +214,1,1860,821,1, +2364,827,1,102,2827, +16,0,214,1,112, 2828,16,0,214,1, -509,2829,16,0,214, -1,1515,2830,16,0, -214,1,2021,718,1, -1775,2831,16,0,214, -1,2029,725,1,2030, -731,1,2031,736,1, -2032,741,1,2033,746, -1,277,2832,16,0, -214,1,2035,752,1, -2037,757,1,2039,762, -1,32,2833,16,0, -214,1,2041,768,1, -2293,2834,16,0,214, -1,2043,774,1,2045, -779,1,41,2835,16, -0,214,1,1297,2836, -16,0,214,1,43, +1117,2829,16,0,214, +1,1873,835,1,1876, +2830,16,0,214,1, +124,2831,16,0,214, +1,2136,842,1,381, +2832,16,0,214,1, +525,2833,16,0,214, +1,137,2834,16,0, +214,1,1901,2835,16, +0,214,1,2658,2836, +16,0,214,1,1153, 2837,16,0,214,1, -1803,787,1,1804,2838, -16,0,214,1,299, -2839,16,0,214,1, -52,2840,16,0,214, -1,2318,2841,16,0, -214,1,2075,2842,16, -0,214,1,1574,799, -1,71,2843,16,0, -214,1,76,2844,16, -0,214,1,1834,2845, -16,0,214,1,2337, -2846,16,0,214,1, -79,2847,16,0,214, -1,1335,2848,16,0, -214,1,322,2849,16, -0,214,1,85,2850, -16,0,214,1,89, -2851,16,0,214,1, -346,2852,16,0,214, -1,2105,814,1,2106, -2853,16,0,214,1, -97,2854,16,0,214, -1,1860,821,1,2364, -827,1,102,2855,16, -0,214,1,112,2856, -16,0,214,1,1117, -2857,16,0,214,1, -1873,835,1,1876,2858, -16,0,214,1,124, +151,2838,16,0,214, +1,1407,2839,16,0, +214,1,1659,2840,16, +0,214,1,2413,2841, +16,0,214,1,406, +2842,16,0,214,1, +1371,2843,16,0,214, +1,166,2844,16,0, +214,1,1622,2845,16, +0,214,1,1931,861, +1,1933,2846,16,0, +214,1,431,2847,16, +0,214,1,1585,2848, +16,0,214,1,182, +2849,16,0,214,1, +1189,2850,16,0,214, +1,1443,2851,16,0, +214,1,1695,2852,16, +0,214,1,2198,2853, +16,0,214,1,447, +2854,16,0,214,1, +2458,876,1,2459,882, +1,1958,2855,16,0, +214,1,2462,889,1, +1657,894,1,2464,899, +1,199,2856,16,0, +214,1,459,2857,16, +0,214,1,462,2858, +16,0,214,1,217, 2859,16,0,214,1, -2136,842,1,381,2860, -16,0,214,1,525, +2227,908,1,1225,2860, +16,0,214,1,1479, 2861,16,0,214,1, -137,2862,16,0,214, -1,1901,2863,16,0, -214,1,2658,2864,16, -0,214,1,1153,2865, -16,0,214,1,151, -2866,16,0,214,1, -1407,2867,16,0,214, -1,1659,2868,16,0, -214,1,2413,2869,16, -0,214,1,406,2870, -16,0,214,1,1371, -2871,16,0,214,1, -166,2872,16,0,214, -1,1622,2873,16,0, -214,1,1931,861,1, -1933,2874,16,0,214, -1,431,2875,16,0, -214,1,1585,2876,16, -0,214,1,182,2877, -16,0,214,1,1189, -2878,16,0,214,1, -1443,2879,16,0,214, -1,1695,2880,16,0, -214,1,2198,2881,16, -0,214,1,447,2882, -16,0,214,1,2458, -876,1,2459,882,1, -1958,2883,16,0,214, -1,2462,889,1,1657, -894,1,2464,899,1, -199,2884,16,0,214, -1,459,2885,16,0, -214,1,462,2886,16, -0,214,1,217,2887, -16,0,214,1,2227, -908,1,1225,2888,16, -0,214,1,1479,2889, -16,0,214,1,1731, -2890,16,0,214,1, -1989,916,1,1990,2891, -16,0,214,1,236, -2892,16,0,214,1, -1756,2893,16,0,214, -1,37,2894,19,233, -1,37,2895,5,94, -1,256,2896,16,0, -231,1,1261,2897,16, -0,231,1,509,2898, -16,0,231,1,1515, -2899,16,0,231,1, -2021,718,1,1775,2900, -16,0,231,1,2029, -725,1,2030,731,1, -2031,736,1,2032,741, -1,2033,746,1,277, -2901,16,0,231,1, -2035,752,1,2037,757, -1,2039,762,1,32, -2902,16,0,231,1, -2041,768,1,2293,2903, -16,0,231,1,2043, -774,1,2045,779,1, -41,2904,16,0,231, -1,1297,2905,16,0, -231,1,43,2906,16, -0,231,1,1803,787, -1,1804,2907,16,0, -231,1,299,2908,16, -0,231,1,52,2909, -16,0,231,1,2318, -2910,16,0,231,1, -2075,2911,16,0,231, -1,1574,799,1,71, -2912,16,0,231,1, -76,2913,16,0,231, -1,1834,2914,16,0, -231,1,2337,2915,16, -0,231,1,79,2916, -16,0,231,1,1335, -2917,16,0,231,1, -322,2918,16,0,231, -1,85,2919,16,0, -231,1,89,2920,16, -0,231,1,346,2921, -16,0,231,1,2105, -814,1,2106,2922,16, -0,231,1,97,2923, -16,0,231,1,1860, -821,1,2364,827,1, -102,2924,16,0,231, -1,112,2925,16,0, -231,1,1117,2926,16, -0,231,1,1873,835, -1,1876,2927,16,0, -231,1,124,2928,16, -0,231,1,2136,842, -1,381,2929,16,0, -231,1,525,2930,16, -0,231,1,137,2931, -16,0,231,1,1901, -2932,16,0,231,1, -2658,2933,16,0,231, -1,1153,2934,16,0, -231,1,151,2935,16, -0,231,1,1407,2936, -16,0,231,1,1659, -2937,16,0,231,1, -2413,2938,16,0,231, -1,406,2939,16,0, -231,1,1371,2940,16, -0,231,1,166,2941, -16,0,231,1,1622, -2942,16,0,231,1, -1931,861,1,1933,2943, -16,0,231,1,431, -2944,16,0,231,1, -1585,2945,16,0,231, -1,182,2946,16,0, -231,1,1189,2947,16, -0,231,1,1443,2948, -16,0,231,1,1695, -2949,16,0,231,1, -2198,2950,16,0,231, -1,447,2951,16,0, -231,1,2458,876,1, -2459,882,1,1958,2952, -16,0,231,1,2462, -889,1,1657,894,1, -2464,899,1,199,2953, -16,0,231,1,459, -2954,16,0,231,1, -462,2955,16,0,231, -1,217,2956,16,0, -231,1,2227,908,1, -1225,2957,16,0,231, -1,1479,2958,16,0, -231,1,1731,2959,16, -0,231,1,1989,916, -1,1990,2960,16,0, -231,1,236,2961,16, -0,231,1,1756,2962, -16,0,231,1,38, -2963,19,230,1,38, -2964,5,84,1,1011, -1102,1,1012,2965,16, -0,228,1,1013,1258, -1,262,1119,1,1267, -2966,16,0,228,1, -515,2967,16,0,228, -1,1521,2968,16,0, -228,1,525,1216,1, -283,1172,1,2299,2969, -16,0,228,1,42, -2970,16,0,228,1, -40,1177,1,44,1183, -1,47,1184,1,1303, -2971,16,0,228,1, -1555,2972,16,0,228, -1,50,1201,1,48, -1190,1,49,1196,1, -51,1206,1,63,1222, -1,305,1211,1,66, -1228,1,67,1233,1, -68,1238,1,69,1243, -1,70,1248,1,73, -2973,16,0,228,1, -74,1253,1,328,1302, -1,1048,1344,1,82, -2974,16,0,228,1, -1840,2975,16,0,228, -1,1591,2976,16,0, -228,1,1341,2977,16, -0,228,1,1096,1312, -1,93,1318,1,352, -1349,1,107,2978,16, -0,228,1,1114,1343, +1731,2862,16,0,214, +1,1989,916,1,1990, +2863,16,0,214,1, +236,2864,16,0,214, +1,1756,2865,16,0, +214,1,37,2866,19, +233,1,37,2867,5, +94,1,256,2868,16, +0,231,1,1261,2869, +16,0,231,1,509, +2870,16,0,231,1, +1515,2871,16,0,231, +1,2021,718,1,1775, +2872,16,0,231,1, +2029,725,1,2030,731, +1,2031,736,1,2032, +741,1,2033,746,1, +277,2873,16,0,231, +1,2035,752,1,2037, +757,1,2039,762,1, +32,2874,16,0,231, +1,2041,768,1,2293, +2875,16,0,231,1, +2043,774,1,2045,779, +1,41,2876,16,0, +231,1,1297,2877,16, +0,231,1,43,2878, +16,0,231,1,1803, +787,1,1804,2879,16, +0,231,1,299,2880, +16,0,231,1,52, +2881,16,0,231,1, +2318,2882,16,0,231, +1,2075,2883,16,0, +231,1,1574,799,1, +71,2884,16,0,231, +1,76,2885,16,0, +231,1,1834,2886,16, +0,231,1,2337,2887, +16,0,231,1,79, +2888,16,0,231,1, +1335,2889,16,0,231, +1,322,2890,16,0, +231,1,85,2891,16, +0,231,1,89,2892, +16,0,231,1,346, +2893,16,0,231,1, +2105,814,1,2106,2894, +16,0,231,1,97, +2895,16,0,231,1, +1860,821,1,2364,827, +1,102,2896,16,0, +231,1,112,2897,16, +0,231,1,1117,2898, +16,0,231,1,1873, +835,1,1876,2899,16, +0,231,1,124,2900, +16,0,231,1,2136, +842,1,381,2901,16, +0,231,1,525,2902, +16,0,231,1,137, +2903,16,0,231,1, +1901,2904,16,0,231, +1,2658,2905,16,0, +231,1,1153,2906,16, +0,231,1,151,2907, +16,0,231,1,1407, +2908,16,0,231,1, +1659,2909,16,0,231, +1,2413,2910,16,0, +231,1,406,2911,16, +0,231,1,1371,2912, +16,0,231,1,166, +2913,16,0,231,1, +1622,2914,16,0,231, +1,1931,861,1,1933, +2915,16,0,231,1, +431,2916,16,0,231, +1,1585,2917,16,0, +231,1,182,2918,16, +0,231,1,1189,2919, +16,0,231,1,1443, +2920,16,0,231,1, +1695,2921,16,0,231, +1,2198,2922,16,0, +231,1,447,2923,16, +0,231,1,2458,876, +1,2459,882,1,1958, +2924,16,0,231,1, +2462,889,1,1657,894, +1,2464,899,1,199, +2925,16,0,231,1, +459,2926,16,0,231, +1,462,2927,16,0, +231,1,217,2928,16, +0,231,1,2227,908, +1,1225,2929,16,0, +231,1,1479,2930,16, +0,231,1,1731,2931, +16,0,231,1,1989, +916,1,1990,2932,16, +0,231,1,236,2933, +16,0,231,1,1756, +2934,16,0,231,1, +38,2935,19,230,1, +38,2936,5,84,1, +1011,1102,1,1012,2937, +16,0,228,1,1013, +1258,1,262,1119,1, +1267,2938,16,0,228, +1,515,2939,16,0, +228,1,1521,2940,16, +0,228,1,525,1216, +1,283,1172,1,2299, +2941,16,0,228,1, +42,2942,16,0,228, +1,40,1177,1,44, +1183,1,47,1184,1, +1303,2943,16,0,228, +1,1555,2944,16,0, +228,1,50,1201,1, +48,1190,1,49,1196, +1,51,1206,1,63, +1222,1,305,1211,1, +66,1228,1,67,1233, +1,68,1238,1,69, +1243,1,70,1248,1, +73,2945,16,0,228, +1,74,1253,1,328, +1302,1,1048,1344,1, +82,1280,1,1840,2946, +16,0,228,1,1591, +2947,16,0,228,1, +1341,2948,16,0,228, +1,1096,1312,1,93, +1318,1,352,1349,1, +107,1338,1,1114,1343, 1,118,1355,1,1123, -2979,16,0,228,1, -371,1365,1,1628,2980, +2949,16,0,228,1, +371,1365,1,1628,2950, 16,0,228,1,375, -1376,1,1882,2981,16, +1376,1,1882,2951,16, 0,228,1,377,1381, 1,379,1386,1,380, 1391,1,883,1397,1, 373,1409,1,130,1414, 1,143,1419,1,387, -2982,16,0,228,1, -2664,2983,16,0,228, -1,1159,2984,16,0, +2952,16,0,228,1, +2664,2953,16,0,228, +1,1159,2954,16,0, 228,1,157,1443,1, -1413,2985,16,0,228, -1,1665,2986,16,0, -228,1,412,2987,16, -0,228,1,1377,2988, +1413,2955,16,0,228, +1,1665,2956,16,0, +228,1,412,2957,16, +0,228,1,1377,2958, 16,0,228,1,172, -1469,1,1939,2989,16, -0,228,1,437,2990, +1469,1,1939,2959,16, +0,228,1,437,2960, 16,0,228,1,188, 1518,1,942,1490,1, -1195,2991,16,0,228, -1,1449,2992,16,0, -228,1,1701,2993,16, +1195,2961,16,0,228, +1,1449,2962,16,0, +228,1,1701,2963,16, 0,228,1,447,1511, 1,205,1523,1,827, 1331,1,223,1533,1, 476,1543,1,477,1549, -1,1231,2994,16,0, +1,1231,2964,16,0, 228,1,479,1559,1, -480,1564,1,1485,2995, +480,1564,1,1485,2965, 16,0,228,1,1737, -2996,16,0,228,1, +2966,16,0,228,1, 242,1578,1,478,1583, 1,1001,1588,1,1002, -1593,1,39,2997,19, -222,1,39,2998,5, +1593,1,39,2967,19, +222,1,39,2968,5, 84,1,1011,1102,1, -1012,2999,16,0,220, +1012,2969,16,0,220, 1,1013,1258,1,262, -1119,1,1267,3000,16, -0,220,1,515,3001, +1119,1,1267,2970,16, +0,220,1,515,2971, 16,0,220,1,1521, -3002,16,0,220,1, +2972,16,0,220,1, 525,1216,1,283,1172, -1,2299,3003,16,0, -220,1,42,3004,16, +1,2299,2973,16,0, +220,1,42,2974,16, 0,220,1,40,1177, 1,44,1183,1,47, -1184,1,1303,3005,16, -0,220,1,1555,3006, +1184,1,1303,2975,16, +0,220,1,1555,2976, 16,0,220,1,50, 1201,1,48,1190,1, 49,1196,1,51,1206, @@ -8046,230 +8028,276 @@ public yyLSLSyntax 1211,1,66,1228,1, 67,1233,1,68,1238, 1,69,1243,1,70, -1248,1,73,3007,16, +1248,1,73,2977,16, 0,220,1,74,1253, 1,328,1302,1,1048, -1344,1,82,3008,16, -0,220,1,1840,3009, -16,0,220,1,1591, -3010,16,0,220,1, -1341,3011,16,0,220, -1,1096,1312,1,93, -1318,1,352,1349,1, -107,3012,16,0,220, -1,1114,1343,1,118, -1355,1,1123,3013,16, -0,220,1,371,1365, -1,1628,3014,16,0, -220,1,375,1376,1, -1882,3015,16,0,220, -1,377,1381,1,379, -1386,1,380,1391,1, -883,1397,1,373,1409, -1,130,1414,1,143, -1419,1,387,3016,16, -0,220,1,2664,3017, -16,0,220,1,1159, -3018,16,0,220,1, -157,1443,1,1413,3019, -16,0,220,1,1665, -3020,16,0,220,1, -412,3021,16,0,220, -1,1377,3022,16,0, -220,1,172,1469,1, -1939,3023,16,0,220, -1,437,3024,16,0, -220,1,188,1518,1, -942,1490,1,1195,3025, -16,0,220,1,1449, -3026,16,0,220,1, -1701,3027,16,0,220, -1,447,1511,1,205, -1523,1,827,1331,1, -223,1533,1,476,1543, -1,477,1549,1,1231, -3028,16,0,220,1, -479,1559,1,480,1564, -1,1485,3029,16,0, -220,1,1737,3030,16, -0,220,1,242,1578, -1,478,1583,1,1001, -1588,1,1002,1593,1, -40,3031,19,210,1, -40,3032,5,84,1, -1011,1102,1,1012,3033, -16,0,208,1,1013, -1258,1,262,1119,1, -1267,3034,16,0,208, -1,515,3035,16,0, -208,1,1521,3036,16, -0,208,1,525,1216, -1,283,1172,1,2299, -3037,16,0,208,1, -42,3038,16,0,208, -1,40,1177,1,44, -1183,1,47,1184,1, -1303,3039,16,0,208, -1,1555,3040,16,0, -208,1,50,1201,1, -48,1190,1,49,1196, -1,51,1206,1,63, -1222,1,305,1211,1, -66,1228,1,67,1233, -1,68,1238,1,69, -1243,1,70,1248,1, -73,3041,16,0,208, -1,74,1253,1,328, -1302,1,1048,1344,1, -82,3042,16,0,208, -1,1840,3043,16,0, -208,1,1591,3044,16, -0,208,1,1341,3045, -16,0,208,1,1096, -1312,1,93,1318,1, -352,1349,1,107,3046, -16,0,208,1,1114, -1343,1,118,3047,16, -0,208,1,1123,3048, -16,0,208,1,371, -1365,1,1628,3049,16, -0,208,1,375,1376, -1,1882,3050,16,0, -208,1,377,1381,1, -379,1386,1,380,1391, -1,883,3051,16,0, -208,1,373,1409,1, -130,3052,16,0,208, -1,143,3053,16,0, -208,1,387,3054,16, -0,208,1,2664,3055, -16,0,208,1,1159, -3056,16,0,208,1, -157,3057,16,0,208, -1,1413,3058,16,0, -208,1,1665,3059,16, -0,208,1,412,3060, -16,0,208,1,1377, -3061,16,0,208,1, -172,3062,16,0,208, -1,1939,3063,16,0, -208,1,437,3064,16, -0,208,1,188,3065, -16,0,208,1,942, -1490,1,1195,3066,16, -0,208,1,1449,3067, -16,0,208,1,1701, -3068,16,0,208,1, -447,1511,1,205,3069, -16,0,208,1,827, -3070,16,0,208,1, -223,3071,16,0,208, -1,476,1543,1,477, -1549,1,1231,3072,16, -0,208,1,479,1559, -1,480,1564,1,1485, -3073,16,0,208,1, -1737,3074,16,0,208, -1,242,3075,16,0, -208,1,478,1583,1, -1001,1588,1,1002,1593, -1,41,3076,19,172, -1,41,3077,5,84, -1,1011,1102,1,1012, -3078,16,0,170,1, -1013,1258,1,262,1119, -1,1267,3079,16,0, -170,1,515,3080,16, -0,170,1,1521,3081, -16,0,170,1,525, -1216,1,283,1172,1, -2299,3082,16,0,170, -1,42,3083,16,0, -170,1,40,1177,1, -44,1183,1,47,1184, -1,1303,3084,16,0, -170,1,1555,3085,16, -0,170,1,50,1201, -1,48,1190,1,49, -1196,1,51,1206,1, -63,1222,1,305,1211, -1,66,1228,1,67, -1233,1,68,1238,1, -69,1243,1,70,1248, -1,73,3086,16,0, -170,1,74,1253,1, -328,1302,1,1048,1344, -1,82,3087,16,0, -170,1,1840,3088,16, -0,170,1,1591,3089, +1344,1,82,1280,1, +1840,2978,16,0,220, +1,1591,2979,16,0, +220,1,1341,2980,16, +0,220,1,1096,1312, +1,93,1318,1,352, +1349,1,107,1338,1, +1114,1343,1,118,1355, +1,1123,2981,16,0, +220,1,371,1365,1, +1628,2982,16,0,220, +1,375,1376,1,1882, +2983,16,0,220,1, +377,1381,1,379,1386, +1,380,1391,1,883, +1397,1,373,1409,1, +130,1414,1,143,1419, +1,387,2984,16,0, +220,1,2664,2985,16, +0,220,1,1159,2986, +16,0,220,1,157, +1443,1,1413,2987,16, +0,220,1,1665,2988, +16,0,220,1,412, +2989,16,0,220,1, +1377,2990,16,0,220, +1,172,1469,1,1939, +2991,16,0,220,1, +437,2992,16,0,220, +1,188,1518,1,942, +1490,1,1195,2993,16, +0,220,1,1449,2994, +16,0,220,1,1701, +2995,16,0,220,1, +447,1511,1,205,1523, +1,827,1331,1,223, +1533,1,476,1543,1, +477,1549,1,1231,2996, +16,0,220,1,479, +1559,1,480,1564,1, +1485,2997,16,0,220, +1,1737,2998,16,0, +220,1,242,1578,1, +478,1583,1,1001,1588, +1,1002,1593,1,40, +2999,19,210,1,40, +3000,5,84,1,1011, +1102,1,1012,3001,16, +0,208,1,1013,1258, +1,262,1119,1,1267, +3002,16,0,208,1, +515,3003,16,0,208, +1,1521,3004,16,0, +208,1,525,1216,1, +283,1172,1,2299,3005, +16,0,208,1,42, +3006,16,0,208,1, +40,1177,1,44,1183, +1,47,1184,1,1303, +3007,16,0,208,1, +1555,3008,16,0,208, +1,50,1201,1,48, +1190,1,49,1196,1, +51,1206,1,63,1222, +1,305,1211,1,66, +1228,1,67,1233,1, +68,1238,1,69,1243, +1,70,1248,1,73, +3009,16,0,208,1, +74,1253,1,328,1302, +1,1048,1344,1,82, +1280,1,1840,3010,16, +0,208,1,1591,3011, +16,0,208,1,1341, +3012,16,0,208,1, +1096,1312,1,93,1318, +1,352,1349,1,107, +1338,1,1114,1343,1, +118,3013,16,0,208, +1,1123,3014,16,0, +208,1,371,1365,1, +1628,3015,16,0,208, +1,375,1376,1,1882, +3016,16,0,208,1, +377,1381,1,379,1386, +1,380,1391,1,883, +3017,16,0,208,1, +373,1409,1,130,3018, +16,0,208,1,143, +3019,16,0,208,1, +387,3020,16,0,208, +1,2664,3021,16,0, +208,1,1159,3022,16, +0,208,1,157,3023, +16,0,208,1,1413, +3024,16,0,208,1, +1665,3025,16,0,208, +1,412,3026,16,0, +208,1,1377,3027,16, +0,208,1,172,3028, +16,0,208,1,1939, +3029,16,0,208,1, +437,3030,16,0,208, +1,188,3031,16,0, +208,1,942,1490,1, +1195,3032,16,0,208, +1,1449,3033,16,0, +208,1,1701,3034,16, +0,208,1,447,1511, +1,205,3035,16,0, +208,1,827,3036,16, +0,208,1,223,3037, +16,0,208,1,476, +1543,1,477,1549,1, +1231,3038,16,0,208, +1,479,1559,1,480, +1564,1,1485,3039,16, +0,208,1,1737,3040, +16,0,208,1,242, +3041,16,0,208,1, +478,1583,1,1001,1588, +1,1002,1593,1,41, +3042,19,172,1,41, +3043,5,84,1,1011, +1102,1,1012,3044,16, +0,170,1,1013,1258, +1,262,1119,1,1267, +3045,16,0,170,1, +515,3046,16,0,170, +1,1521,3047,16,0, +170,1,525,1216,1, +283,1172,1,2299,3048, +16,0,170,1,42, +3049,16,0,170,1, +40,1177,1,44,1183, +1,47,1184,1,1303, +3050,16,0,170,1, +1555,3051,16,0,170, +1,50,1201,1,48, +1190,1,49,1196,1, +51,1206,1,63,1222, +1,305,1211,1,66, +1228,1,67,1233,1, +68,1238,1,69,1243, +1,70,1248,1,73, +3052,16,0,170,1, +74,1253,1,328,1302, +1,1048,1344,1,82, +1280,1,1840,3053,16, +0,170,1,1591,3054, 16,0,170,1,1341, -3090,16,0,170,1, +3055,16,0,170,1, 1096,1312,1,93,1318, 1,352,1349,1,107, -3091,16,0,170,1, -1114,1343,1,118,3092, -16,0,170,1,1123, -3093,16,0,170,1, -371,1365,1,1628,3094, -16,0,170,1,375, -1376,1,1882,3095,16, -0,170,1,377,1381, -1,379,1386,1,380, -1391,1,883,3096,16, -0,170,1,373,1409, -1,130,3097,16,0, -170,1,143,3098,16, -0,170,1,387,3099, -16,0,170,1,2664, -3100,16,0,170,1, -1159,3101,16,0,170, -1,157,3102,16,0, -170,1,1413,3103,16, -0,170,1,1665,3104, -16,0,170,1,412, -3105,16,0,170,1, -1377,3106,16,0,170, -1,172,3107,16,0, -170,1,1939,3108,16, -0,170,1,437,3109, -16,0,170,1,188, -3110,16,0,170,1, -942,1490,1,1195,3111, -16,0,170,1,1449, -3112,16,0,170,1, -1701,3113,16,0,170, -1,447,1511,1,205, -3114,16,0,170,1, -827,3115,16,0,170, -1,223,3116,16,0, -170,1,476,1543,1, -477,1549,1,1231,3117, -16,0,170,1,479, -1559,1,480,1564,1, -1485,3118,16,0,170, -1,1737,3119,16,0, -170,1,242,3120,16, -0,170,1,478,1583, -1,1001,1588,1,1002, -1593,1,42,3121,19, -394,1,42,3122,5, -38,1,1901,3123,16, -0,392,1,2075,3124, -16,0,392,1,1860, +1338,1,1114,1343,1, +118,3056,16,0,170, +1,1123,3057,16,0, +170,1,371,1365,1, +1628,3058,16,0,170, +1,375,1376,1,1882, +3059,16,0,170,1, +377,1381,1,379,1386, +1,380,1391,1,883, +3060,16,0,170,1, +373,1409,1,130,3061, +16,0,170,1,143, +3062,16,0,170,1, +387,3063,16,0,170, +1,2664,3064,16,0, +170,1,1159,3065,16, +0,170,1,157,3066, +16,0,170,1,1413, +3067,16,0,170,1, +1665,3068,16,0,170, +1,412,3069,16,0, +170,1,1377,3070,16, +0,170,1,172,3071, +16,0,170,1,1939, +3072,16,0,170,1, +437,3073,16,0,170, +1,188,3074,16,0, +170,1,942,1490,1, +1195,3075,16,0,170, +1,1449,3076,16,0, +170,1,1701,3077,16, +0,170,1,447,1511, +1,205,3078,16,0, +170,1,827,3079,16, +0,170,1,223,3080, +16,0,170,1,476, +1543,1,477,1549,1, +1231,3081,16,0,170, +1,479,1559,1,480, +1564,1,1485,3082,16, +0,170,1,1737,3083, +16,0,170,1,242, +3084,16,0,170,1, +478,1583,1,1001,1588, +1,1002,1593,1,42, +3085,19,394,1,42, +3086,5,38,1,1901, +3087,16,0,392,1, +2075,3088,16,0,392, +1,1860,821,1,1803, +787,1,1804,3089,16, +0,392,1,2413,3090, +16,0,392,1,2198, +3091,16,0,392,1, +1873,835,1,1657,894, +1,1989,916,1,1990, +3092,16,0,392,1, +1775,3093,16,0,392, +1,32,3094,16,0, +392,1,2105,814,1, +2106,3095,16,0,392, +1,2364,827,1,2227, +908,1,2337,3096,16, +0,392,1,2021,718, +1,2458,876,1,2459, +882,1,2462,889,1, +2136,842,1,2464,899, +1,2029,725,1,2030, +731,1,2031,736,1, +2032,741,1,2033,746, +1,2035,752,1,2037, +757,1,2039,762,1, +1931,861,1,2041,768, +1,2043,774,1,2045, +779,1,1574,799,1, +1958,3097,16,0,392, +1,43,3098,19,453, +1,43,3099,5,25, +1,2035,752,1,2037, +757,1,2039,762,1, +2041,768,1,2227,908, +1,2043,774,1,1657, +894,1,1860,821,1, +2136,842,1,2021,718, +1,2459,882,1,1574, +799,1,2105,3100,16, +0,578,1,1931,861, +1,1873,835,1,2031, +736,1,1803,787,1, +1989,3101,16,0,451, +1,2464,899,1,2029, +725,1,2030,731,1, +2364,827,1,2032,741, +1,2033,746,1,2045, +779,1,44,3102,19, +264,1,44,3103,5, +38,1,1901,3104,16, +0,262,1,2075,3105, +16,0,262,1,1860, 821,1,1803,787,1, -1804,3125,16,0,392, -1,2413,3126,16,0, -392,1,2198,3127,16, -0,392,1,1873,835, +1804,3106,16,0,262, +1,2413,3107,16,0, +262,1,2198,3108,16, +0,262,1,1873,835, 1,1657,894,1,1989, -916,1,1990,3128,16, -0,392,1,1775,3129, -16,0,392,1,32, -3130,16,0,392,1, -2105,814,1,2106,3131, -16,0,392,1,2364, +916,1,1990,3109,16, +0,262,1,1775,3110, +16,0,262,1,32, +3111,16,0,262,1, +2105,814,1,2106,3112, +16,0,262,1,2364, 827,1,2227,908,1, -2337,3132,16,0,392, +2337,3113,16,0,262, 1,2021,718,1,2458, 876,1,2459,882,1, 2462,889,1,2136,842, @@ -8281,76 +8309,59 @@ public yyLSLSyntax 2039,762,1,1931,861, 1,2041,768,1,2043, 774,1,2045,779,1, -1574,799,1,1958,3133, -16,0,392,1,43, -3134,19,453,1,43, -3135,5,25,1,2035, -752,1,2037,757,1, -2039,762,1,2041,768, -1,2227,908,1,2043, -774,1,1657,894,1, -1860,821,1,2136,842, -1,2021,718,1,2459, -882,1,1574,799,1, -2105,3136,16,0,578, -1,1931,861,1,1873, -835,1,2031,736,1, -1803,787,1,1989,3137, -16,0,451,1,2464, -899,1,2029,725,1, -2030,731,1,2364,827, -1,2032,741,1,2033, -746,1,2045,779,1, -44,3138,19,264,1, -44,3139,5,38,1, -1901,3140,16,0,262, -1,2075,3141,16,0, -262,1,1860,821,1, -1803,787,1,1804,3142, -16,0,262,1,2413, -3143,16,0,262,1, -2198,3144,16,0,262, -1,1873,835,1,1657, -894,1,1989,916,1, -1990,3145,16,0,262, -1,1775,3146,16,0, -262,1,32,3147,16, -0,262,1,2105,814, -1,2106,3148,16,0, -262,1,2364,827,1, -2227,908,1,2337,3149, -16,0,262,1,2021, -718,1,2458,876,1, -2459,882,1,2462,889, -1,2136,842,1,2464, -899,1,2029,725,1, -2030,731,1,2031,736, -1,2032,741,1,2033, -746,1,2035,752,1, -2037,757,1,2039,762, -1,1931,861,1,2041, -768,1,2043,774,1, -2045,779,1,1574,799, -1,1958,3150,16,0, -262,1,45,3151,19, -287,1,45,3152,5, -39,1,1901,3153,16, -0,315,1,2075,3154, -16,0,315,1,1860, +1574,799,1,1958,3114, +16,0,262,1,45, +3115,19,287,1,45, +3116,5,39,1,1901, +3117,16,0,315,1, +2075,3118,16,0,315, +1,1860,821,1,1803, +787,1,1804,3119,16, +0,315,1,2413,3120, +16,0,315,1,2198, +3121,16,0,315,1, +1873,835,1,1657,894, +1,1989,916,1,1990, +3122,16,0,315,1, +1775,3123,16,0,315, +1,32,3124,16,0, +315,1,2105,814,1, +2106,3125,16,0,315, +1,2364,827,1,2227, +908,1,2337,3126,16, +0,315,1,2021,718, +1,2458,876,1,2459, +882,1,2462,889,1, +2136,842,1,2464,899, +1,2029,725,1,2030, +731,1,2031,736,1, +2032,741,1,2033,746, +1,2035,752,1,2037, +757,1,2039,762,1, +1931,861,1,2041,768, +1,2043,774,1,2045, +779,1,1832,3127,16, +0,285,1,1574,799, +1,1958,3128,16,0, +315,1,46,3129,19, +671,1,46,3130,5, +38,1,1901,3131,16, +0,669,1,2075,3132, +16,0,669,1,1860, 821,1,1803,787,1, -1804,3155,16,0,315, -1,2413,3156,16,0, -315,1,2198,3157,16, -0,315,1,1873,835, +1804,3133,16,0,669, +1,2413,3134,16,0, +669,1,2198,3135,16, +0,669,1,1873,835, 1,1657,894,1,1989, -916,1,1990,3158,16, -0,315,1,1775,3159, -16,0,315,1,32, -3160,16,0,315,1, -2105,814,1,2106,3161, -16,0,315,1,2364, +916,1,1990,3136,16, +0,669,1,1775,3137, +16,0,669,1,32, +3138,16,0,669,1, +2105,814,1,2106,3139, +16,0,669,1,2364, 827,1,2227,908,1, -2337,3162,16,0,315, +2337,3140,16,0,669, 1,2021,718,1,2458, 876,1,2459,882,1, 2462,889,1,2136,842, @@ -8362,111 +8373,67 @@ public yyLSLSyntax 2039,762,1,1931,861, 1,2041,768,1,2043, 774,1,2045,779,1, -1832,3163,16,0,285, -1,1574,799,1,1958, -3164,16,0,315,1, -46,3165,19,671,1, -46,3166,5,38,1, -1901,3167,16,0,669, -1,2075,3168,16,0, -669,1,1860,821,1, -1803,787,1,1804,3169, -16,0,669,1,2413, -3170,16,0,669,1, -2198,3171,16,0,669, -1,1873,835,1,1657, -894,1,1989,916,1, -1990,3172,16,0,669, -1,1775,3173,16,0, -669,1,32,3174,16, -0,669,1,2105,814, -1,2106,3175,16,0, -669,1,2364,827,1, -2227,908,1,2337,3176, -16,0,669,1,2021, -718,1,2458,876,1, -2459,882,1,2462,889, -1,2136,842,1,2464, -899,1,2029,725,1, -2030,731,1,2031,736, -1,2032,741,1,2033, -746,1,2035,752,1, -2037,757,1,2039,762, -1,1931,861,1,2041, -768,1,2043,774,1, -2045,779,1,1574,799, -1,1958,3177,16,0, -669,1,47,3178,19, -466,1,47,3179,5, -19,1,0,3180,16, -0,464,1,2706,3181, -16,0,464,1,2634, -691,1,2636,3182,16, -0,464,1,2639,707, -1,2714,3183,17,3184, -15,3185,4,36,37, -0,71,0,108,0, -111,0,98,0,97, -0,108,0,68,0, -101,0,102,0,105, -0,110,0,105,0, -116,0,105,0,111, -0,110,0,115,0, -1,-1,1,5,3186, -20,3187,4,38,71, -0,108,0,111,0, -98,0,97,0,108, -0,68,0,101,0, -102,0,105,0,110, -0,105,0,116,0, -105,0,111,0,110, -0,115,0,95,0, -50,0,1,145,1, -3,1,3,1,2, -3188,22,1,4,1, -2558,697,1,2716,3189, -17,3190,15,3185,1, --1,1,5,3191,20, -3192,4,38,71,0, -108,0,111,0,98, -0,97,0,108,0, -68,0,101,0,102, -0,105,0,110,0, -105,0,116,0,105, -0,111,0,110,0, -115,0,95,0,49, -0,1,144,1,3, -1,2,1,1,3193, -22,1,3,1,2022, -3194,16,0,567,1, -2459,882,1,2715,3195, -17,3196,15,3185,1, --1,1,5,3197,20, -3198,4,38,71,0, +1574,799,1,1958,3141, +16,0,669,1,47, +3142,19,466,1,47, +3143,5,19,1,0, +3144,16,0,464,1, +2706,3145,16,0,464, +1,2634,691,1,2636, +3146,16,0,464,1, +2639,707,1,2714,3147, +17,3148,15,3149,4, +36,37,0,71,0, 108,0,111,0,98, 0,97,0,108,0, 68,0,101,0,102, 0,105,0,110,0, 105,0,116,0,105, 0,111,0,110,0, -115,0,95,0,51, -0,1,146,1,3, -1,2,1,1,3199, -22,1,5,1,2464, -899,1,2466,3200,17, -3201,15,3202,4,50, -37,0,71,0,108, -0,111,0,98,0, -97,0,108,0,70, -0,117,0,110,0, -99,0,116,0,105, -0,111,0,110,0, -68,0,101,0,102, -0,105,0,110,0, -105,0,116,0,105, -0,111,0,110,0, -1,-1,1,5,3203, -20,3204,4,52,71, +115,0,1,-1,1, +5,3150,20,3151,4, +38,71,0,108,0, +111,0,98,0,97, +0,108,0,68,0, +101,0,102,0,105, +0,110,0,105,0, +116,0,105,0,111, +0,110,0,115,0, +95,0,50,0,1, +145,1,3,1,3, +1,2,3152,22,1, +4,1,2558,697,1, +2716,3153,17,3154,15, +3149,1,-1,1,5, +3155,20,3156,4,38, +71,0,108,0,111, +0,98,0,97,0, +108,0,68,0,101, +0,102,0,105,0, +110,0,105,0,116, +0,105,0,111,0, +110,0,115,0,95, +0,49,0,1,144, +1,3,1,2,1, +1,3157,22,1,3, +1,2022,3158,16,0, +567,1,2459,882,1, +2715,3159,17,3160,15, +3149,1,-1,1,5, +3161,20,3162,4,38, +71,0,108,0,111, +0,98,0,97,0, +108,0,68,0,101, +0,102,0,105,0, +110,0,105,0,116, +0,105,0,111,0, +110,0,115,0,95, +0,51,0,1,146, +1,3,1,2,1, +1,3163,22,1,5, +1,2464,899,1,2466, +3164,17,3165,15,3166, +4,50,37,0,71, 0,108,0,111,0, 98,0,97,0,108, 0,70,0,117,0, @@ -8476,71 +8443,53 @@ public yyLSLSyntax 0,102,0,105,0, 110,0,105,0,116, 0,105,0,111,0, -110,0,95,0,50, -0,1,151,1,3, -1,7,1,6,3205, -22,1,10,1,2640, -685,1,2713,3206,17, -3207,15,3185,1,-1, -1,5,3208,20,3209, -4,38,71,0,108, -0,111,0,98,0, -97,0,108,0,68, +110,0,1,-1,1, +5,3167,20,3168,4, +52,71,0,108,0, +111,0,98,0,97, +0,108,0,70,0, +117,0,110,0,99, +0,116,0,105,0, +111,0,110,0,68, 0,101,0,102,0, 105,0,110,0,105, 0,116,0,105,0, -111,0,110,0,115, -0,95,0,52,0, -1,147,1,3,1, -3,1,2,3210,22, -1,6,1,2655,3211, -17,3212,15,3202,1, --1,1,5,3213,20, -3214,4,52,71,0, -108,0,111,0,98, -0,97,0,108,0, -70,0,117,0,110, -0,99,0,116,0, -105,0,111,0,110, +111,0,110,0,95, +0,50,0,1,151, +1,3,1,7,1, +6,3169,22,1,10, +1,2640,685,1,2713, +3170,17,3171,15,3149, +1,-1,1,5,3172, +20,3173,4,38,71, +0,108,0,111,0, +98,0,97,0,108, 0,68,0,101,0, 102,0,105,0,110, 0,105,0,116,0, 105,0,111,0,110, -0,95,0,49,0, -1,150,1,3,1, -6,1,5,3215,22, -1,9,1,2694,3216, -17,3217,15,3218,4, -52,37,0,71,0, -108,0,111,0,98, -0,97,0,108,0, -86,0,97,0,114, -0,105,0,97,0, -98,0,108,0,101, -0,68,0,101,0, -99,0,108,0,97, -0,114,0,97,0, +0,115,0,95,0, +52,0,1,147,1, +3,1,3,1,2, +3174,22,1,6,1, +2655,3175,17,3176,15, +3166,1,-1,1,5, +3177,20,3178,4,52, +71,0,108,0,111, +0,98,0,97,0, +108,0,70,0,117, +0,110,0,99,0, 116,0,105,0,111, -0,110,0,1,-1, -1,5,3219,20,3220, -4,54,71,0,108, -0,111,0,98,0, -97,0,108,0,86, -0,97,0,114,0, -105,0,97,0,98, -0,108,0,101,0, -68,0,101,0,99, -0,108,0,97,0, -114,0,97,0,116, -0,105,0,111,0, -110,0,95,0,49, -0,1,148,1,3, -1,3,1,2,3221, -22,1,7,1,2695, -3222,16,0,464,1, -2683,3223,17,3224,15, -3218,1,-1,1,5, -3225,20,3226,4,54, +0,110,0,68,0, +101,0,102,0,105, +0,110,0,105,0, +116,0,105,0,111, +0,110,0,95,0, +49,0,1,150,1, +3,1,6,1,5, +3179,22,1,9,1, +2694,3180,17,3181,15, +3182,4,52,37,0, 71,0,108,0,111, 0,98,0,97,0, 108,0,86,0,97, @@ -8551,103 +8500,101 @@ public yyLSLSyntax 0,97,0,114,0, 97,0,116,0,105, 0,111,0,110,0, -95,0,50,0,1, -149,1,3,1,5, -1,4,3227,22,1, -8,1,48,3228,19, -339,1,48,3229,5, -54,1,0,3230,16, -0,337,1,2075,3231, -16,0,495,1,1860, -821,1,1803,787,1, -1804,3232,16,0,495, -1,2413,3233,16,0, -495,1,2634,691,1, -1873,835,1,1657,894, -1,2639,707,1,2640, -685,1,1989,916,1, -1990,3234,16,0,495, -1,2459,882,1,1775, -3235,16,0,495,1, -32,3236,16,0,495, -1,2105,814,1,2106, -3237,16,0,495,1, -2466,3200,1,2655,3211, -1,2683,3223,1,2227, -908,1,2337,3238,16, -0,495,1,2558,697, -1,2694,3216,1,2695, -3239,16,0,337,1, -2021,718,1,2458,876, -1,1901,3240,16,0, -495,1,2462,889,1, -2136,842,1,2464,899, -1,2029,725,1,2030, -731,1,2031,736,1, -2032,741,1,2033,746, -1,2035,752,1,2364, -827,1,2715,3195,1, -2039,762,1,1931,861, -1,2041,768,1,2043, -774,1,2045,779,1, -2198,3241,16,0,495, -1,2706,3242,16,0, -337,1,2037,757,1, -2713,3206,1,2714,3183, -1,1574,799,1,2716, -3189,1,2636,3243,16, -0,337,1,1958,3244, -16,0,495,1,49, -3245,19,500,1,49, -3246,5,38,1,1901, -3247,16,0,498,1, -2075,3248,16,0,498, -1,1860,821,1,1803, -787,1,1804,3249,16, -0,498,1,2413,3250, -16,0,498,1,2198, -3251,16,0,498,1, -1873,835,1,1657,894, -1,1989,916,1,1990, -3252,16,0,498,1, -1775,3253,16,0,498, -1,32,3254,16,0, -498,1,2105,814,1, -2106,3255,16,0,498, -1,2364,827,1,2227, -908,1,2337,3256,16, -0,498,1,2021,718, -1,2458,876,1,2459, -882,1,2462,889,1, -2136,842,1,2464,899, -1,2029,725,1,2030, -731,1,2031,736,1, -2032,741,1,2033,746, -1,2035,752,1,2037, -757,1,2039,762,1, +1,-1,1,5,3183, +20,3184,4,54,71, +0,108,0,111,0, +98,0,97,0,108, +0,86,0,97,0, +114,0,105,0,97, +0,98,0,108,0, +101,0,68,0,101, +0,99,0,108,0, +97,0,114,0,97, +0,116,0,105,0, +111,0,110,0,95, +0,49,0,1,148, +1,3,1,3,1, +2,3185,22,1,7, +1,2695,3186,16,0, +464,1,2683,3187,17, +3188,15,3182,1,-1, +1,5,3189,20,3190, +4,54,71,0,108, +0,111,0,98,0, +97,0,108,0,86, +0,97,0,114,0, +105,0,97,0,98, +0,108,0,101,0, +68,0,101,0,99, +0,108,0,97,0, +114,0,97,0,116, +0,105,0,111,0, +110,0,95,0,50, +0,1,149,1,3, +1,5,1,4,3191, +22,1,8,1,48, +3192,19,339,1,48, +3193,5,54,1,0, +3194,16,0,337,1, +2075,3195,16,0,495, +1,1860,821,1,1803, +787,1,1804,3196,16, +0,495,1,2413,3197, +16,0,495,1,2634, +691,1,1873,835,1, +1657,894,1,2639,707, +1,2640,685,1,1989, +916,1,1990,3198,16, +0,495,1,2459,882, +1,1775,3199,16,0, +495,1,32,3200,16, +0,495,1,2105,814, +1,2106,3201,16,0, +495,1,2466,3164,1, +2655,3175,1,2683,3187, +1,2227,908,1,2337, +3202,16,0,495,1, +2558,697,1,2694,3180, +1,2695,3203,16,0, +337,1,2021,718,1, +2458,876,1,1901,3204, +16,0,495,1,2462, +889,1,2136,842,1, +2464,899,1,2029,725, +1,2030,731,1,2031, +736,1,2032,741,1, +2033,746,1,2035,752, +1,2364,827,1,2715, +3159,1,2039,762,1, 1931,861,1,2041,768, 1,2043,774,1,2045, -779,1,1574,799,1, -1958,3257,16,0,498, -1,50,3258,19,614, -1,50,3259,5,38, -1,1901,3260,16,0, -612,1,2075,3261,16, -0,612,1,1860,821, +779,1,2198,3205,16, +0,495,1,2706,3206, +16,0,337,1,2037, +757,1,2713,3170,1, +2714,3147,1,1574,799, +1,2716,3153,1,2636, +3207,16,0,337,1, +1958,3208,16,0,495, +1,49,3209,19,500, +1,49,3210,5,38, +1,1901,3211,16,0, +498,1,2075,3212,16, +0,498,1,1860,821, 1,1803,787,1,1804, -3262,16,0,612,1, -2413,3263,16,0,612, -1,2198,3264,16,0, -612,1,1873,835,1, +3213,16,0,498,1, +2413,3214,16,0,498, +1,2198,3215,16,0, +498,1,1873,835,1, 1657,894,1,1989,916, -1,1990,3265,16,0, -612,1,1775,3266,16, -0,612,1,32,3267, -16,0,612,1,2105, -814,1,2106,3268,16, -0,612,1,2364,827, +1,1990,3216,16,0, +498,1,1775,3217,16, +0,498,1,32,3218, +16,0,498,1,2105, +814,1,2106,3219,16, +0,498,1,2364,827, 1,2227,908,1,2337, -3269,16,0,612,1, +3220,16,0,498,1, 2021,718,1,2458,876, 1,2459,882,1,2462, 889,1,2136,842,1, @@ -8659,2076 +8606,2127 @@ public yyLSLSyntax 762,1,1931,861,1, 2041,768,1,2043,774, 1,2045,779,1,1574, -799,1,1958,3270,16, -0,612,1,51,3271, -19,127,1,51,3272, -5,53,1,0,3273, -16,0,125,1,2075, -3274,16,0,125,1, +799,1,1958,3221,16, +0,498,1,50,3222, +19,614,1,50,3223, +5,38,1,1901,3224, +16,0,612,1,2075, +3225,16,0,612,1, +1860,821,1,1803,787, +1,1804,3226,16,0, +612,1,2413,3227,16, +0,612,1,2198,3228, +16,0,612,1,1873, +835,1,1657,894,1, +1989,916,1,1990,3229, +16,0,612,1,1775, +3230,16,0,612,1, +32,3231,16,0,612, +1,2105,814,1,2106, +3232,16,0,612,1, +2364,827,1,2227,908, +1,2337,3233,16,0, +612,1,2021,718,1, +2458,876,1,2459,882, +1,2462,889,1,2136, +842,1,2464,899,1, +2029,725,1,2030,731, +1,2031,736,1,2032, +741,1,2033,746,1, +2035,752,1,2037,757, +1,2039,762,1,1931, +861,1,2041,768,1, +2043,774,1,2045,779, +1,1574,799,1,1958, +3234,16,0,612,1, +51,3235,19,127,1, +51,3236,5,53,1, +0,3237,16,0,125, +1,2075,3238,16,0, +125,1,1860,821,1, +1803,787,1,1804,3239, +16,0,125,1,10, +3240,16,0,125,1, +2413,3241,16,0,125, +1,2198,3242,16,0, +125,1,1873,835,1, +21,3243,16,0,125, +1,1657,894,1,2030, +731,1,2642,3244,16, +0,125,1,1989,916, +1,1990,3245,16,0, +125,1,2459,882,1, +1775,3246,16,0,125, +1,32,3247,16,0, +125,1,2105,814,1, +2106,3248,16,0,125, +1,2655,3175,1,2683, +3187,1,2227,908,1, +2337,3249,16,0,125, +1,52,3250,16,0, +125,1,2694,3180,1, +2695,3251,16,0,125, +1,2021,718,1,2458, +876,1,1901,3252,16, +0,125,1,2462,889, +1,2136,842,1,2464, +899,1,2029,725,1, +2466,3164,1,2031,736, +1,2032,741,1,2033, +746,1,2035,752,1, +2364,827,1,2715,3159, +1,2039,762,1,1931, +861,1,2041,768,1, +2043,774,1,2045,779, +1,2037,757,1,2713, +3170,1,2714,3147,1, +1574,799,1,2716,3153, +1,1958,3253,16,0, +125,1,2506,3254,16, +0,125,1,52,3255, +19,124,1,52,3256, +5,53,1,0,3257, +16,0,122,1,2075, +3258,16,0,122,1, 1860,821,1,1803,787, -1,1804,3275,16,0, -125,1,10,3276,16, -0,125,1,2413,3277, -16,0,125,1,2198, -3278,16,0,125,1, -1873,835,1,21,3279, -16,0,125,1,1657, +1,1804,3259,16,0, +122,1,10,3260,16, +0,122,1,2413,3261, +16,0,122,1,2198, +3262,16,0,122,1, +1873,835,1,21,3263, +16,0,122,1,1657, 894,1,2030,731,1, -2642,3280,16,0,125, +2642,3264,16,0,122, 1,1989,916,1,1990, -3281,16,0,125,1, -2459,882,1,1775,3282, -16,0,125,1,32, -3283,16,0,125,1, -2105,814,1,2106,3284, -16,0,125,1,2655, -3211,1,2683,3223,1, -2227,908,1,2337,3285, -16,0,125,1,52, -3286,16,0,125,1, -2694,3216,1,2695,3287, -16,0,125,1,2021, +3265,16,0,122,1, +2459,882,1,1775,3266, +16,0,122,1,32, +3267,16,0,122,1, +2105,814,1,2106,3268, +16,0,122,1,2655, +3175,1,2683,3187,1, +2227,908,1,2337,3269, +16,0,122,1,52, +3270,16,0,122,1, +2694,3180,1,2695,3271, +16,0,122,1,2021, 718,1,2458,876,1, -1901,3288,16,0,125, +1901,3272,16,0,122, 1,2462,889,1,2136, 842,1,2464,899,1, -2029,725,1,2466,3200, +2029,725,1,2466,3164, 1,2031,736,1,2032, 741,1,2033,746,1, 2035,752,1,2364,827, -1,2715,3195,1,2039, +1,2715,3159,1,2039, 762,1,1931,861,1, 2041,768,1,2043,774, 1,2045,779,1,2037, -757,1,2713,3206,1, -2714,3183,1,1574,799, -1,2716,3189,1,1958, -3289,16,0,125,1, -2506,3290,16,0,125, -1,52,3291,19,124, -1,52,3292,5,53, -1,0,3293,16,0, -122,1,2075,3294,16, -0,122,1,1860,821, +757,1,2713,3170,1, +2714,3147,1,1574,799, +1,2716,3153,1,1958, +3273,16,0,122,1, +2506,3274,16,0,122, +1,53,3275,19,121, +1,53,3276,5,53, +1,0,3277,16,0, +119,1,2075,3278,16, +0,119,1,1860,821, 1,1803,787,1,1804, -3295,16,0,122,1, -10,3296,16,0,122, -1,2413,3297,16,0, -122,1,2198,3298,16, -0,122,1,1873,835, -1,21,3299,16,0, -122,1,1657,894,1, -2030,731,1,2642,3300, -16,0,122,1,1989, -916,1,1990,3301,16, -0,122,1,2459,882, -1,1775,3302,16,0, -122,1,32,3303,16, -0,122,1,2105,814, -1,2106,3304,16,0, -122,1,2655,3211,1, -2683,3223,1,2227,908, -1,2337,3305,16,0, -122,1,52,3306,16, -0,122,1,2694,3216, -1,2695,3307,16,0, -122,1,2021,718,1, -2458,876,1,1901,3308, -16,0,122,1,2462, +3279,16,0,119,1, +10,3280,16,0,119, +1,2413,3281,16,0, +119,1,2198,3282,16, +0,119,1,1873,835, +1,21,3283,16,0, +119,1,1657,894,1, +2030,731,1,2642,3284, +16,0,119,1,1989, +916,1,1990,3285,16, +0,119,1,2459,882, +1,1775,3286,16,0, +119,1,32,3287,16, +0,119,1,2105,814, +1,2106,3288,16,0, +119,1,2655,3175,1, +2683,3187,1,2227,908, +1,2337,3289,16,0, +119,1,52,3290,16, +0,119,1,2694,3180, +1,2695,3291,16,0, +119,1,2021,718,1, +2458,876,1,1901,3292, +16,0,119,1,2462, 889,1,2136,842,1, 2464,899,1,2029,725, -1,2466,3200,1,2031, +1,2466,3164,1,2031, 736,1,2032,741,1, 2033,746,1,2035,752, 1,2364,827,1,2715, -3195,1,2039,762,1, +3159,1,2039,762,1, 1931,861,1,2041,768, 1,2043,774,1,2045, 779,1,2037,757,1, -2713,3206,1,2714,3183, +2713,3170,1,2714,3147, 1,1574,799,1,2716, -3189,1,1958,3309,16, -0,122,1,2506,3310, -16,0,122,1,53, -3311,19,121,1,53, -3312,5,53,1,0, -3313,16,0,119,1, -2075,3314,16,0,119, +3153,1,1958,3293,16, +0,119,1,2506,3294, +16,0,119,1,54, +3295,19,118,1,54, +3296,5,53,1,0, +3297,16,0,116,1, +2075,3298,16,0,116, 1,1860,821,1,1803, -787,1,1804,3315,16, -0,119,1,10,3316, -16,0,119,1,2413, -3317,16,0,119,1, -2198,3318,16,0,119, +787,1,1804,3299,16, +0,116,1,10,3300, +16,0,116,1,2413, +3301,16,0,116,1, +2198,3302,16,0,116, 1,1873,835,1,21, -3319,16,0,119,1, +3303,16,0,116,1, 1657,894,1,2030,731, -1,2642,3320,16,0, -119,1,1989,916,1, -1990,3321,16,0,119, +1,2642,3304,16,0, +116,1,1989,916,1, +1990,3305,16,0,116, 1,2459,882,1,1775, -3322,16,0,119,1, -32,3323,16,0,119, +3306,16,0,116,1, +32,3307,16,0,116, 1,2105,814,1,2106, -3324,16,0,119,1, -2655,3211,1,2683,3223, +3308,16,0,116,1, +2655,3175,1,2683,3187, 1,2227,908,1,2337, -3325,16,0,119,1, -52,3326,16,0,119, -1,2694,3216,1,2695, -3327,16,0,119,1, +3309,16,0,116,1, +52,3310,16,0,116, +1,2694,3180,1,2695, +3311,16,0,116,1, 2021,718,1,2458,876, -1,1901,3328,16,0, -119,1,2462,889,1, +1,1901,3312,16,0, +116,1,2462,889,1, 2136,842,1,2464,899, 1,2029,725,1,2466, -3200,1,2031,736,1, +3164,1,2031,736,1, 2032,741,1,2033,746, 1,2035,752,1,2364, -827,1,2715,3195,1, +827,1,2715,3159,1, 2039,762,1,1931,861, 1,2041,768,1,2043, 774,1,2045,779,1, -2037,757,1,2713,3206, -1,2714,3183,1,1574, -799,1,2716,3189,1, -1958,3329,16,0,119, -1,2506,3330,16,0, -119,1,54,3331,19, -118,1,54,3332,5, -53,1,0,3333,16, -0,116,1,2075,3334, -16,0,116,1,1860, +2037,757,1,2713,3170, +1,2714,3147,1,1574, +799,1,2716,3153,1, +1958,3313,16,0,116, +1,2506,3314,16,0, +116,1,55,3315,19, +115,1,55,3316,5, +53,1,0,3317,16, +0,113,1,2075,3318, +16,0,113,1,1860, 821,1,1803,787,1, -1804,3335,16,0,116, -1,10,3336,16,0, -116,1,2413,3337,16, -0,116,1,2198,3338, -16,0,116,1,1873, -835,1,21,3339,16, -0,116,1,1657,894, +1804,3319,16,0,113, +1,10,3320,16,0, +113,1,2413,3321,16, +0,113,1,2198,3322, +16,0,113,1,1873, +835,1,21,3323,16, +0,113,1,1657,894, 1,2030,731,1,2642, -3340,16,0,116,1, -1989,916,1,1990,3341, -16,0,116,1,2459, -882,1,1775,3342,16, -0,116,1,32,3343, -16,0,116,1,2105, -814,1,2106,3344,16, -0,116,1,2655,3211, -1,2683,3223,1,2227, -908,1,2337,3345,16, -0,116,1,52,3346, -16,0,116,1,2694, -3216,1,2695,3347,16, -0,116,1,2021,718, +3324,16,0,113,1, +1989,916,1,1990,3325, +16,0,113,1,2459, +882,1,1775,3326,16, +0,113,1,32,3327, +16,0,113,1,2105, +814,1,2106,3328,16, +0,113,1,2655,3175, +1,2683,3187,1,2227, +908,1,2337,3329,16, +0,113,1,52,3330, +16,0,113,1,2694, +3180,1,2695,3331,16, +0,113,1,2021,718, 1,2458,876,1,1901, -3348,16,0,116,1, +3332,16,0,113,1, 2462,889,1,2136,842, 1,2464,899,1,2029, -725,1,2466,3200,1, +725,1,2466,3164,1, 2031,736,1,2032,741, 1,2033,746,1,2035, 752,1,2364,827,1, -2715,3195,1,2039,762, +2715,3159,1,2039,762, 1,1931,861,1,2041, 768,1,2043,774,1, 2045,779,1,2037,757, -1,2713,3206,1,2714, -3183,1,1574,799,1, -2716,3189,1,1958,3349, -16,0,116,1,2506, -3350,16,0,116,1, -55,3351,19,115,1, -55,3352,5,53,1, -0,3353,16,0,113, -1,2075,3354,16,0, -113,1,1860,821,1, -1803,787,1,1804,3355, -16,0,113,1,10, -3356,16,0,113,1, -2413,3357,16,0,113, -1,2198,3358,16,0, -113,1,1873,835,1, -21,3359,16,0,113, +1,2713,3170,1,2714, +3147,1,1574,799,1, +2716,3153,1,1958,3333, +16,0,113,1,2506, +3334,16,0,113,1, +56,3335,19,112,1, +56,3336,5,53,1, +0,3337,16,0,110, +1,2075,3338,16,0, +110,1,1860,821,1, +1803,787,1,1804,3339, +16,0,110,1,10, +3340,16,0,110,1, +2413,3341,16,0,110, +1,2198,3342,16,0, +110,1,1873,835,1, +21,3343,16,0,110, 1,1657,894,1,2030, -731,1,2642,3360,16, -0,113,1,1989,916, -1,1990,3361,16,0, -113,1,2459,882,1, -1775,3362,16,0,113, -1,32,3363,16,0, -113,1,2105,814,1, -2106,3364,16,0,113, -1,2655,3211,1,2683, -3223,1,2227,908,1, -2337,3365,16,0,113, -1,52,3366,16,0, -113,1,2694,3216,1, -2695,3367,16,0,113, +731,1,2642,3344,16, +0,110,1,1989,916, +1,1990,3345,16,0, +110,1,2459,882,1, +1775,3346,16,0,110, +1,32,3347,16,0, +110,1,2105,814,1, +2106,3348,16,0,110, +1,2655,3175,1,2683, +3187,1,2227,908,1, +2337,3349,16,0,110, +1,52,3350,16,0, +110,1,2694,3180,1, +2695,3351,16,0,110, 1,2021,718,1,2458, -876,1,1901,3368,16, -0,113,1,2462,889, +876,1,1901,3352,16, +0,110,1,2462,889, 1,2136,842,1,2464, 899,1,2029,725,1, -2466,3200,1,2031,736, +2466,3164,1,2031,736, 1,2032,741,1,2033, 746,1,2035,752,1, -2364,827,1,2715,3195, +2364,827,1,2715,3159, 1,2039,762,1,1931, 861,1,2041,768,1, 2043,774,1,2045,779, 1,2037,757,1,2713, -3206,1,2714,3183,1, -1574,799,1,2716,3189, -1,1958,3369,16,0, -113,1,2506,3370,16, -0,113,1,56,3371, -19,112,1,56,3372, -5,53,1,0,3373, -16,0,110,1,2075, -3374,16,0,110,1, +3170,1,2714,3147,1, +1574,799,1,2716,3153, +1,1958,3353,16,0, +110,1,2506,3354,16, +0,110,1,57,3355, +19,109,1,57,3356, +5,53,1,0,3357, +16,0,107,1,2075, +3358,16,0,107,1, 1860,821,1,1803,787, -1,1804,3375,16,0, -110,1,10,3376,16, -0,110,1,2413,3377, -16,0,110,1,2198, -3378,16,0,110,1, -1873,835,1,21,3379, -16,0,110,1,1657, +1,1804,3359,16,0, +107,1,10,3360,16, +0,107,1,2413,3361, +16,0,107,1,2198, +3362,16,0,107,1, +1873,835,1,21,3363, +16,0,107,1,1657, 894,1,2030,731,1, -2642,3380,16,0,110, +2642,3364,16,0,107, 1,1989,916,1,1990, -3381,16,0,110,1, -2459,882,1,1775,3382, -16,0,110,1,32, -3383,16,0,110,1, -2105,814,1,2106,3384, -16,0,110,1,2655, -3211,1,2683,3223,1, -2227,908,1,2337,3385, -16,0,110,1,52, -3386,16,0,110,1, -2694,3216,1,2695,3387, -16,0,110,1,2021, +3365,16,0,107,1, +2459,882,1,1775,3366, +16,0,107,1,32, +3367,16,0,107,1, +2105,814,1,2106,3368, +16,0,107,1,2655, +3175,1,2683,3187,1, +2227,908,1,2337,3369, +16,0,107,1,52, +3370,16,0,107,1, +2694,3180,1,2695,3371, +16,0,107,1,2021, 718,1,2458,876,1, -1901,3388,16,0,110, +1901,3372,16,0,107, 1,2462,889,1,2136, 842,1,2464,899,1, -2029,725,1,2466,3200, +2029,725,1,2466,3164, 1,2031,736,1,2032, 741,1,2033,746,1, 2035,752,1,2364,827, -1,2715,3195,1,2039, +1,2715,3159,1,2039, 762,1,1931,861,1, 2041,768,1,2043,774, 1,2045,779,1,2037, -757,1,2713,3206,1, -2714,3183,1,1574,799, -1,2716,3189,1,1958, -3389,16,0,110,1, -2506,3390,16,0,110, -1,57,3391,19,109, -1,57,3392,5,53, -1,0,3393,16,0, -107,1,2075,3394,16, -0,107,1,1860,821, -1,1803,787,1,1804, -3395,16,0,107,1, -10,3396,16,0,107, -1,2413,3397,16,0, -107,1,2198,3398,16, -0,107,1,1873,835, -1,21,3399,16,0, -107,1,1657,894,1, -2030,731,1,2642,3400, -16,0,107,1,1989, -916,1,1990,3401,16, -0,107,1,2459,882, -1,1775,3402,16,0, -107,1,32,3403,16, -0,107,1,2105,814, -1,2106,3404,16,0, -107,1,2655,3211,1, -2683,3223,1,2227,908, -1,2337,3405,16,0, -107,1,52,3406,16, -0,107,1,2694,3216, -1,2695,3407,16,0, -107,1,2021,718,1, -2458,876,1,1901,3408, -16,0,107,1,2462, -889,1,2136,842,1, -2464,899,1,2029,725, -1,2466,3200,1,2031, -736,1,2032,741,1, -2033,746,1,2035,752, -1,2364,827,1,2715, -3195,1,2039,762,1, -1931,861,1,2041,768, -1,2043,774,1,2045, -779,1,2037,757,1, -2713,3206,1,2714,3183, -1,1574,799,1,2716, -3189,1,1958,3409,16, -0,107,1,2506,3410, -16,0,107,1,58, -3411,19,429,1,58, -3412,5,9,1,2519, +757,1,2713,3170,1, +2714,3147,1,1574,799, +1,2716,3153,1,1958, +3373,16,0,107,1, +2506,3374,16,0,107, +1,58,3375,19,429, +1,58,3376,5,9, +1,2519,1618,1,2557, +1627,1,2521,3377,16, +0,427,1,2559,1633, +1,2597,3378,16,0, +427,1,2561,3379,16, +0,427,1,2459,882, +1,2464,899,1,2470, +3380,16,0,427,1, +59,3381,19,426,1, +59,3382,5,9,1, +2519,1618,1,2557,1627, +1,2521,3383,16,0, +424,1,2559,1633,1, +2597,3384,16,0,424, +1,2561,3385,16,0, +424,1,2459,882,1, +2464,899,1,2470,3386, +16,0,424,1,60, +3387,19,423,1,60, +3388,5,9,1,2519, 1618,1,2557,1627,1, -2521,3413,16,0,427, +2521,3389,16,0,421, 1,2559,1633,1,2597, -3414,16,0,427,1, -2561,3415,16,0,427, +3390,16,0,421,1, +2561,3391,16,0,421, 1,2459,882,1,2464, -899,1,2470,3416,16, -0,427,1,59,3417, -19,426,1,59,3418, +899,1,2470,3392,16, +0,421,1,61,3393, +19,420,1,61,3394, 5,9,1,2519,1618, 1,2557,1627,1,2521, -3419,16,0,424,1, -2559,1633,1,2597,3420, -16,0,424,1,2561, -3421,16,0,424,1, +3395,16,0,418,1, +2559,1633,1,2597,3396, +16,0,418,1,2561, +3397,16,0,418,1, 2459,882,1,2464,899, -1,2470,3422,16,0, -424,1,60,3423,19, -423,1,60,3424,5, +1,2470,3398,16,0, +418,1,62,3399,19, +417,1,62,3400,5, 9,1,2519,1618,1, -2557,1627,1,2521,3425, -16,0,421,1,2559, -1633,1,2597,3426,16, -0,421,1,2561,3427, -16,0,421,1,2459, +2557,1627,1,2521,3401, +16,0,415,1,2559, +1633,1,2597,3402,16, +0,415,1,2561,3403, +16,0,415,1,2459, 882,1,2464,899,1, -2470,3428,16,0,421, -1,61,3429,19,420, -1,61,3430,5,9, +2470,3404,16,0,415, +1,63,3405,19,414, +1,63,3406,5,9, 1,2519,1618,1,2557, -1627,1,2521,3431,16, -0,418,1,2559,1633, -1,2597,3432,16,0, -418,1,2561,3433,16, -0,418,1,2459,882, +1627,1,2521,3407,16, +0,412,1,2559,1633, +1,2597,3408,16,0, +412,1,2561,3409,16, +0,412,1,2459,882, 1,2464,899,1,2470, -3434,16,0,418,1, -62,3435,19,417,1, -62,3436,5,9,1, +3410,16,0,412,1, +64,3411,19,653,1, +64,3412,5,9,1, 2519,1618,1,2557,1627, -1,2521,3437,16,0, -415,1,2559,1633,1, -2597,3438,16,0,415, -1,2561,3439,16,0, -415,1,2459,882,1, -2464,899,1,2470,3440, -16,0,415,1,63, -3441,19,414,1,63, -3442,5,9,1,2519, +1,2521,3413,16,0, +651,1,2559,1633,1, +2597,3414,16,0,651, +1,2561,3415,16,0, +651,1,2459,882,1, +2464,899,1,2470,3416, +16,0,651,1,65, +3417,19,410,1,65, +3418,5,9,1,2519, 1618,1,2557,1627,1, -2521,3443,16,0,412, +2521,3419,16,0,408, 1,2559,1633,1,2597, -3444,16,0,412,1, -2561,3445,16,0,412, +3420,16,0,408,1, +2561,3421,16,0,408, 1,2459,882,1,2464, -899,1,2470,3446,16, -0,412,1,64,3447, -19,653,1,64,3448, +899,1,2470,3422,16, +0,408,1,66,3423, +19,493,1,66,3424, 5,9,1,2519,1618, 1,2557,1627,1,2521, -3449,16,0,651,1, -2559,1633,1,2597,3450, -16,0,651,1,2561, -3451,16,0,651,1, +3425,16,0,491,1, +2559,1633,1,2597,3426, +16,0,491,1,2561, +3427,16,0,491,1, 2459,882,1,2464,899, -1,2470,3452,16,0, -651,1,65,3453,19, -410,1,65,3454,5, +1,2470,3428,16,0, +491,1,67,3429,19, +406,1,67,3430,5, 9,1,2519,1618,1, -2557,1627,1,2521,3455, -16,0,408,1,2559, -1633,1,2597,3456,16, -0,408,1,2561,3457, -16,0,408,1,2459, +2557,1627,1,2521,3431, +16,0,404,1,2559, +1633,1,2597,3432,16, +0,404,1,2561,3433, +16,0,404,1,2459, 882,1,2464,899,1, -2470,3458,16,0,408, -1,66,3459,19,493, -1,66,3460,5,9, +2470,3434,16,0,404, +1,68,3435,19,403, +1,68,3436,5,9, 1,2519,1618,1,2557, -1627,1,2521,3461,16, -0,491,1,2559,1633, -1,2597,3462,16,0, -491,1,2561,3463,16, -0,491,1,2459,882, +1627,1,2521,3437,16, +0,401,1,2559,1633, +1,2597,3438,16,0, +401,1,2561,3439,16, +0,401,1,2459,882, 1,2464,899,1,2470, -3464,16,0,491,1, -67,3465,19,406,1, -67,3466,5,9,1, +3440,16,0,401,1, +69,3441,19,486,1, +69,3442,5,9,1, 2519,1618,1,2557,1627, -1,2521,3467,16,0, -404,1,2559,1633,1, -2597,3468,16,0,404, -1,2561,3469,16,0, -404,1,2459,882,1, -2464,899,1,2470,3470, -16,0,404,1,68, -3471,19,403,1,68, -3472,5,9,1,2519, +1,2521,3443,16,0, +484,1,2559,1633,1, +2597,3444,16,0,484, +1,2561,3445,16,0, +484,1,2459,882,1, +2464,899,1,2470,3446, +16,0,484,1,70, +3447,19,399,1,70, +3448,5,9,1,2519, 1618,1,2557,1627,1, -2521,3473,16,0,401, +2521,3449,16,0,397, 1,2559,1633,1,2597, -3474,16,0,401,1, -2561,3475,16,0,401, +3450,16,0,397,1, +2561,3451,16,0,397, 1,2459,882,1,2464, -899,1,2470,3476,16, -0,401,1,69,3477, -19,486,1,69,3478, +899,1,2470,3452,16, +0,397,1,71,3453, +19,483,1,71,3454, 5,9,1,2519,1618, 1,2557,1627,1,2521, -3479,16,0,484,1, -2559,1633,1,2597,3480, -16,0,484,1,2561, -3481,16,0,484,1, +3455,16,0,481,1, +2559,1633,1,2597,3456, +16,0,481,1,2561, +3457,16,0,481,1, 2459,882,1,2464,899, -1,2470,3482,16,0, -484,1,70,3483,19, -399,1,70,3484,5, +1,2470,3458,16,0, +481,1,72,3459,19, +480,1,72,3460,5, 9,1,2519,1618,1, -2557,1627,1,2521,3485, -16,0,397,1,2559, -1633,1,2597,3486,16, -0,397,1,2561,3487, -16,0,397,1,2459, +2557,1627,1,2521,3461, +16,0,478,1,2559, +1633,1,2597,3462,16, +0,478,1,2561,3463, +16,0,478,1,2459, 882,1,2464,899,1, -2470,3488,16,0,397, -1,71,3489,19,483, -1,71,3490,5,9, +2470,3464,16,0,478, +1,73,3465,19,477, +1,73,3466,5,9, 1,2519,1618,1,2557, -1627,1,2521,3491,16, -0,481,1,2559,1633, -1,2597,3492,16,0, -481,1,2561,3493,16, -0,481,1,2459,882, +1627,1,2521,3467,16, +0,475,1,2559,1633, +1,2597,3468,16,0, +475,1,2561,3469,16, +0,475,1,2459,882, 1,2464,899,1,2470, -3494,16,0,481,1, -72,3495,19,480,1, -72,3496,5,9,1, +3470,16,0,475,1, +74,3471,19,474,1, +74,3472,5,9,1, 2519,1618,1,2557,1627, -1,2521,3497,16,0, -478,1,2559,1633,1, -2597,3498,16,0,478, -1,2561,3499,16,0, -478,1,2459,882,1, -2464,899,1,2470,3500, -16,0,478,1,73, -3501,19,477,1,73, -3502,5,9,1,2519, +1,2521,3473,16,0, +472,1,2559,1633,1, +2597,3474,16,0,472, +1,2561,3475,16,0, +472,1,2459,882,1, +2464,899,1,2470,3476, +16,0,472,1,75, +3477,19,390,1,75, +3478,5,9,1,2519, 1618,1,2557,1627,1, -2521,3503,16,0,475, +2521,3479,16,0,388, 1,2559,1633,1,2597, -3504,16,0,475,1, -2561,3505,16,0,475, +3480,16,0,388,1, +2561,3481,16,0,388, 1,2459,882,1,2464, -899,1,2470,3506,16, -0,475,1,74,3507, -19,474,1,74,3508, +899,1,2470,3482,16, +0,388,1,76,3483, +19,387,1,76,3484, 5,9,1,2519,1618, 1,2557,1627,1,2521, -3509,16,0,472,1, -2559,1633,1,2597,3510, -16,0,472,1,2561, -3511,16,0,472,1, +3485,16,0,385,1, +2559,1633,1,2597,3486, +16,0,385,1,2561, +3487,16,0,385,1, 2459,882,1,2464,899, -1,2470,3512,16,0, -472,1,75,3513,19, -390,1,75,3514,5, +1,2470,3488,16,0, +385,1,77,3489,19, +471,1,77,3490,5, 9,1,2519,1618,1, -2557,1627,1,2521,3515, -16,0,388,1,2559, -1633,1,2597,3516,16, -0,388,1,2561,3517, -16,0,388,1,2459, +2557,1627,1,2521,3491, +16,0,469,1,2559, +1633,1,2597,3492,16, +0,469,1,2561,3493, +16,0,469,1,2459, 882,1,2464,899,1, -2470,3518,16,0,388, -1,76,3519,19,387, -1,76,3520,5,9, +2470,3494,16,0,469, +1,78,3495,19,566, +1,78,3496,5,9, 1,2519,1618,1,2557, -1627,1,2521,3521,16, -0,385,1,2559,1633, -1,2597,3522,16,0, -385,1,2561,3523,16, -0,385,1,2459,882, +1627,1,2521,3497,16, +0,564,1,2559,1633, +1,2597,3498,16,0, +564,1,2561,3499,16, +0,564,1,2459,882, 1,2464,899,1,2470, -3524,16,0,385,1, -77,3525,19,471,1, -77,3526,5,9,1, +3500,16,0,564,1, +79,3501,19,380,1, +79,3502,5,9,1, 2519,1618,1,2557,1627, -1,2521,3527,16,0, -469,1,2559,1633,1, -2597,3528,16,0,469, -1,2561,3529,16,0, -469,1,2459,882,1, -2464,899,1,2470,3530, -16,0,469,1,78, -3531,19,566,1,78, -3532,5,9,1,2519, +1,2521,3503,16,0, +378,1,2559,1633,1, +2597,3504,16,0,378, +1,2561,3505,16,0, +378,1,2459,882,1, +2464,899,1,2470,3506, +16,0,378,1,80, +3507,19,377,1,80, +3508,5,9,1,2519, 1618,1,2557,1627,1, -2521,3533,16,0,564, +2521,3509,16,0,375, 1,2559,1633,1,2597, -3534,16,0,564,1, -2561,3535,16,0,564, +3510,16,0,375,1, +2561,3511,16,0,375, 1,2459,882,1,2464, -899,1,2470,3536,16, -0,564,1,79,3537, -19,380,1,79,3538, +899,1,2470,3512,16, +0,375,1,81,3513, +19,374,1,81,3514, 5,9,1,2519,1618, 1,2557,1627,1,2521, -3539,16,0,378,1, -2559,1633,1,2597,3540, -16,0,378,1,2561, -3541,16,0,378,1, +3515,16,0,372,1, +2559,1633,1,2597,3516, +16,0,372,1,2561, +3517,16,0,372,1, 2459,882,1,2464,899, -1,2470,3542,16,0, -378,1,80,3543,19, -377,1,80,3544,5, +1,2470,3518,16,0, +372,1,82,3519,19, +371,1,82,3520,5, 9,1,2519,1618,1, -2557,1627,1,2521,3545, -16,0,375,1,2559, -1633,1,2597,3546,16, -0,375,1,2561,3547, -16,0,375,1,2459, +2557,1627,1,2521,3521, +16,0,369,1,2559, +1633,1,2597,3522,16, +0,369,1,2561,3523, +16,0,369,1,2459, 882,1,2464,899,1, -2470,3548,16,0,375, -1,81,3549,19,374, -1,81,3550,5,9, +2470,3524,16,0,369, +1,83,3525,19,368, +1,83,3526,5,9, 1,2519,1618,1,2557, -1627,1,2521,3551,16, -0,372,1,2559,1633, -1,2597,3552,16,0, -372,1,2561,3553,16, -0,372,1,2459,882, +1627,1,2521,3527,16, +0,366,1,2559,1633, +1,2597,3528,16,0, +366,1,2561,3529,16, +0,366,1,2459,882, 1,2464,899,1,2470, -3554,16,0,372,1, -82,3555,19,371,1, -82,3556,5,9,1, +3530,16,0,366,1, +84,3531,19,365,1, +84,3532,5,9,1, 2519,1618,1,2557,1627, -1,2521,3557,16,0, -369,1,2559,1633,1, -2597,3558,16,0,369, -1,2561,3559,16,0, -369,1,2459,882,1, -2464,899,1,2470,3560, -16,0,369,1,83, -3561,19,368,1,83, -3562,5,9,1,2519, +1,2521,3533,16,0, +363,1,2559,1633,1, +2597,3534,16,0,363, +1,2561,3535,16,0, +363,1,2459,882,1, +2464,899,1,2470,3536, +16,0,363,1,85, +3537,19,362,1,85, +3538,5,9,1,2519, 1618,1,2557,1627,1, -2521,3563,16,0,366, +2521,3539,16,0,360, 1,2559,1633,1,2597, -3564,16,0,366,1, -2561,3565,16,0,366, +3540,16,0,360,1, +2561,3541,16,0,360, 1,2459,882,1,2464, -899,1,2470,3566,16, -0,366,1,84,3567, -19,365,1,84,3568, +899,1,2470,3542,16, +0,360,1,86,3543, +19,359,1,86,3544, 5,9,1,2519,1618, 1,2557,1627,1,2521, -3569,16,0,363,1, -2559,1633,1,2597,3570, -16,0,363,1,2561, -3571,16,0,363,1, +3545,16,0,357,1, +2559,1633,1,2597,3546, +16,0,357,1,2561, +3547,16,0,357,1, 2459,882,1,2464,899, -1,2470,3572,16,0, -363,1,85,3573,19, -362,1,85,3574,5, +1,2470,3548,16,0, +357,1,87,3549,19, +356,1,87,3550,5, 9,1,2519,1618,1, -2557,1627,1,2521,3575, -16,0,360,1,2559, -1633,1,2597,3576,16, -0,360,1,2561,3577, -16,0,360,1,2459, +2557,1627,1,2521,3551, +16,0,354,1,2559, +1633,1,2597,3552,16, +0,354,1,2561,3553, +16,0,354,1,2459, 882,1,2464,899,1, -2470,3578,16,0,360, -1,86,3579,19,359, -1,86,3580,5,9, +2470,3554,16,0,354, +1,88,3555,19,353, +1,88,3556,5,9, 1,2519,1618,1,2557, -1627,1,2521,3581,16, -0,357,1,2559,1633, -1,2597,3582,16,0, -357,1,2561,3583,16, -0,357,1,2459,882, +1627,1,2521,3557,16, +0,351,1,2559,1633, +1,2597,3558,16,0, +351,1,2561,3559,16, +0,351,1,2459,882, 1,2464,899,1,2470, -3584,16,0,357,1, -87,3585,19,356,1, -87,3586,5,9,1, +3560,16,0,351,1, +89,3561,19,347,1, +89,3562,5,9,1, 2519,1618,1,2557,1627, -1,2521,3587,16,0, -354,1,2559,1633,1, -2597,3588,16,0,354, -1,2561,3589,16,0, -354,1,2459,882,1, -2464,899,1,2470,3590, -16,0,354,1,88, -3591,19,353,1,88, -3592,5,9,1,2519, +1,2521,3563,16,0, +345,1,2559,1633,1, +2597,3564,16,0,345, +1,2561,3565,16,0, +345,1,2459,882,1, +2464,899,1,2470,3566, +16,0,345,1,90, +3567,19,350,1,90, +3568,5,9,1,2519, 1618,1,2557,1627,1, -2521,3593,16,0,351, +2521,3569,16,0,348, 1,2559,1633,1,2597, -3594,16,0,351,1, -2561,3595,16,0,351, +3570,16,0,348,1, +2561,3571,16,0,348, 1,2459,882,1,2464, -899,1,2470,3596,16, -0,351,1,89,3597, -19,347,1,89,3598, +899,1,2470,3572,16, +0,348,1,91,3573, +19,344,1,91,3574, 5,9,1,2519,1618, 1,2557,1627,1,2521, -3599,16,0,345,1, -2559,1633,1,2597,3600, -16,0,345,1,2561, -3601,16,0,345,1, +3575,16,0,342,1, +2559,1633,1,2597,3576, +16,0,342,1,2561, +3577,16,0,342,1, 2459,882,1,2464,899, -1,2470,3602,16,0, -345,1,90,3603,19, -350,1,90,3604,5, -9,1,2519,1618,1, -2557,1627,1,2521,3605, -16,0,348,1,2559, -1633,1,2597,3606,16, -0,348,1,2561,3607, -16,0,348,1,2459, -882,1,2464,899,1, -2470,3608,16,0,348, -1,91,3609,19,344, -1,91,3610,5,9, -1,2519,1618,1,2557, -1627,1,2521,3611,16, -0,342,1,2559,1633, -1,2597,3612,16,0, -342,1,2561,3613,16, -0,342,1,2459,882, -1,2464,899,1,2470, -3614,16,0,342,1, -92,3615,19,133,1, -92,3616,5,125,1, -0,3617,16,0,563, -1,1,1951,1,2, -1957,1,3,1962,1, -4,1967,1,5,1972, -1,6,1977,1,7, -1982,1,8,3618,16, -0,131,1,1515,3619, -16,0,165,1,2021, -718,1,2022,3620,16, -0,497,1,256,3621, -16,0,173,1,2025, -3622,16,0,501,1, -18,3623,16,0,138, -1,2027,3624,16,0, -505,1,2695,3625,16, -0,563,1,2029,725, +1,2470,3578,16,0, +342,1,92,3579,19, +133,1,92,3580,5, +125,1,0,3581,16, +0,563,1,1,1951, +1,2,1957,1,3, +1962,1,4,1967,1, +5,1972,1,6,1977, +1,7,1982,1,8, +3582,16,0,131,1, +1515,3583,16,0,165, +1,2021,718,1,2022, +3584,16,0,497,1, +256,3585,16,0,173, +1,2025,3586,16,0, +501,1,18,3587,16, +0,138,1,2027,3588, +16,0,505,1,2695, +3589,16,0,563,1, +2029,725,1,2030,731, +1,2031,736,1,2032, +741,1,2033,746,1, +277,3590,16,0,173, +1,2035,752,1,2037, +757,1,2039,762,1, +32,3591,16,0,165, +1,2041,768,1,2293, +3592,16,0,173,1, +2043,774,1,2045,779, +1,2713,3170,1,2715, +3159,1,41,3593,16, +0,173,1,1297,3594, +16,0,165,1,43, +3595,16,0,173,1, +46,3596,16,0,178, +1,1804,3597,16,0, +165,1,299,3598,16, +0,173,1,52,3599, +16,0,165,1,509, +3600,16,0,173,1, +2318,3601,16,0,165, +1,62,3602,16,0, +195,1,65,3603,16, +0,197,1,2075,3604, +16,0,165,1,1574, +799,1,71,3605,16, +0,173,1,1775,3606, +16,0,165,1,76, +3607,16,0,173,1, +1834,3608,16,0,165, +1,2337,3609,16,0, +165,1,79,3610,16, +0,173,1,1335,3611, +16,0,165,1,322, +3612,16,0,173,1, +85,3613,16,0,173, +1,1261,3614,16,0, +165,1,89,3615,16, +0,173,1,346,3616, +16,0,173,1,97, +3617,16,0,173,1, +2106,3618,16,0,165, +1,102,3619,16,0, +173,1,1860,821,1, +1803,787,1,2364,827, +1,1113,3620,16,0, +158,1,112,3621,16, +0,173,1,1117,3622, +16,0,165,1,1873, +835,1,1876,3623,16, +0,165,1,372,3624, +16,0,535,1,374, +3625,16,0,537,1, +124,3626,16,0,173, +1,376,3627,16,0, +539,1,378,3628,16, +0,541,1,2136,842, +1,381,3629,16,0, +173,1,525,3630,16, +0,173,1,137,3631, +16,0,173,1,1901, +3632,16,0,165,1, +2655,3175,1,2658,3633, +16,0,173,1,1153, +3634,16,0,165,1, +151,3635,16,0,173, +1,1407,3636,16,0, +165,1,1659,3637,16, +0,165,1,2413,3638, +16,0,165,1,406, +3639,16,0,173,1, +1371,3640,16,0,165, +1,2105,814,1,1657, +894,1,166,3641,16, +0,173,1,1622,3642, +16,0,173,1,2683, +3187,1,1931,861,1, +1933,3643,16,0,165, +1,431,3644,16,0, +173,1,1585,3645,16, +0,173,1,182,3646, +16,0,173,1,2694, +3180,1,1189,3647,16, +0,165,1,1443,3648, +16,0,165,1,1695, +3649,16,0,165,1, +2198,3650,16,0,165, +1,447,3651,16,0, +173,1,2458,876,1, +2459,882,1,1958,3652, +16,0,165,1,2462, +889,1,2714,3147,1, +2464,899,1,2716,3153, +1,2466,3164,1,459, +3653,16,0,173,1, +2468,3654,16,0,340, +1,462,3655,16,0, +173,1,199,3656,16, +0,173,1,217,3657, +16,0,173,1,2227, +908,1,1225,3658,16, +0,165,1,1479,3659, +16,0,165,1,1731, +3660,16,0,173,1, +1989,916,1,1990,3661, +16,0,165,1,236, +3662,16,0,173,1, +1756,3663,16,0,165, +1,93,3664,19,626, +1,93,3665,5,95, +1,256,3666,16,0, +624,1,1261,3667,16, +0,624,1,509,3668, +16,0,624,1,1515, +3669,16,0,624,1, +2021,718,1,1775,3670, +16,0,624,1,2029, +725,1,2030,731,1, +2031,736,1,2032,741, +1,2033,746,1,277, +3671,16,0,624,1, +2035,752,1,2037,757, +1,2039,762,1,32, +3672,16,0,624,1, +2041,768,1,2293,3673, +16,0,624,1,2043, +774,1,2045,779,1, +41,3674,16,0,624, +1,1297,3675,16,0, +624,1,43,3676,16, +0,624,1,1803,787, +1,1804,3677,16,0, +624,1,299,3678,16, +0,624,1,52,3679, +16,0,624,1,2318, +3680,16,0,624,1, +62,3681,16,0,624, +1,2075,3682,16,0, +624,1,1574,799,1, +71,3683,16,0,624, +1,76,3684,16,0, +624,1,1834,3685,16, +0,624,1,2337,3686, +16,0,624,1,79, +3687,16,0,624,1, +1335,3688,16,0,624, +1,322,3689,16,0, +624,1,85,3690,16, +0,624,1,89,3691, +16,0,624,1,346, +3692,16,0,624,1, +2105,814,1,2106,3693, +16,0,624,1,97, +3694,16,0,624,1, +1860,821,1,2364,827, +1,102,3695,16,0, +624,1,112,3696,16, +0,624,1,1117,3697, +16,0,624,1,1873, +835,1,1876,3698,16, +0,624,1,124,3699, +16,0,624,1,2136, +842,1,381,3700,16, +0,624,1,525,3701, +16,0,624,1,137, +3702,16,0,624,1, +1901,3703,16,0,624, +1,2658,3704,16,0, +624,1,1153,3705,16, +0,624,1,151,3706, +16,0,624,1,1407, +3707,16,0,624,1, +1659,3708,16,0,624, +1,2413,3709,16,0, +624,1,406,3710,16, +0,624,1,1371,3711, +16,0,624,1,166, +3712,16,0,624,1, +1622,3713,16,0,624, +1,1931,861,1,1933, +3714,16,0,624,1, +431,3715,16,0,624, +1,1585,3716,16,0, +624,1,182,3717,16, +0,624,1,1189,3718, +16,0,624,1,1443, +3719,16,0,624,1, +1695,3720,16,0,624, +1,2198,3721,16,0, +624,1,447,3722,16, +0,624,1,2458,876, +1,2459,882,1,1958, +3723,16,0,624,1, +2462,889,1,1657,894, +1,2464,899,1,199, +3724,16,0,624,1, +459,3725,16,0,624, +1,462,3726,16,0, +624,1,217,3727,16, +0,624,1,2227,908, +1,1225,3728,16,0, +624,1,1479,3729,16, +0,624,1,1731,3730, +16,0,624,1,1989, +916,1,1990,3731,16, +0,624,1,236,3732, +16,0,624,1,1756, +3733,16,0,624,1, +94,3734,19,623,1, +94,3735,5,95,1, +256,3736,16,0,621, +1,1261,3737,16,0, +621,1,509,3738,16, +0,621,1,1515,3739, +16,0,621,1,2021, +718,1,1775,3740,16, +0,621,1,2029,725, 1,2030,731,1,2031, 736,1,2032,741,1, -2033,746,1,277,3626, -16,0,173,1,2035, +2033,746,1,277,3741, +16,0,621,1,2035, 752,1,2037,757,1, -2039,762,1,32,3627, -16,0,165,1,2041, -768,1,2293,3628,16, -0,173,1,2043,774, -1,2045,779,1,2713, -3206,1,2715,3195,1, -41,3629,16,0,173, -1,1297,3630,16,0, -165,1,43,3631,16, -0,173,1,46,3632, -16,0,178,1,1804, -3633,16,0,165,1, -299,3634,16,0,173, -1,52,3635,16,0, -165,1,509,3636,16, -0,173,1,2318,3637, -16,0,165,1,62, -3638,16,0,195,1, -65,3639,16,0,197, -1,2075,3640,16,0, -165,1,1574,799,1, -71,3641,16,0,173, -1,1775,3642,16,0, -165,1,76,3643,16, -0,173,1,1834,3644, -16,0,165,1,2337, -3645,16,0,165,1, -79,3646,16,0,173, -1,1335,3647,16,0, -165,1,322,3648,16, -0,173,1,85,3649, -16,0,173,1,1261, -3650,16,0,165,1, -89,3651,16,0,173, -1,346,3652,16,0, -173,1,97,3653,16, -0,173,1,2106,3654, -16,0,165,1,102, -3655,16,0,173,1, -1860,821,1,1803,787, -1,2364,827,1,1113, -3656,16,0,158,1, -112,3657,16,0,173, -1,1117,3658,16,0, -165,1,1873,835,1, -1876,3659,16,0,165, -1,372,3660,16,0, -535,1,374,3661,16, -0,537,1,124,3662, -16,0,173,1,376, -3663,16,0,539,1, -378,3664,16,0,541, -1,2136,842,1,381, -3665,16,0,173,1, -525,3666,16,0,173, -1,137,3667,16,0, -173,1,1901,3668,16, -0,165,1,2655,3211, -1,2658,3669,16,0, -173,1,1153,3670,16, -0,165,1,151,3671, -16,0,173,1,1407, -3672,16,0,165,1, -1659,3673,16,0,165, -1,2413,3674,16,0, -165,1,406,3675,16, -0,173,1,1371,3676, -16,0,165,1,2105, -814,1,1657,894,1, -166,3677,16,0,173, -1,1622,3678,16,0, -173,1,2683,3223,1, -1931,861,1,1933,3679, -16,0,165,1,431, -3680,16,0,173,1, -1585,3681,16,0,173, -1,182,3682,16,0, -173,1,2694,3216,1, -1189,3683,16,0,165, -1,1443,3684,16,0, -165,1,1695,3685,16, -0,165,1,2198,3686, -16,0,165,1,447, -3687,16,0,173,1, -2458,876,1,2459,882, -1,1958,3688,16,0, -165,1,2462,889,1, -2714,3183,1,2464,899, -1,2716,3189,1,2466, -3200,1,459,3689,16, -0,173,1,2468,3690, -16,0,340,1,462, -3691,16,0,173,1, -199,3692,16,0,173, -1,217,3693,16,0, -173,1,2227,908,1, -1225,3694,16,0,165, -1,1479,3695,16,0, -165,1,1731,3696,16, -0,173,1,1989,916, -1,1990,3697,16,0, -165,1,236,3698,16, -0,173,1,1756,3699, -16,0,165,1,93, -3700,19,626,1,93, -3701,5,95,1,256, -3702,16,0,624,1, -1261,3703,16,0,624, -1,509,3704,16,0, -624,1,1515,3705,16, -0,624,1,2021,718, -1,1775,3706,16,0, -624,1,2029,725,1, +2039,762,1,32,3742, +16,0,621,1,2041, +768,1,2293,3743,16, +0,621,1,2043,774, +1,2045,779,1,41, +3744,16,0,621,1, +1297,3745,16,0,621, +1,43,3746,16,0, +621,1,1803,787,1, +1804,3747,16,0,621, +1,299,3748,16,0, +621,1,52,3749,16, +0,621,1,2318,3750, +16,0,621,1,62, +3751,16,0,621,1, +2075,3752,16,0,621, +1,1574,799,1,71, +3753,16,0,621,1, +76,3754,16,0,621, +1,1834,3755,16,0, +621,1,2337,3756,16, +0,621,1,79,3757, +16,0,621,1,1335, +3758,16,0,621,1, +322,3759,16,0,621, +1,85,3760,16,0, +621,1,89,3761,16, +0,621,1,346,3762, +16,0,621,1,2105, +814,1,2106,3763,16, +0,621,1,97,3764, +16,0,621,1,1860, +821,1,2364,827,1, +102,3765,16,0,621, +1,112,3766,16,0, +621,1,1117,3767,16, +0,621,1,1873,835, +1,1876,3768,16,0, +621,1,124,3769,16, +0,621,1,2136,842, +1,381,3770,16,0, +621,1,525,3771,16, +0,621,1,137,3772, +16,0,621,1,1901, +3773,16,0,621,1, +2658,3774,16,0,621, +1,1153,3775,16,0, +621,1,151,3776,16, +0,621,1,1407,3777, +16,0,621,1,1659, +3778,16,0,621,1, +2413,3779,16,0,621, +1,406,3780,16,0, +621,1,1371,3781,16, +0,621,1,166,3782, +16,0,621,1,1622, +3783,16,0,621,1, +1931,861,1,1933,3784, +16,0,621,1,431, +3785,16,0,621,1, +1585,3786,16,0,621, +1,182,3787,16,0, +621,1,1189,3788,16, +0,621,1,1443,3789, +16,0,621,1,1695, +3790,16,0,621,1, +2198,3791,16,0,621, +1,447,3792,16,0, +621,1,2458,876,1, +2459,882,1,1958,3793, +16,0,621,1,2462, +889,1,1657,894,1, +2464,899,1,199,3794, +16,0,621,1,459, +3795,16,0,621,1, +462,3796,16,0,621, +1,217,3797,16,0, +621,1,2227,908,1, +1225,3798,16,0,621, +1,1479,3799,16,0, +621,1,1731,3800,16, +0,621,1,1989,916, +1,1990,3801,16,0, +621,1,236,3802,16, +0,621,1,1756,3803, +16,0,621,1,95, +3804,19,620,1,95, +3805,5,95,1,256, +3806,16,0,618,1, +1261,3807,16,0,618, +1,509,3808,16,0, +618,1,1515,3809,16, +0,618,1,2021,718, +1,1775,3810,16,0, +618,1,2029,725,1, 2030,731,1,2031,736, 1,2032,741,1,2033, -746,1,277,3707,16, -0,624,1,2035,752, +746,1,277,3811,16, +0,618,1,2035,752, 1,2037,757,1,2039, -762,1,32,3708,16, -0,624,1,2041,768, -1,2293,3709,16,0, -624,1,2043,774,1, -2045,779,1,41,3710, -16,0,624,1,1297, -3711,16,0,624,1, -43,3712,16,0,624, +762,1,32,3812,16, +0,618,1,2041,768, +1,2293,3813,16,0, +618,1,2043,774,1, +2045,779,1,41,3814, +16,0,618,1,1297, +3815,16,0,618,1, +43,3816,16,0,618, 1,1803,787,1,1804, -3713,16,0,624,1, -299,3714,16,0,624, -1,52,3715,16,0, -624,1,2318,3716,16, -0,624,1,62,3717, -16,0,624,1,2075, -3718,16,0,624,1, -1574,799,1,71,3719, -16,0,624,1,76, -3720,16,0,624,1, -1834,3721,16,0,624, -1,2337,3722,16,0, -624,1,79,3723,16, -0,624,1,1335,3724, -16,0,624,1,322, -3725,16,0,624,1, -85,3726,16,0,624, -1,89,3727,16,0, -624,1,346,3728,16, -0,624,1,2105,814, -1,2106,3729,16,0, -624,1,97,3730,16, -0,624,1,1860,821, +3817,16,0,618,1, +299,3818,16,0,618, +1,52,3819,16,0, +618,1,2318,3820,16, +0,618,1,62,3821, +16,0,618,1,2075, +3822,16,0,618,1, +1574,799,1,71,3823, +16,0,618,1,76, +3824,16,0,618,1, +1834,3825,16,0,618, +1,2337,3826,16,0, +618,1,79,3827,16, +0,618,1,1335,3828, +16,0,618,1,322, +3829,16,0,618,1, +85,3830,16,0,618, +1,89,3831,16,0, +618,1,346,3832,16, +0,618,1,2105,814, +1,2106,3833,16,0, +618,1,97,3834,16, +0,618,1,1860,821, 1,2364,827,1,102, -3731,16,0,624,1, -112,3732,16,0,624, -1,1117,3733,16,0, -624,1,1873,835,1, -1876,3734,16,0,624, -1,124,3735,16,0, -624,1,2136,842,1, -381,3736,16,0,624, -1,525,3737,16,0, -624,1,137,3738,16, -0,624,1,1901,3739, -16,0,624,1,2658, -3740,16,0,624,1, -1153,3741,16,0,624, -1,151,3742,16,0, -624,1,1407,3743,16, -0,624,1,1659,3744, -16,0,624,1,2413, -3745,16,0,624,1, -406,3746,16,0,624, -1,1371,3747,16,0, -624,1,166,3748,16, -0,624,1,1622,3749, -16,0,624,1,1931, -861,1,1933,3750,16, -0,624,1,431,3751, -16,0,624,1,1585, -3752,16,0,624,1, -182,3753,16,0,624, -1,1189,3754,16,0, -624,1,1443,3755,16, -0,624,1,1695,3756, -16,0,624,1,2198, -3757,16,0,624,1, -447,3758,16,0,624, +3835,16,0,618,1, +112,3836,16,0,618, +1,1117,3837,16,0, +618,1,1873,835,1, +1876,3838,16,0,618, +1,124,3839,16,0, +618,1,2136,842,1, +381,3840,16,0,618, +1,525,3841,16,0, +618,1,137,3842,16, +0,618,1,1901,3843, +16,0,618,1,2658, +3844,16,0,618,1, +1153,3845,16,0,618, +1,151,3846,16,0, +618,1,1407,3847,16, +0,618,1,1659,3848, +16,0,618,1,2413, +3849,16,0,618,1, +406,3850,16,0,618, +1,1371,3851,16,0, +618,1,166,3852,16, +0,618,1,1622,3853, +16,0,618,1,1931, +861,1,1933,3854,16, +0,618,1,431,3855, +16,0,618,1,1585, +3856,16,0,618,1, +182,3857,16,0,618, +1,1189,3858,16,0, +618,1,1443,3859,16, +0,618,1,1695,3860, +16,0,618,1,2198, +3861,16,0,618,1, +447,3862,16,0,618, 1,2458,876,1,2459, -882,1,1958,3759,16, -0,624,1,2462,889, +882,1,1958,3863,16, +0,618,1,2462,889, 1,1657,894,1,2464, -899,1,199,3760,16, -0,624,1,459,3761, -16,0,624,1,462, -3762,16,0,624,1, -217,3763,16,0,624, +899,1,199,3864,16, +0,618,1,459,3865, +16,0,618,1,462, +3866,16,0,618,1, +217,3867,16,0,618, 1,2227,908,1,1225, -3764,16,0,624,1, -1479,3765,16,0,624, -1,1731,3766,16,0, -624,1,1989,916,1, -1990,3767,16,0,624, -1,236,3768,16,0, -624,1,1756,3769,16, -0,624,1,94,3770, -19,623,1,94,3771, -5,95,1,256,3772, -16,0,621,1,1261, -3773,16,0,621,1, -509,3774,16,0,621, -1,1515,3775,16,0, -621,1,2021,718,1, -1775,3776,16,0,621, -1,2029,725,1,2030, -731,1,2031,736,1, -2032,741,1,2033,746, -1,277,3777,16,0, -621,1,2035,752,1, -2037,757,1,2039,762, -1,32,3778,16,0, -621,1,2041,768,1, -2293,3779,16,0,621, -1,2043,774,1,2045, -779,1,41,3780,16, -0,621,1,1297,3781, -16,0,621,1,43, -3782,16,0,621,1, -1803,787,1,1804,3783, -16,0,621,1,299, -3784,16,0,621,1, -52,3785,16,0,621, -1,2318,3786,16,0, -621,1,62,3787,16, -0,621,1,2075,3788, -16,0,621,1,1574, -799,1,71,3789,16, -0,621,1,76,3790, -16,0,621,1,1834, -3791,16,0,621,1, -2337,3792,16,0,621, -1,79,3793,16,0, -621,1,1335,3794,16, -0,621,1,322,3795, -16,0,621,1,85, -3796,16,0,621,1, -89,3797,16,0,621, -1,346,3798,16,0, -621,1,2105,814,1, -2106,3799,16,0,621, -1,97,3800,16,0, -621,1,1860,821,1, -2364,827,1,102,3801, -16,0,621,1,112, -3802,16,0,621,1, -1117,3803,16,0,621, -1,1873,835,1,1876, -3804,16,0,621,1, -124,3805,16,0,621, -1,2136,842,1,381, -3806,16,0,621,1, -525,3807,16,0,621, -1,137,3808,16,0, -621,1,1901,3809,16, -0,621,1,2658,3810, -16,0,621,1,1153, -3811,16,0,621,1, -151,3812,16,0,621, -1,1407,3813,16,0, -621,1,1659,3814,16, -0,621,1,2413,3815, -16,0,621,1,406, -3816,16,0,621,1, -1371,3817,16,0,621, -1,166,3818,16,0, -621,1,1622,3819,16, -0,621,1,1931,861, -1,1933,3820,16,0, -621,1,431,3821,16, -0,621,1,1585,3822, -16,0,621,1,182, -3823,16,0,621,1, -1189,3824,16,0,621, -1,1443,3825,16,0, -621,1,1695,3826,16, -0,621,1,2198,3827, -16,0,621,1,447, -3828,16,0,621,1, -2458,876,1,2459,882, -1,1958,3829,16,0, -621,1,2462,889,1, -1657,894,1,2464,899, -1,199,3830,16,0, -621,1,459,3831,16, -0,621,1,462,3832, -16,0,621,1,217, -3833,16,0,621,1, -2227,908,1,1225,3834, -16,0,621,1,1479, -3835,16,0,621,1, -1731,3836,16,0,621, -1,1989,916,1,1990, -3837,16,0,621,1, -236,3838,16,0,621, -1,1756,3839,16,0, -621,1,95,3840,19, -620,1,95,3841,5, -95,1,256,3842,16, -0,618,1,1261,3843, -16,0,618,1,509, -3844,16,0,618,1, -1515,3845,16,0,618, -1,2021,718,1,1775, -3846,16,0,618,1, -2029,725,1,2030,731, -1,2031,736,1,2032, -741,1,2033,746,1, -277,3847,16,0,618, -1,2035,752,1,2037, -757,1,2039,762,1, -32,3848,16,0,618, -1,2041,768,1,2293, -3849,16,0,618,1, -2043,774,1,2045,779, -1,41,3850,16,0, -618,1,1297,3851,16, -0,618,1,43,3852, -16,0,618,1,1803, -787,1,1804,3853,16, -0,618,1,299,3854, -16,0,618,1,52, -3855,16,0,618,1, -2318,3856,16,0,618, -1,62,3857,16,0, -618,1,2075,3858,16, -0,618,1,1574,799, -1,71,3859,16,0, -618,1,76,3860,16, -0,618,1,1834,3861, -16,0,618,1,2337, -3862,16,0,618,1, -79,3863,16,0,618, -1,1335,3864,16,0, -618,1,322,3865,16, -0,618,1,85,3866, -16,0,618,1,89, -3867,16,0,618,1, -346,3868,16,0,618, -1,2105,814,1,2106, -3869,16,0,618,1, -97,3870,16,0,618, -1,1860,821,1,2364, -827,1,102,3871,16, -0,618,1,112,3872, -16,0,618,1,1117, -3873,16,0,618,1, -1873,835,1,1876,3874, -16,0,618,1,124, -3875,16,0,618,1, -2136,842,1,381,3876, -16,0,618,1,525, -3877,16,0,618,1, -137,3878,16,0,618, -1,1901,3879,16,0, -618,1,2658,3880,16, -0,618,1,1153,3881, -16,0,618,1,151, -3882,16,0,618,1, -1407,3883,16,0,618, -1,1659,3884,16,0, -618,1,2413,3885,16, -0,618,1,406,3886, -16,0,618,1,1371, -3887,16,0,618,1, -166,3888,16,0,618, -1,1622,3889,16,0, -618,1,1931,861,1, -1933,3890,16,0,618, -1,431,3891,16,0, -618,1,1585,3892,16, -0,618,1,182,3893, -16,0,618,1,1189, -3894,16,0,618,1, -1443,3895,16,0,618, -1,1695,3896,16,0, -618,1,2198,3897,16, -0,618,1,447,3898, -16,0,618,1,2458, -876,1,2459,882,1, -1958,3899,16,0,618, -1,2462,889,1,1657, -894,1,2464,899,1, -199,3900,16,0,618, -1,459,3901,16,0, -618,1,462,3902,16, -0,618,1,217,3903, -16,0,618,1,2227, -908,1,1225,3904,16, -0,618,1,1479,3905, -16,0,618,1,1731, -3906,16,0,618,1, -1989,916,1,1990,3907, -16,0,618,1,236, -3908,16,0,618,1, -1756,3909,16,0,618, -1,96,3910,19,103, -1,96,3911,5,1, -1,0,3912,16,0, -104,1,97,3913,19, -611,1,97,3914,5, -1,1,0,3915,16, -0,609,1,98,3916, -19,636,1,98,3917, -5,2,1,0,3918, -16,0,638,1,2695, -3919,16,0,634,1, -99,3920,19,633,1, -99,3921,5,2,1, -0,3922,16,0,637, -1,2695,3923,16,0, -631,1,100,3924,19, -296,1,100,3925,5, -2,1,0,3926,16, -0,557,1,2695,3927, -16,0,294,1,101, -3928,19,561,1,101, -3929,5,4,1,0, -3930,16,0,641,1, -2695,3931,16,0,641, -1,2706,3932,16,0, -559,1,2636,3933,16, -0,559,1,102,3934, -19,591,1,102,3935, -5,2,1,2470,3936, -16,0,664,1,2561, -3937,16,0,589,1, -103,3938,19,463,1, -103,3939,5,4,1, -2597,3940,16,0,558, -1,2521,3941,16,0, -558,1,2470,3942,16, -0,461,1,2561,3943, -16,0,461,1,104, -3944,19,141,1,104, -3945,5,3,1,2642, -3946,16,0,569,1, -2506,3947,16,0,317, -1,10,3948,16,0, -139,1,105,3949,19, -151,1,105,3950,5, -17,1,0,3951,16, -0,254,1,2075,3952, -16,0,648,1,2337, -3953,16,0,648,1, -2413,3954,16,0,648, -1,10,3955,16,0, -336,1,2198,3956,16, -0,648,1,1901,3957, -16,0,648,1,2642, -3958,16,0,336,1, -21,3959,16,0,149, -1,2106,3960,16,0, -648,1,2506,3961,16, -0,336,1,1804,3962, -16,0,648,1,1990, -3963,16,0,648,1, -2695,3964,16,0,254, -1,32,3965,16,0, -648,1,1958,3966,16, -0,648,1,1775,3967, -16,0,648,1,106, -3968,19,130,1,106, -3969,5,18,1,0, -3970,16,0,128,1, -2642,3971,16,0,137, -1,2075,3972,16,0, -137,1,2337,3973,16, -0,137,1,2413,3974, -16,0,137,1,10, -3975,16,0,137,1, -2198,3976,16,0,137, -1,1901,3977,16,0, -137,1,52,3978,16, -0,193,1,21,3979, -16,0,137,1,2106, -3980,16,0,137,1, -2506,3981,16,0,137, -1,1804,3982,16,0, -137,1,1990,3983,16, -0,137,1,2695,3984, -16,0,128,1,32, -3985,16,0,137,1, -1958,3986,16,0,137, -1,1775,3987,16,0, -137,1,107,3988,19, -658,1,107,3989,5, -4,1,2597,3990,16, -0,656,1,2521,3991, -16,0,656,1,2470, -3992,16,0,656,1, -2561,3993,16,0,656, -1,108,3994,19,335, -1,108,3995,5,14, -1,2517,3996,16,0, -437,1,2075,3997,16, -0,506,1,2337,3998, -16,0,506,1,2413, -3999,16,0,506,1, -1901,4000,16,0,506, -1,2198,4001,16,0, -506,1,2106,4002,16, -0,506,1,2653,4003, -16,0,571,1,1804, -4004,16,0,506,1, -1990,4005,16,0,506, -1,31,4006,16,0, -333,1,32,4007,16, -0,506,1,1958,4008, -16,0,506,1,1775, -4009,16,0,506,1, -109,4010,19,302,1, -109,4011,5,1,1, -32,4012,16,0,300, -1,110,4013,19,261, -1,110,4014,5,11, -1,2075,4015,16,0, -577,1,2337,4016,16, -0,265,1,2413,4017, -16,0,445,1,1901, -4018,16,0,391,1, -2198,4019,16,0,319, -1,2106,4020,16,0, -607,1,1804,4021,16, -0,284,1,1990,4022, -16,0,494,1,32, -4023,16,0,329,1, -1958,4024,16,0,450, -1,1775,4025,16,0, -259,1,111,4026,19, -583,1,111,4027,5, -11,1,2075,4028,16, -0,581,1,2337,4029, -16,0,581,1,2413, -4030,16,0,581,1, -1901,4031,16,0,581, -1,2198,4032,16,0, -581,1,2106,4033,16, -0,581,1,1804,4034, -16,0,581,1,1990, -4035,16,0,581,1, -32,4036,16,0,581, -1,1958,4037,16,0, -581,1,1775,4038,16, -0,581,1,112,4039, -19,645,1,112,4040, -5,11,1,2075,4041, -16,0,643,1,2337, -4042,16,0,643,1, -2413,4043,16,0,643, -1,1901,4044,16,0, -643,1,2198,4045,16, -0,643,1,2106,4046, -16,0,643,1,1804, -4047,16,0,643,1, -1990,4048,16,0,643, -1,32,4049,16,0, -643,1,1958,4050,16, -0,643,1,1775,4051, -16,0,643,1,113, -4052,19,161,1,113, -4053,5,31,1,1901, -4054,16,0,647,1, -1479,4055,16,0,551, -1,2075,4056,16,0, -647,1,1695,4057,16, -0,189,1,1756,4058, -16,0,188,1,2413, -4059,16,0,647,1, -2198,4060,16,0,647, -1,1876,4061,16,0, -661,1,1659,4062,16, -0,188,1,1443,4063, -16,0,522,1,1117, -4064,16,0,159,1, -1990,4065,16,0,647, -1,1189,4066,16,0, -240,1,1775,4067,16, -0,647,1,32,4068, -16,0,647,1,2106, -4069,16,0,647,1, -1515,4070,16,0,579, -1,2337,4071,16,0, -647,1,52,4072,16, -0,592,1,1804,4073, -16,0,647,1,1261, -4074,16,0,298,1, -1153,4075,16,0,247, -1,1225,4076,16,0, -274,1,1335,4077,16, -0,443,1,1933,4078, -16,0,553,1,1834, -4079,16,0,312,1, -1297,4080,16,0,323, -1,1407,4081,16,0, -568,1,2318,4082,16, -0,188,1,1958,4083, -16,0,647,1,1371, -4084,16,0,438,1, -114,4085,19,531,1, -114,4086,5,11,1, -2075,4087,16,0,529, -1,2337,4088,16,0, -529,1,2413,4089,16, -0,529,1,1901,4090, -16,0,529,1,2198, -4091,16,0,529,1, -2106,4092,16,0,529, -1,1804,4093,16,0, -529,1,1990,4094,16, -0,529,1,32,4095, -16,0,529,1,1958, -4096,16,0,529,1, -1775,4097,16,0,529, -1,115,4098,19,527, -1,115,4099,5,11, -1,2075,4100,16,0, -525,1,2337,4101,16, -0,525,1,2413,4102, -16,0,525,1,1901, -4103,16,0,525,1, -2198,4104,16,0,525, -1,2106,4105,16,0, -525,1,1804,4106,16, -0,525,1,1990,4107, -16,0,525,1,32, -4108,16,0,525,1, -1958,4109,16,0,525, -1,1775,4110,16,0, -525,1,116,4111,19, -575,1,116,4112,5, -11,1,2075,4113,16, -0,573,1,2337,4114, -16,0,573,1,2413, -4115,16,0,573,1, -1901,4116,16,0,573, -1,2198,4117,16,0, -573,1,2106,4118,16, -0,573,1,1804,4119, -16,0,573,1,1990, -4120,16,0,573,1, -32,4121,16,0,573, -1,1958,4122,16,0, -573,1,1775,4123,16, -0,573,1,117,4124, -19,521,1,117,4125, -5,11,1,2075,4126, -16,0,519,1,2337, -4127,16,0,519,1, -2413,4128,16,0,519, -1,1901,4129,16,0, -519,1,2198,4130,16, -0,519,1,2106,4131, -16,0,519,1,1804, -4132,16,0,519,1, -1990,4133,16,0,519, -1,32,4134,16,0, -519,1,1958,4135,16, -0,519,1,1775,4136, -16,0,519,1,118, -4137,19,518,1,118, -4138,5,11,1,2075, -4139,16,0,516,1, -2337,4140,16,0,516, -1,2413,4141,16,0, -516,1,1901,4142,16, -0,516,1,2198,4143, -16,0,516,1,2106, -4144,16,0,516,1, -1804,4145,16,0,516, -1,1990,4146,16,0, -516,1,32,4147,16, -0,516,1,1958,4148, -16,0,516,1,1775, -4149,16,0,516,1, -119,4150,19,515,1, -119,4151,5,11,1, -2075,4152,16,0,513, -1,2337,4153,16,0, -513,1,2413,4154,16, -0,513,1,1901,4155, -16,0,513,1,2198, -4156,16,0,513,1, -2106,4157,16,0,513, -1,1804,4158,16,0, -513,1,1990,4159,16, -0,513,1,32,4160, -16,0,513,1,1958, -4161,16,0,513,1, -1775,4162,16,0,513, -1,120,4163,19,512, -1,120,4164,5,11, -1,2075,4165,16,0, -510,1,2337,4166,16, -0,510,1,2413,4167, -16,0,510,1,1901, -4168,16,0,510,1, -2198,4169,16,0,510, -1,2106,4170,16,0, -510,1,1804,4171,16, -0,510,1,1990,4172, -16,0,510,1,32, -4173,16,0,510,1, -1958,4174,16,0,510, -1,1775,4175,16,0, -510,1,121,4176,19, -509,1,121,4177,5, -11,1,2075,4178,16, -0,507,1,2337,4179, -16,0,507,1,2413, -4180,16,0,507,1, -1901,4181,16,0,507, -1,2198,4182,16,0, -507,1,2106,4183,16, -0,507,1,1804,4184, -16,0,507,1,1990, -4185,16,0,507,1, -32,4186,16,0,507, -1,1958,4187,16,0, -507,1,1775,4188,16, -0,507,1,122,4189, -19,147,1,122,4190, -5,3,1,1756,4191, -16,0,283,1,2318, -4192,16,0,297,1, -1659,4193,16,0,145, -1,123,4194,19,548, -1,123,4195,5,68, -1,1901,4196,16,0, -546,1,1479,4197,16, -0,546,1,112,4198, -16,0,546,1,2293, -4199,16,0,546,1, -1804,4200,16,0,546, -1,431,4201,16,0, -546,1,1443,4202,16, -0,546,1,1756,4203, -16,0,546,1,124, -4204,16,0,546,1, -525,4205,16,0,546, -1,236,4206,16,0, -546,1,346,4207,16, -0,546,1,1876,4208, -16,0,546,1,1659, -4209,16,0,546,1, -1225,4210,16,0,546, -1,1117,4211,16,0, -546,1,137,4212,16, -0,546,1,2318,4213, -16,0,546,1,1775, -4214,16,0,546,1, -32,4215,16,0,546, -1,1407,4216,16,0, -546,1,256,4217,16, -0,546,1,459,4218, -16,0,546,1,406, -4219,16,0,546,1, -41,4220,16,0,546, -1,2658,4221,16,0, -546,1,43,4222,16, -0,546,1,1585,4223, -16,0,546,1,1990, -4224,16,0,546,1, -2337,4225,16,0,546, -1,509,4226,16,0, -546,1,52,4227,16, -0,546,1,151,4228, -16,0,546,1,447, -4229,16,0,546,1, -166,4230,16,0,546, -1,462,4231,16,0, -546,1,277,4232,16, -0,546,1,1695,4233, -16,0,546,1,62, -4234,16,0,586,1, -1153,4235,16,0,546, -1,381,4236,16,0, -546,1,2106,4237,16, -0,546,1,1335,4238, -16,0,546,1,71, -4239,16,0,546,1, -182,4240,16,0,546, -1,76,4241,16,0, -546,1,79,4242,16, -0,546,1,1933,4243, -16,0,546,1,299, -4244,16,0,546,1, -85,4245,16,0,546, -1,1515,4246,16,0, -546,1,2198,4247,16, -0,546,1,89,4248, -16,0,546,1,1834, -4249,16,0,546,1, -1622,4250,16,0,546, -1,2413,4251,16,0, -546,1,2075,4252,16, -0,546,1,1731,4253, -16,0,546,1,97, -4254,16,0,546,1, -1297,4255,16,0,546, -1,1189,4256,16,0, -546,1,102,4257,16, -0,546,1,1261,4258, -16,0,546,1,322, -4259,16,0,546,1, -1958,4260,16,0,546, -1,199,4261,16,0, -546,1,1371,4262,16, -0,546,1,217,4263, -16,0,546,1,124, -4264,19,602,1,124, -4265,5,2,1,459, -4266,16,0,600,1, -41,4267,16,0,665, -1,125,4268,19,606, -1,125,4269,5,3, -1,462,4270,16,0, -604,1,459,4271,16, -0,630,1,41,4272, -16,0,630,1,126, -4273,19,4274,4,36, -69,0,120,0,112, -0,114,0,101,0, -115,0,115,0,105, -0,111,0,110,0, -65,0,114,0,103, -0,117,0,109,0, -101,0,110,0,116, -0,1,126,4269,1, -127,4275,19,544,1, -127,4276,5,68,1, -1901,4277,16,0,542, -1,1479,4278,16,0, -542,1,112,4279,16, -0,542,1,2293,4280, -16,0,542,1,1804, -4281,16,0,542,1, -431,4282,16,0,542, -1,1443,4283,16,0, -542,1,1756,4284,16, -0,542,1,124,4285, -16,0,542,1,525, -4286,16,0,542,1, -236,4287,16,0,542, -1,346,4288,16,0, -542,1,1876,4289,16, -0,542,1,1659,4290, -16,0,542,1,1225, -4291,16,0,542,1, -1117,4292,16,0,542, -1,137,4293,16,0, -542,1,2318,4294,16, -0,542,1,1775,4295, -16,0,542,1,32, -4296,16,0,542,1, -1407,4297,16,0,542, -1,256,4298,16,0, -542,1,459,4299,16, -0,542,1,406,4300, -16,0,542,1,41, -4301,16,0,542,1, -2658,4302,16,0,542, -1,43,4303,16,0, -542,1,1585,4304,16, -0,542,1,1990,4305, -16,0,542,1,2337, -4306,16,0,542,1, -509,4307,16,0,542, -1,52,4308,16,0, -542,1,151,4309,16, -0,542,1,447,4310, -16,0,542,1,166, -4311,16,0,542,1, -462,4312,16,0,542, -1,277,4313,16,0, -542,1,1695,4314,16, -0,542,1,62,4315, -16,0,587,1,1153, -4316,16,0,542,1, -381,4317,16,0,542, -1,2106,4318,16,0, -542,1,1335,4319,16, -0,542,1,71,4320, -16,0,542,1,182, -4321,16,0,542,1, -76,4322,16,0,542, -1,79,4323,16,0, -542,1,1933,4324,16, -0,542,1,299,4325, -16,0,542,1,85, -4326,16,0,542,1, -1515,4327,16,0,542, -1,2198,4328,16,0, -542,1,89,4329,16, -0,542,1,1834,4330, -16,0,542,1,1622, -4331,16,0,542,1, -2413,4332,16,0,542, -1,2075,4333,16,0, -542,1,1731,4334,16, -0,542,1,97,4335, -16,0,542,1,1297, -4336,16,0,542,1, -1189,4337,16,0,542, -1,102,4338,16,0, -542,1,1261,4339,16, -0,542,1,322,4340, -16,0,542,1,1958, -4341,16,0,542,1, -199,4342,16,0,542, -1,1371,4343,16,0, -542,1,217,4344,16, -0,542,1,128,4345, -19,4346,4,28,86, -0,101,0,99,0, -116,0,111,0,114, -0,67,0,111,0, -110,0,115,0,116, -0,97,0,110,0, -116,0,1,128,4276, -1,129,4347,19,4348, -4,32,82,0,111, -0,116,0,97,0, -116,0,105,0,111, -0,110,0,67,0, +3868,16,0,618,1, +1479,3869,16,0,618, +1,1731,3870,16,0, +618,1,1989,916,1, +1990,3871,16,0,618, +1,236,3872,16,0, +618,1,1756,3873,16, +0,618,1,96,3874, +19,103,1,96,3875, +5,1,1,0,3876, +16,0,104,1,97, +3877,19,611,1,97, +3878,5,1,1,0, +3879,16,0,609,1, +98,3880,19,636,1, +98,3881,5,2,1, +0,3882,16,0,638, +1,2695,3883,16,0, +634,1,99,3884,19, +633,1,99,3885,5, +2,1,0,3886,16, +0,637,1,2695,3887, +16,0,631,1,100, +3888,19,296,1,100, +3889,5,2,1,0, +3890,16,0,557,1, +2695,3891,16,0,294, +1,101,3892,19,561, +1,101,3893,5,4, +1,0,3894,16,0, +641,1,2695,3895,16, +0,641,1,2706,3896, +16,0,559,1,2636, +3897,16,0,559,1, +102,3898,19,591,1, +102,3899,5,2,1, +2470,3900,16,0,664, +1,2561,3901,16,0, +589,1,103,3902,19, +463,1,103,3903,5, +4,1,2597,3904,16, +0,558,1,2521,3905, +16,0,558,1,2470, +3906,16,0,461,1, +2561,3907,16,0,461, +1,104,3908,19,141, +1,104,3909,5,3, +1,2642,3910,16,0, +569,1,2506,3911,16, +0,317,1,10,3912, +16,0,139,1,105, +3913,19,151,1,105, +3914,5,17,1,0, +3915,16,0,254,1, +2075,3916,16,0,648, +1,2337,3917,16,0, +648,1,2413,3918,16, +0,648,1,10,3919, +16,0,336,1,2198, +3920,16,0,648,1, +1901,3921,16,0,648, +1,2642,3922,16,0, +336,1,21,3923,16, +0,149,1,2106,3924, +16,0,648,1,2506, +3925,16,0,336,1, +1804,3926,16,0,648, +1,1990,3927,16,0, +648,1,2695,3928,16, +0,254,1,32,3929, +16,0,648,1,1958, +3930,16,0,648,1, +1775,3931,16,0,648, +1,106,3932,19,130, +1,106,3933,5,18, +1,0,3934,16,0, +128,1,2642,3935,16, +0,137,1,2075,3936, +16,0,137,1,2337, +3937,16,0,137,1, +2413,3938,16,0,137, +1,10,3939,16,0, +137,1,2198,3940,16, +0,137,1,1901,3941, +16,0,137,1,52, +3942,16,0,193,1, +21,3943,16,0,137, +1,2106,3944,16,0, +137,1,2506,3945,16, +0,137,1,1804,3946, +16,0,137,1,1990, +3947,16,0,137,1, +2695,3948,16,0,128, +1,32,3949,16,0, +137,1,1958,3950,16, +0,137,1,1775,3951, +16,0,137,1,107, +3952,19,658,1,107, +3953,5,4,1,2597, +3954,16,0,656,1, +2521,3955,16,0,656, +1,2470,3956,16,0, +656,1,2561,3957,16, +0,656,1,108,3958, +19,335,1,108,3959, +5,14,1,2517,3960, +16,0,437,1,2075, +3961,16,0,506,1, +2337,3962,16,0,506, +1,2413,3963,16,0, +506,1,1901,3964,16, +0,506,1,2198,3965, +16,0,506,1,2106, +3966,16,0,506,1, +2653,3967,16,0,571, +1,1804,3968,16,0, +506,1,1990,3969,16, +0,506,1,31,3970, +16,0,333,1,32, +3971,16,0,506,1, +1958,3972,16,0,506, +1,1775,3973,16,0, +506,1,109,3974,19, +302,1,109,3975,5, +1,1,32,3976,16, +0,300,1,110,3977, +19,261,1,110,3978, +5,11,1,2075,3979, +16,0,577,1,2337, +3980,16,0,265,1, +2413,3981,16,0,445, +1,1901,3982,16,0, +391,1,2198,3983,16, +0,319,1,2106,3984, +16,0,607,1,1804, +3985,16,0,284,1, +1990,3986,16,0,494, +1,32,3987,16,0, +329,1,1958,3988,16, +0,450,1,1775,3989, +16,0,259,1,111, +3990,19,583,1,111, +3991,5,11,1,2075, +3992,16,0,581,1, +2337,3993,16,0,581, +1,2413,3994,16,0, +581,1,1901,3995,16, +0,581,1,2198,3996, +16,0,581,1,2106, +3997,16,0,581,1, +1804,3998,16,0,581, +1,1990,3999,16,0, +581,1,32,4000,16, +0,581,1,1958,4001, +16,0,581,1,1775, +4002,16,0,581,1, +112,4003,19,645,1, +112,4004,5,11,1, +2075,4005,16,0,643, +1,2337,4006,16,0, +643,1,2413,4007,16, +0,643,1,1901,4008, +16,0,643,1,2198, +4009,16,0,643,1, +2106,4010,16,0,643, +1,1804,4011,16,0, +643,1,1990,4012,16, +0,643,1,32,4013, +16,0,643,1,1958, +4014,16,0,643,1, +1775,4015,16,0,643, +1,113,4016,19,161, +1,113,4017,5,31, +1,1901,4018,16,0, +647,1,1479,4019,16, +0,551,1,2075,4020, +16,0,647,1,1695, +4021,16,0,189,1, +1756,4022,16,0,188, +1,2413,4023,16,0, +647,1,2198,4024,16, +0,647,1,1876,4025, +16,0,661,1,1659, +4026,16,0,188,1, +1443,4027,16,0,522, +1,1117,4028,16,0, +159,1,1990,4029,16, +0,647,1,1189,4030, +16,0,240,1,1775, +4031,16,0,647,1, +32,4032,16,0,647, +1,2106,4033,16,0, +647,1,1515,4034,16, +0,579,1,2337,4035, +16,0,647,1,52, +4036,16,0,592,1, +1804,4037,16,0,647, +1,1261,4038,16,0, +298,1,1153,4039,16, +0,247,1,1225,4040, +16,0,274,1,1335, +4041,16,0,443,1, +1933,4042,16,0,553, +1,1834,4043,16,0, +312,1,1297,4044,16, +0,323,1,1407,4045, +16,0,568,1,2318, +4046,16,0,188,1, +1958,4047,16,0,647, +1,1371,4048,16,0, +438,1,114,4049,19, +531,1,114,4050,5, +11,1,2075,4051,16, +0,529,1,2337,4052, +16,0,529,1,2413, +4053,16,0,529,1, +1901,4054,16,0,529, +1,2198,4055,16,0, +529,1,2106,4056,16, +0,529,1,1804,4057, +16,0,529,1,1990, +4058,16,0,529,1, +32,4059,16,0,529, +1,1958,4060,16,0, +529,1,1775,4061,16, +0,529,1,115,4062, +19,527,1,115,4063, +5,11,1,2075,4064, +16,0,525,1,2337, +4065,16,0,525,1, +2413,4066,16,0,525, +1,1901,4067,16,0, +525,1,2198,4068,16, +0,525,1,2106,4069, +16,0,525,1,1804, +4070,16,0,525,1, +1990,4071,16,0,525, +1,32,4072,16,0, +525,1,1958,4073,16, +0,525,1,1775,4074, +16,0,525,1,116, +4075,19,575,1,116, +4076,5,11,1,2075, +4077,16,0,573,1, +2337,4078,16,0,573, +1,2413,4079,16,0, +573,1,1901,4080,16, +0,573,1,2198,4081, +16,0,573,1,2106, +4082,16,0,573,1, +1804,4083,16,0,573, +1,1990,4084,16,0, +573,1,32,4085,16, +0,573,1,1958,4086, +16,0,573,1,1775, +4087,16,0,573,1, +117,4088,19,521,1, +117,4089,5,11,1, +2075,4090,16,0,519, +1,2337,4091,16,0, +519,1,2413,4092,16, +0,519,1,1901,4093, +16,0,519,1,2198, +4094,16,0,519,1, +2106,4095,16,0,519, +1,1804,4096,16,0, +519,1,1990,4097,16, +0,519,1,32,4098, +16,0,519,1,1958, +4099,16,0,519,1, +1775,4100,16,0,519, +1,118,4101,19,518, +1,118,4102,5,11, +1,2075,4103,16,0, +516,1,2337,4104,16, +0,516,1,2413,4105, +16,0,516,1,1901, +4106,16,0,516,1, +2198,4107,16,0,516, +1,2106,4108,16,0, +516,1,1804,4109,16, +0,516,1,1990,4110, +16,0,516,1,32, +4111,16,0,516,1, +1958,4112,16,0,516, +1,1775,4113,16,0, +516,1,119,4114,19, +515,1,119,4115,5, +11,1,2075,4116,16, +0,513,1,2337,4117, +16,0,513,1,2413, +4118,16,0,513,1, +1901,4119,16,0,513, +1,2198,4120,16,0, +513,1,2106,4121,16, +0,513,1,1804,4122, +16,0,513,1,1990, +4123,16,0,513,1, +32,4124,16,0,513, +1,1958,4125,16,0, +513,1,1775,4126,16, +0,513,1,120,4127, +19,512,1,120,4128, +5,11,1,2075,4129, +16,0,510,1,2337, +4130,16,0,510,1, +2413,4131,16,0,510, +1,1901,4132,16,0, +510,1,2198,4133,16, +0,510,1,2106,4134, +16,0,510,1,1804, +4135,16,0,510,1, +1990,4136,16,0,510, +1,32,4137,16,0, +510,1,1958,4138,16, +0,510,1,1775,4139, +16,0,510,1,121, +4140,19,509,1,121, +4141,5,11,1,2075, +4142,16,0,507,1, +2337,4143,16,0,507, +1,2413,4144,16,0, +507,1,1901,4145,16, +0,507,1,2198,4146, +16,0,507,1,2106, +4147,16,0,507,1, +1804,4148,16,0,507, +1,1990,4149,16,0, +507,1,32,4150,16, +0,507,1,1958,4151, +16,0,507,1,1775, +4152,16,0,507,1, +122,4153,19,147,1, +122,4154,5,3,1, +1756,4155,16,0,283, +1,2318,4156,16,0, +297,1,1659,4157,16, +0,145,1,123,4158, +19,548,1,123,4159, +5,68,1,1901,4160, +16,0,546,1,1479, +4161,16,0,546,1, +112,4162,16,0,546, +1,2293,4163,16,0, +546,1,1804,4164,16, +0,546,1,431,4165, +16,0,546,1,1443, +4166,16,0,546,1, +1756,4167,16,0,546, +1,124,4168,16,0, +546,1,525,4169,16, +0,546,1,236,4170, +16,0,546,1,346, +4171,16,0,546,1, +1876,4172,16,0,546, +1,1659,4173,16,0, +546,1,1225,4174,16, +0,546,1,1117,4175, +16,0,546,1,137, +4176,16,0,546,1, +2318,4177,16,0,546, +1,1775,4178,16,0, +546,1,32,4179,16, +0,546,1,1407,4180, +16,0,546,1,256, +4181,16,0,546,1, +459,4182,16,0,546, +1,406,4183,16,0, +546,1,41,4184,16, +0,546,1,2658,4185, +16,0,546,1,43, +4186,16,0,546,1, +1585,4187,16,0,546, +1,1990,4188,16,0, +546,1,2337,4189,16, +0,546,1,509,4190, +16,0,546,1,52, +4191,16,0,546,1, +151,4192,16,0,546, +1,447,4193,16,0, +546,1,166,4194,16, +0,546,1,462,4195, +16,0,546,1,277, +4196,16,0,546,1, +1695,4197,16,0,546, +1,62,4198,16,0, +586,1,1153,4199,16, +0,546,1,381,4200, +16,0,546,1,2106, +4201,16,0,546,1, +1335,4202,16,0,546, +1,71,4203,16,0, +546,1,182,4204,16, +0,546,1,76,4205, +16,0,546,1,79, +4206,16,0,546,1, +1933,4207,16,0,546, +1,299,4208,16,0, +546,1,85,4209,16, +0,546,1,1515,4210, +16,0,546,1,2198, +4211,16,0,546,1, +89,4212,16,0,546, +1,1834,4213,16,0, +546,1,1622,4214,16, +0,546,1,2413,4215, +16,0,546,1,2075, +4216,16,0,546,1, +1731,4217,16,0,546, +1,97,4218,16,0, +546,1,1297,4219,16, +0,546,1,1189,4220, +16,0,546,1,102, +4221,16,0,546,1, +1261,4222,16,0,546, +1,322,4223,16,0, +546,1,1958,4224,16, +0,546,1,199,4225, +16,0,546,1,1371, +4226,16,0,546,1, +217,4227,16,0,546, +1,124,4228,19,602, +1,124,4229,5,2, +1,459,4230,16,0, +600,1,41,4231,16, +0,665,1,125,4232, +19,606,1,125,4233, +5,3,1,462,4234, +16,0,604,1,459, +4235,16,0,630,1, +41,4236,16,0,630, +1,126,4237,19,4238, +4,36,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,65,0,114, +0,103,0,117,0, +109,0,101,0,110, +0,116,0,1,126, +4233,1,127,4239,19, +544,1,127,4240,5, +68,1,1901,4241,16, +0,542,1,1479,4242, +16,0,542,1,112, +4243,16,0,542,1, +2293,4244,16,0,542, +1,1804,4245,16,0, +542,1,431,4246,16, +0,542,1,1443,4247, +16,0,542,1,1756, +4248,16,0,542,1, +124,4249,16,0,542, +1,525,4250,16,0, +542,1,236,4251,16, +0,542,1,346,4252, +16,0,542,1,1876, +4253,16,0,542,1, +1659,4254,16,0,542, +1,1225,4255,16,0, +542,1,1117,4256,16, +0,542,1,137,4257, +16,0,542,1,2318, +4258,16,0,542,1, +1775,4259,16,0,542, +1,32,4260,16,0, +542,1,1407,4261,16, +0,542,1,256,4262, +16,0,542,1,459, +4263,16,0,542,1, +406,4264,16,0,542, +1,41,4265,16,0, +542,1,2658,4266,16, +0,542,1,43,4267, +16,0,542,1,1585, +4268,16,0,542,1, +1990,4269,16,0,542, +1,2337,4270,16,0, +542,1,509,4271,16, +0,542,1,52,4272, +16,0,542,1,151, +4273,16,0,542,1, +447,4274,16,0,542, +1,166,4275,16,0, +542,1,462,4276,16, +0,542,1,277,4277, +16,0,542,1,1695, +4278,16,0,542,1, +62,4279,16,0,587, +1,1153,4280,16,0, +542,1,381,4281,16, +0,542,1,2106,4282, +16,0,542,1,1335, +4283,16,0,542,1, +71,4284,16,0,542, +1,182,4285,16,0, +542,1,76,4286,16, +0,542,1,79,4287, +16,0,542,1,1933, +4288,16,0,542,1, +299,4289,16,0,542, +1,85,4290,16,0, +542,1,1515,4291,16, +0,542,1,2198,4292, +16,0,542,1,89, +4293,16,0,542,1, +1834,4294,16,0,542, +1,1622,4295,16,0, +542,1,2413,4296,16, +0,542,1,2075,4297, +16,0,542,1,1731, +4298,16,0,542,1, +97,4299,16,0,542, +1,1297,4300,16,0, +542,1,1189,4301,16, +0,542,1,102,4302, +16,0,542,1,1261, +4303,16,0,542,1, +322,4304,16,0,542, +1,1958,4305,16,0, +542,1,199,4306,16, +0,542,1,1371,4307, +16,0,542,1,217, +4308,16,0,542,1, +128,4309,19,4310,4, +28,86,0,101,0, +99,0,116,0,111, +0,114,0,67,0, 111,0,110,0,115, 0,116,0,97,0, 110,0,116,0,1, -129,4276,1,130,4349, -19,4350,4,24,76, -0,105,0,115,0, -116,0,67,0,111, -0,110,0,115,0, -116,0,97,0,110, -0,116,0,1,130, -4276,1,131,4351,19, -169,1,131,4352,5, -67,1,1901,4353,16, -0,585,1,1479,4354, -16,0,533,1,112, -4355,16,0,249,1, -2293,4356,16,0,273, -1,1804,4357,16,0, -585,1,431,4358,16, -0,580,1,1443,4359, -16,0,468,1,1756, -4360,16,0,673,1, -124,4361,16,0,258, -1,525,4362,16,0, -305,1,236,4363,16, -0,341,1,346,4364, -16,0,496,1,1876, -4365,16,0,318,1, -1659,4366,16,0,673, -1,1225,4367,16,0, -248,1,1117,4368,16, -0,219,1,137,4369, -16,0,272,1,2318, -4370,16,0,673,1, -1775,4371,16,0,585, -1,32,4372,16,0, -585,1,1407,4373,16, -0,487,1,256,4374, -16,0,395,1,459, -4375,16,0,167,1, -406,4376,16,0,562, -1,41,4377,16,0, -167,1,2658,4378,16, -0,659,1,43,4379, -16,0,640,1,1990, -4380,16,0,585,1, -2337,4381,16,0,585, -1,509,4382,16,0, -655,1,52,4383,16, -0,594,1,151,4384, -16,0,282,1,447, -4385,16,0,305,1, -166,4386,16,0,293, -1,462,4387,16,0, -167,1,277,4388,16, -0,434,1,1695,4389, -16,0,270,1,1261, -4390,16,0,281,1, -1153,4391,16,0,174, -1,381,4392,16,0, -550,1,2106,4393,16, -0,585,1,1335,4394, -16,0,326,1,71, -4395,16,0,203,1, -182,4396,16,0,305, -1,76,4397,16,0, -549,1,79,4398,16, -0,218,1,1933,4399, -16,0,407,1,299, -4400,16,0,444,1, -85,4401,16,0,457, -1,1515,4402,16,0, -556,1,2198,4403,16, -0,585,1,89,4404, -16,0,227,1,1834, -4405,16,0,292,1, -1622,4406,16,0,654, -1,2413,4407,16,0, -585,1,2075,4408,16, -0,585,1,1731,4409, -16,0,250,1,97, -4410,16,0,411,1, -1297,4411,16,0,328, -1,1189,4412,16,0, -217,1,102,4413,16, -0,238,1,1585,4414, -16,0,663,1,322, -4415,16,0,458,1, -1958,4416,16,0,585, -1,199,4417,16,0, -316,1,1371,4418,16, -0,396,1,217,4419, -16,0,325,1,132, -4420,19,4421,4,36, +128,4240,1,129,4311, +19,4312,4,32,82, +0,111,0,116,0, +97,0,116,0,105, +0,111,0,110,0, 67,0,111,0,110, 0,115,0,116,0, 97,0,110,0,116, -0,69,0,120,0, -112,0,114,0,101, -0,115,0,115,0, -105,0,111,0,110, -0,1,132,4352,1, -133,4422,19,4423,4, -30,73,0,100,0, -101,0,110,0,116, -0,69,0,120,0, -112,0,114,0,101, -0,115,0,115,0, -105,0,111,0,110, -0,1,133,4352,1, -134,4424,19,4425,4, -36,73,0,100,0, -101,0,110,0,116, -0,68,0,111,0, -116,0,69,0,120, -0,112,0,114,0, -101,0,115,0,115, -0,105,0,111,0, -110,0,1,134,4352, -1,135,4426,19,4427, -4,44,70,0,117, -0,110,0,99,0, -116,0,105,0,111, -0,110,0,67,0, -97,0,108,0,108, -0,69,0,120,0, -112,0,114,0,101, -0,115,0,115,0, -105,0,111,0,110, -0,1,135,4352,1, -136,4428,19,4429,4, -32,66,0,105,0, -110,0,97,0,114, -0,121,0,69,0, +0,1,129,4240,1, +130,4313,19,4314,4, +24,76,0,105,0, +115,0,116,0,67, +0,111,0,110,0, +115,0,116,0,97, +0,110,0,116,0, +1,130,4240,1,131, +4315,19,169,1,131, +4316,5,67,1,1901, +4317,16,0,585,1, +1479,4318,16,0,533, +1,112,4319,16,0, +249,1,2293,4320,16, +0,273,1,1804,4321, +16,0,585,1,431, +4322,16,0,580,1, +1443,4323,16,0,468, +1,1756,4324,16,0, +673,1,124,4325,16, +0,258,1,525,4326, +16,0,305,1,236, +4327,16,0,341,1, +346,4328,16,0,496, +1,1876,4329,16,0, +318,1,1659,4330,16, +0,673,1,1225,4331, +16,0,248,1,1117, +4332,16,0,219,1, +137,4333,16,0,272, +1,2318,4334,16,0, +673,1,1775,4335,16, +0,585,1,32,4336, +16,0,585,1,1407, +4337,16,0,487,1, +256,4338,16,0,395, +1,459,4339,16,0, +167,1,406,4340,16, +0,562,1,41,4341, +16,0,167,1,2658, +4342,16,0,659,1, +43,4343,16,0,640, +1,1990,4344,16,0, +585,1,2337,4345,16, +0,585,1,509,4346, +16,0,655,1,52, +4347,16,0,594,1, +151,4348,16,0,282, +1,447,4349,16,0, +305,1,166,4350,16, +0,293,1,462,4351, +16,0,167,1,277, +4352,16,0,434,1, +1695,4353,16,0,270, +1,1261,4354,16,0, +281,1,1153,4355,16, +0,174,1,381,4356, +16,0,550,1,2106, +4357,16,0,585,1, +1335,4358,16,0,326, +1,71,4359,16,0, +203,1,182,4360,16, +0,305,1,76,4361, +16,0,549,1,79, +4362,16,0,218,1, +1933,4363,16,0,407, +1,299,4364,16,0, +444,1,85,4365,16, +0,457,1,1515,4366, +16,0,556,1,2198, +4367,16,0,585,1, +89,4368,16,0,227, +1,1834,4369,16,0, +292,1,1622,4370,16, +0,654,1,2413,4371, +16,0,585,1,2075, +4372,16,0,585,1, +1731,4373,16,0,250, +1,97,4374,16,0, +411,1,1297,4375,16, +0,328,1,1189,4376, +16,0,217,1,102, +4377,16,0,238,1, +1585,4378,16,0,663, +1,322,4379,16,0, +458,1,1958,4380,16, +0,585,1,199,4381, +16,0,316,1,1371, +4382,16,0,396,1, +217,4383,16,0,325, +1,132,4384,19,4385, +4,36,67,0,111, +0,110,0,115,0, +116,0,97,0,110, +0,116,0,69,0, 120,0,112,0,114, 0,101,0,115,0, 115,0,105,0,111, -0,110,0,1,136, -4352,1,137,4430,19, -4431,4,30,85,0, -110,0,97,0,114, -0,121,0,69,0, +0,110,0,1,132, +4316,1,133,4386,19, +4387,4,30,73,0, +100,0,101,0,110, +0,116,0,69,0, 120,0,112,0,114, 0,101,0,115,0, 115,0,105,0,111, -0,110,0,1,137, -4352,1,138,4432,19, -4433,4,36,84,0, -121,0,112,0,101, -0,99,0,97,0, -115,0,116,0,69, +0,110,0,1,133, +4316,1,134,4388,19, +4389,4,36,73,0, +100,0,101,0,110, +0,116,0,68,0, +111,0,116,0,69, 0,120,0,112,0, 114,0,101,0,115, 0,115,0,105,0, 111,0,110,0,1, -138,4352,1,139,4434, -19,4435,4,42,80, -0,97,0,114,0, -101,0,110,0,116, -0,104,0,101,0, -115,0,105,0,115, +134,4316,1,135,4390, +19,4391,4,44,70, +0,117,0,110,0, +99,0,116,0,105, +0,111,0,110,0, +67,0,97,0,108, +0,108,0,69,0, +120,0,112,0,114, +0,101,0,115,0, +115,0,105,0,111, +0,110,0,1,135, +4316,1,136,4392,19, +4393,4,32,66,0, +105,0,110,0,97, +0,114,0,121,0, +69,0,120,0,112, +0,114,0,101,0, +115,0,115,0,105, +0,111,0,110,0, +1,136,4316,1,137, +4394,19,4395,4,30, +85,0,110,0,97, +0,114,0,121,0, +69,0,120,0,112, +0,114,0,101,0, +115,0,115,0,105, +0,111,0,110,0, +1,137,4316,1,138, +4396,19,4397,4,36, +84,0,121,0,112, +0,101,0,99,0, +97,0,115,0,116, 0,69,0,120,0, 112,0,114,0,101, 0,115,0,115,0, 105,0,111,0,110, -0,1,139,4352,1, -140,4436,19,4437,4, -56,73,0,110,0, +0,1,138,4316,1, +139,4398,19,4399,4, +42,80,0,97,0, +114,0,101,0,110, +0,116,0,104,0, +101,0,115,0,105, +0,115,0,69,0, +120,0,112,0,114, +0,101,0,115,0, +115,0,105,0,111, +0,110,0,1,139, +4316,1,140,4400,19, +4401,4,56,73,0, +110,0,99,0,114, +0,101,0,109,0, +101,0,110,0,116, +0,68,0,101,0, 99,0,114,0,101, 0,109,0,101,0, -110,0,116,0,68, -0,101,0,99,0, -114,0,101,0,109, -0,101,0,110,0, -116,0,69,0,120, -0,112,0,114,0, -101,0,115,0,115, +110,0,116,0,69, +0,120,0,112,0, +114,0,101,0,115, +0,115,0,105,0, +111,0,110,0,1, +140,4316,1,142,4402, +19,683,1,142,3875, +1,143,4403,19,705, +1,143,3875,1,144, +4404,19,3156,1,144, +3878,1,145,4405,19, +3151,1,145,3878,1, +146,4406,19,3162,1, +146,3878,1,147,4407, +19,3173,1,147,3878, +1,148,4408,19,3184, +1,148,3881,1,149, +4409,19,3190,1,149, +3881,1,150,4410,19, +3178,1,150,3885,1, +151,4411,19,3168,1, +151,3885,1,152,4412, +19,689,1,152,3889, +1,153,4413,19,710, +1,153,3889,1,154, +4414,19,695,1,154, +3893,1,155,4415,19, +700,1,155,3893,1, +156,4416,19,1636,1, +156,3899,1,157,4417, +19,1631,1,157,3899, +1,158,4418,19,1622, +1,158,3903,1,159, +4419,19,1680,1,159, +3909,1,160,4420,19, +1657,1,160,3909,1, +161,4421,19,1117,1, +161,3914,1,162,4422, +19,902,1,162,3959, +1,163,4423,19,886, +1,163,3959,1,164, +4424,19,892,1,164, +3975,1,165,4425,19, +880,1,165,3975,1, +166,4426,19,1145,1, +166,3991,1,167,4427, +19,782,1,167,3978, +1,168,4428,19,897, +1,168,3978,1,169, +4429,19,777,1,169, +3978,1,170,4430,19, +802,1,170,3978,1, +171,4431,19,771,1, +171,3978,1,172,4432, +19,765,1,172,3978, +1,173,4433,19,760, +1,173,3978,1,174, +4434,19,755,1,174, +3978,1,175,4435,19, +749,1,175,3978,1, +176,4436,19,744,1, +176,3978,1,177,4437, +19,739,1,177,3978, +1,178,4438,19,734, +1,178,3978,1,179, +4439,19,729,1,179, +3978,1,180,4440,19, +1152,1,180,4063,1, +181,4441,19,1290,1, +181,4076,1,182,4442, +19,1139,1,182,4089, +1,183,4443,19,1278, +1,183,4089,1,184, +4444,19,919,1,184, +4102,1,185,4445,19, +722,1,185,4102,1, +186,4446,19,817,1, +186,4102,1,187,4447, +19,845,1,187,4102, +1,188,4448,19,865, +1,188,4115,1,189, +4449,19,911,1,189, +4115,1,190,4450,19, +825,1,190,4128,1, +191,4451,19,838,1, +191,4128,1,192,4452, +19,791,1,192,4141, +1,193,4453,19,830, +1,193,4141,1,194, +4454,19,1477,1,194, +4154,1,195,4455,19, +1158,1,195,4154,1, +196,4456,19,1509,1, +196,4154,1,197,4457, +19,1541,1,197,4154, +1,198,4458,19,1406, +1,198,4004,1,199, +4459,19,1466,1,199, +4004,1,200,4460,19, +1133,1,200,4017,1, +201,4461,19,1573,1, +201,4017,1,202,4462, +19,1504,1,202,4017, +1,203,4463,19,1451, +1,203,4017,1,204, +4464,19,1374,1,204, +4017,1,205,4465,19, +1300,1,205,4017,1, +206,4466,19,1310,1, +206,4017,1,207,4467, +19,1128,1,207,4017, +1,208,4468,19,1557, +1,208,4017,1,209, +4469,19,1499,1,209, +4017,1,210,4470,19, +1441,1,210,4017,1, +211,4471,19,1363,1, +211,4017,1,212,4472, +19,1326,1,212,4017, +1,213,4473,19,1111, +1,213,4017,1,214, +4474,19,1461,1,214, +4017,1,215,4475,19, +1487,1,215,4017,1, +216,4476,19,1434,1, +216,4017,1,217,4477, +19,1456,1,217,4017, +1,218,4478,19,1266, +1,218,4017,1,219, +4479,19,1170,1,219, +4017,1,220,4480,19, +1100,1,220,4017,1, +221,4481,19,1531,1, +221,4017,1,222,4482, +19,1482,1,222,4017, +1,223,4483,19,1429, +1,223,4017,1,224, +4484,19,1295,1,224, +4050,1,225,4485,19, +1273,1,225,4050,1, +226,4486,19,1562,1, +226,4240,1,227,4487, +19,1586,1,227,4240, +1,228,4488,19,1552, +1,228,4240,1,229, +4489,19,1547,1,229, +4240,1,230,4490,19, +1568,1,230,4240,1, +231,4491,19,1515,1, +231,4240,1,232,4492, +19,1220,1,232,4240, +1,233,4493,19,1395, +1,233,4316,1,234, +4494,19,1181,1,234, +4316,1,235,4495,19, +1188,1,235,4316,1, +236,4496,19,1209,1, +236,4316,1,237,4497, +19,1204,1,237,4316, +1,238,4498,19,1199, +1,238,4316,1,239, +4499,19,1194,1,239, +4316,1,240,4500,19, +1384,1,240,4316,1, +241,4501,19,1412,1, +241,4316,1,242,4502, +19,1389,1,242,4316, +1,243,4503,19,1379, +1,243,4316,1,244, +4504,19,1369,1,244, +4316,1,245,4505,19, +1352,1,245,4316,1, +246,4506,19,1305,1, +246,4316,1,247,4507, +19,1214,1,247,4316, +1,248,4508,19,1175, +1,248,4316,1,249, +4509,19,1123,1,249, +4316,1,250,4510,19, +1581,1,250,4316,1, +251,4511,19,1536,1, +251,4316,1,252,4512, +19,1526,1,252,4316, +1,253,4513,19,1521, +1,253,4316,1,254, +4514,19,1472,1,254, +4316,1,255,4515,19, +1446,1,255,4316,1, +256,4516,19,1422,1, +256,4316,1,257,4517, +19,1417,1,257,4316, +1,258,4518,19,1358, +1,258,4316,1,259, +4519,19,1334,1,259, +4316,1,260,4520,19, +1400,1,260,4316,1, +261,4521,19,1493,1, +261,4316,1,262,4522, +19,1347,1,262,4316, +1,263,4523,19,1341, +1,263,4316,1,264, +4524,19,1321,1,264, +4316,1,265,4525,19, +1284,1,265,4316,1, +266,4526,19,1261,1, +266,4316,1,267,4527, +19,1106,1,267,4316, +1,268,4528,19,1596, +1,268,4316,1,269, +4529,19,1226,1,269, +4316,1,270,4530,19, +1231,1,270,4316,1, +271,4531,19,1251,1, +271,4316,1,272,4532, +19,1241,1,272,4316, +1,273,4533,19,1246, +1,273,4316,1,274, +4534,19,1236,1,274, +4316,1,275,4535,19, +1591,1,275,4316,1, +276,4536,19,1256,1, +276,4316,1,277,4537, +19,1316,1,277,4159, +1,278,4538,19,1650, +1,278,4229,1,279, +4539,19,1686,1,279, +4229,1,280,4540,19, +1666,1,280,4233,1, +281,4541,19,1985,1, +281,3933,1,282,4542, +19,1980,1,282,3933, +1,283,4543,19,1975, +1,283,3933,1,284, +4544,19,1970,1,284, +3933,1,285,4545,19, +1965,1,285,3933,1, +286,4546,19,1960,1, +286,3933,1,287,4547, +19,1955,1,287,3933, +1,288,4548,19,1944, +1,288,3953,1,289, +4549,19,1939,1,289, +3953,1,290,4550,19, +1934,1,290,3953,1, +291,4551,19,1929,1, +291,3953,1,292,4552, +19,1924,1,292,3953, +1,293,4553,19,1919, +1,293,3953,1,294, +4554,19,1914,1,294, +3953,1,295,4555,19, +1909,1,295,3953,1, +296,4556,19,1904,1, +296,3953,1,297,4557, +19,1739,1,297,3953, +1,298,4558,19,1898, +1,298,3953,1,299, +4559,19,1893,1,299, +3953,1,300,4560,19, +1888,1,300,3953,1, +301,4561,19,1732,1, +301,3953,1,302,4562, +19,1883,1,302,3953, +1,303,4563,19,1878, +1,303,3953,1,304, +4564,19,1873,1,304, +3953,1,305,4565,19, +1868,1,305,3953,1, +306,4566,19,1863,1, +306,3953,1,307,4567, +19,1858,1,307,3953, +1,308,4568,19,1725, +1,308,3953,1,309, +4569,19,1852,1,309, +3953,1,310,4570,19, +1847,1,310,3953,1, +311,4571,19,1842,1, +311,3953,1,312,4572, +19,1719,1,312,3953, +1,313,4573,19,1836, +1,313,3953,1,314, +4574,19,1767,1,314, +3953,1,315,4575,19, +1831,1,315,3953,1, +316,4576,19,1826,1, +316,3953,1,317,4577, +19,1821,1,317,3953, +1,318,4578,19,1816, +1,318,3953,1,319, +4579,19,1811,1,319, +3953,1,320,4580,19, +1806,1,320,3953,1, +321,4581,19,1801,1, +321,3953,1,322,4582, +19,4583,4,50,65, +0,114,0,103,0, +117,0,109,0,101, +0,110,0,116,0, +68,0,101,0,99, +0,108,0,97,0, +114,0,97,0,116, 0,105,0,111,0, -110,0,1,140,4352, -1,142,4438,19,683, -1,142,3911,1,143, -4439,19,705,1,143, -3911,1,144,4440,19, -3192,1,144,3914,1, -145,4441,19,3187,1, -145,3914,1,146,4442, -19,3198,1,146,3914, -1,147,4443,19,3209, -1,147,3914,1,148, -4444,19,3220,1,148, -3917,1,149,4445,19, -3226,1,149,3917,1, -150,4446,19,3214,1, -150,3921,1,151,4447, -19,3204,1,151,3921, -1,152,4448,19,689, -1,152,3925,1,153, -4449,19,710,1,153, -3925,1,154,4450,19, -695,1,154,3929,1, -155,4451,19,700,1, -155,3929,1,156,4452, -19,1636,1,156,3935, -1,157,4453,19,1631, -1,157,3935,1,158, -4454,19,1622,1,158, -3939,1,159,4455,19, -1680,1,159,3945,1, -160,4456,19,1657,1, -160,3945,1,161,4457, -19,1117,1,161,3950, -1,162,4458,19,902, -1,162,3995,1,163, -4459,19,886,1,163, -3995,1,164,4460,19, -892,1,164,4011,1, -165,4461,19,880,1, -165,4011,1,166,4462, -19,1145,1,166,4027, -1,167,4463,19,782, -1,167,4014,1,168, -4464,19,897,1,168, -4014,1,169,4465,19, -777,1,169,4014,1, -170,4466,19,802,1, -170,4014,1,171,4467, -19,771,1,171,4014, -1,172,4468,19,765, -1,172,4014,1,173, -4469,19,760,1,173, -4014,1,174,4470,19, -755,1,174,4014,1, -175,4471,19,749,1, -175,4014,1,176,4472, -19,744,1,176,4014, -1,177,4473,19,739, -1,177,4014,1,178, -4474,19,734,1,178, -4014,1,179,4475,19, -729,1,179,4014,1, -180,4476,19,1152,1, -180,4099,1,181,4477, -19,1290,1,181,4112, -1,182,4478,19,1139, -1,182,4125,1,183, -4479,19,1278,1,183, -4125,1,184,4480,19, -919,1,184,4138,1, -185,4481,19,722,1, -185,4138,1,186,4482, -19,817,1,186,4138, -1,187,4483,19,845, -1,187,4138,1,188, -4484,19,865,1,188, -4151,1,189,4485,19, -911,1,189,4151,1, -190,4486,19,825,1, -190,4164,1,191,4487, -19,838,1,191,4164, -1,192,4488,19,791, -1,192,4177,1,193, -4489,19,830,1,193, -4177,1,194,4490,19, -1477,1,194,4190,1, -195,4491,19,1158,1, -195,4190,1,196,4492, -19,1509,1,196,4190, -1,197,4493,19,1541, -1,197,4190,1,198, -4494,19,1406,1,198, -4040,1,199,4495,19, -1466,1,199,4040,1, -200,4496,19,1133,1, -200,4053,1,201,4497, -19,1573,1,201,4053, -1,202,4498,19,1504, -1,202,4053,1,203, -4499,19,1451,1,203, -4053,1,204,4500,19, -1374,1,204,4053,1, -205,4501,19,1300,1, -205,4053,1,206,4502, -19,1310,1,206,4053, -1,207,4503,19,1128, -1,207,4053,1,208, -4504,19,1557,1,208, -4053,1,209,4505,19, -1499,1,209,4053,1, -210,4506,19,1441,1, -210,4053,1,211,4507, -19,1363,1,211,4053, -1,212,4508,19,1326, -1,212,4053,1,213, -4509,19,1111,1,213, -4053,1,214,4510,19, -1461,1,214,4053,1, -215,4511,19,1487,1, -215,4053,1,216,4512, -19,1434,1,216,4053, -1,217,4513,19,1456, -1,217,4053,1,218, -4514,19,1266,1,218, -4053,1,219,4515,19, -1170,1,219,4053,1, -220,4516,19,1100,1, -220,4053,1,221,4517, -19,1531,1,221,4053, -1,222,4518,19,1482, -1,222,4053,1,223, -4519,19,1429,1,223, -4053,1,224,4520,19, -1295,1,224,4086,1, -225,4521,19,1273,1, -225,4086,1,226,4522, -19,1562,1,226,4276, -1,227,4523,19,1586, -1,227,4276,1,228, -4524,19,1552,1,228, -4276,1,229,4525,19, -1547,1,229,4276,1, -230,4526,19,1568,1, -230,4276,1,231,4527, -19,1515,1,231,4276, -1,232,4528,19,1220, -1,232,4276,1,233, -4529,19,1395,1,233, -4352,1,234,4530,19, -1181,1,234,4352,1, -235,4531,19,1188,1, -235,4352,1,236,4532, -19,1209,1,236,4352, -1,237,4533,19,1204, -1,237,4352,1,238, -4534,19,1199,1,238, -4352,1,239,4535,19, -1194,1,239,4352,1, -240,4536,19,1384,1, -240,4352,1,241,4537, -19,1412,1,241,4352, -1,242,4538,19,1389, -1,242,4352,1,243, -4539,19,1379,1,243, -4352,1,244,4540,19, -1369,1,244,4352,1, -245,4541,19,1352,1, -245,4352,1,246,4542, -19,1305,1,246,4352, -1,247,4543,19,1214, -1,247,4352,1,248, -4544,19,1175,1,248, -4352,1,249,4545,19, -1123,1,249,4352,1, -250,4546,19,1581,1, -250,4352,1,251,4547, -19,1536,1,251,4352, -1,252,4548,19,1526, -1,252,4352,1,253, -4549,19,1521,1,253, -4352,1,254,4550,19, -1472,1,254,4352,1, -255,4551,19,1446,1, -255,4352,1,256,4552, -19,1422,1,256,4352, -1,257,4553,19,1417, -1,257,4352,1,258, -4554,19,1358,1,258, -4352,1,259,4555,19, -1334,1,259,4352,1, -260,4556,19,1400,1, -260,4352,1,261,4557, -19,1493,1,261,4352, -1,262,4558,19,1347, -1,262,4352,1,263, -4559,19,1341,1,263, -4352,1,264,4560,19, -1321,1,264,4352,1, -265,4561,19,1284,1, -265,4352,1,266,4562, -19,1261,1,266,4352, -1,267,4563,19,1106, -1,267,4352,1,268, -4564,19,1596,1,268, -4352,1,269,4565,19, -1226,1,269,4352,1, -270,4566,19,1231,1, -270,4352,1,271,4567, -19,1251,1,271,4352, -1,272,4568,19,1241, -1,272,4352,1,273, -4569,19,1246,1,273, -4352,1,274,4570,19, -1236,1,274,4352,1, -275,4571,19,1591,1, -275,4352,1,276,4572, -19,1256,1,276,4352, -1,277,4573,19,1316, -1,277,4195,1,278, -4574,19,1650,1,278, -4265,1,279,4575,19, -1686,1,279,4265,1, -280,4576,19,1666,1, -280,4269,1,281,4577, -19,1985,1,281,3969, -1,282,4578,19,1980, -1,282,3969,1,283, -4579,19,1975,1,283, -3969,1,284,4580,19, -1970,1,284,3969,1, -285,4581,19,1965,1, -285,3969,1,286,4582, -19,1960,1,286,3969, -1,287,4583,19,1955, -1,287,3969,1,288, -4584,19,1944,1,288, -3989,1,289,4585,19, -1939,1,289,3989,1, -290,4586,19,1934,1, -290,3989,1,291,4587, -19,1929,1,291,3989, -1,292,4588,19,1924, -1,292,3989,1,293, -4589,19,1919,1,293, -3989,1,294,4590,19, -1914,1,294,3989,1, -295,4591,19,1909,1, -295,3989,1,296,4592, -19,1904,1,296,3989, -1,297,4593,19,1739, -1,297,3989,1,298, -4594,19,1898,1,298, -3989,1,299,4595,19, -1893,1,299,3989,1, -300,4596,19,1888,1, -300,3989,1,301,4597, -19,1732,1,301,3989, -1,302,4598,19,1883, -1,302,3989,1,303, -4599,19,1878,1,303, -3989,1,304,4600,19, -1873,1,304,3989,1, -305,4601,19,1868,1, -305,3989,1,306,4602, -19,1863,1,306,3989, -1,307,4603,19,1858, -1,307,3989,1,308, -4604,19,1725,1,308, -3989,1,309,4605,19, -1852,1,309,3989,1, -310,4606,19,1847,1, -310,3989,1,311,4607, -19,1842,1,311,3989, -1,312,4608,19,1719, -1,312,3989,1,313, -4609,19,1836,1,313, -3989,1,314,4610,19, -1767,1,314,3989,1, -315,4611,19,1831,1, -315,3989,1,316,4612, -19,1826,1,316,3989, -1,317,4613,19,1821, -1,317,3989,1,318, -4614,19,1816,1,318, -3989,1,319,4615,19, -1811,1,319,3989,1, -320,4616,19,1806,1, -320,3989,1,321,4617, -19,1801,1,321,3989, -1,322,4618,19,4619, +110,0,76,0,105, +0,115,0,116,0, +95,0,51,0,1, +322,3909,1,323,4584, +19,4585,4,28,65, +0,114,0,103,0, +117,0,109,0,101, +0,110,0,116,0, +76,0,105,0,115, +0,116,0,95,0, +51,0,1,323,4229, +1,324,4586,19,4587, 4,50,65,0,114, 0,103,0,117,0, 109,0,101,0,110, @@ -10739,16 +10737,16 @@ public yyLSLSyntax 0,111,0,110,0, 76,0,105,0,115, 0,116,0,95,0, -51,0,1,322,3945, -1,323,4620,19,4621, +52,0,1,324,3909, +1,325,4588,19,4589, 4,28,65,0,114, 0,103,0,117,0, 109,0,101,0,110, 0,116,0,76,0, 105,0,115,0,116, -0,95,0,51,0, -1,323,4265,1,324, -4622,19,4623,4,50, +0,95,0,52,0, +1,325,4229,1,326, +4590,19,4591,4,50, 65,0,114,0,103, 0,117,0,109,0, 101,0,110,0,116, @@ -10758,28 +10756,8 @@ public yyLSLSyntax 116,0,105,0,111, 0,110,0,76,0, 105,0,115,0,116, -0,95,0,52,0, -1,324,3945,1,325, -4624,19,4625,4,28, -65,0,114,0,103, -0,117,0,109,0, -101,0,110,0,116, -0,76,0,105,0, -115,0,116,0,95, -0,52,0,1,325, -4265,1,326,4626,19, -4627,4,50,65,0, -114,0,103,0,117, -0,109,0,101,0, -110,0,116,0,68, -0,101,0,99,0, -108,0,97,0,114, -0,97,0,116,0, -105,0,111,0,110, -0,76,0,105,0, -115,0,116,0,95, -0,53,0,1,326, -3945,2,0,0}; +0,95,0,53,0, +1,326,3909,2,0,0}; new Sfactory(this,"ExpressionArgument_1",new SCreator(ExpressionArgument_1_factory)); new Sfactory(this,"SimpleAssignment_8",new SCreator(SimpleAssignment_8_factory)); new Sfactory(this,"StatementList_1",new SCreator(StatementList_1_factory)); -- cgit v1.1 From 71ba85137f6b85db7c617bd6ee8ef2081b9fab61 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 11 Jun 2012 16:45:52 +0100 Subject: Commitig the Avination implementation of llTeleportAgent and llTeleportAgentGlobalCoords. These do NOT use PERMISSION_TELEPORT like their SL counterparts because that permission is not yet understood by TPVs based on v1.x. --- .../Shared/Api/Implementation/LSL_Api.cs | 94 ++++++++++++++++++++++ .../ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | 2 + .../ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs | 10 +++ 3 files changed, 106 insertions(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index fb0fdc9..89f2068 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4169,6 +4169,100 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScriptSleep(5000); } + public void llTeleportAgent(string agent, string destination, LSL_Vector pos, LSL_Vector lookAt) + { + m_host.AddScriptLPS(1); + UUID agentId = new UUID(); + + Vector3 targetPos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z); + Vector3 targetLookAt = new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z); + + if (UUID.TryParse(agent, out agentId)) + { + ScenePresence presence = World.GetScenePresence(agentId); + if (presence != null && presence.PresenceType != PresenceType.Npc) + { + // agent must not be a god + if (presence.GodLevel >= 200) return; + + if (destination == String.Empty) + destination = World.RegionInfo.RegionName; + + // agent must be over the owners land + if (m_host.OwnerID == World.LandChannel.GetLandObject( + presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) + { + DoLLTeleport(presence, destination, targetPos, targetLookAt); + } + else // or must be wearing the prim + { + if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) + { + DoLLTeleport(presence, destination, targetPos, targetLookAt); + } + } + } + } + } + + public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector pos, LSL_Vector lookAt) + { + m_host.AddScriptLPS(1); + UUID agentId = new UUID(); + + ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y); + + Vector3 targetPos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z); + Vector3 targetLookAt = new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z); + if (UUID.TryParse(agent, out agentId)) + { + ScenePresence presence = World.GetScenePresence(agentId); + if (presence != null && presence.PresenceType != PresenceType.Npc) + { + // agent must not be a god + if (presence.GodLevel >= 200) return; + + // agent must be over the owners land + if (m_host.OwnerID == World.LandChannel.GetLandObject( + presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) + { + World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); + } + else // or must be wearing the prim + { + if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) + { + World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); + } + } + } + } + } + + private void DoLLTeleport(ScenePresence sp, string destination, Vector3 targetPos, Vector3 targetLookAt) + { + UUID assetID = KeyOrName(destination); + + // The destinaion is not an asset ID and also doesn't name a landmark. + // Use it as a sim name + if (assetID == UUID.Zero) + { + World.RequestTeleportLocation(sp.ControllingClient, destination, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); + return; + } + + AssetBase lma = World.AssetService.Get(assetID.ToString()); + if (lma == null) + return; + + if (lma.Type != (sbyte)AssetType.Landmark) + return; + + AssetLandmark lm = new AssetLandmark(lma); + + World.RequestTeleportLocation(sp.ControllingClient, lm.RegionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); + } + public void llTextBox(string agent, string message, int chatChannel) { IDialogModule dm = World.RequestModuleInterface(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 7f5d1fe..d39b204 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -403,6 +403,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llTargetOmega(LSL_Vector axis, double spinrate, double gain); void llTargetRemove(int number); void llTeleportAgentHome(string agent); + void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt); + void llTeleportAgentGlobalCoords(string agent, LSL_Vector global, LSL_Vector pos, LSL_Vector lookAt); void llTextBox(string avatar, string message, int chat_channel); LSL_String llToLower(string source); LSL_String llToUpper(string source); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index c0bf29c..06f5617 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -1833,6 +1833,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llTargetRemove(number); } + public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt) + { + m_LSL_Functions.llTeleportAgent(agent, simname, pos, lookAt); + } + + public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global, LSL_Vector pos, LSL_Vector lookAt) + { + m_LSL_Functions.llTeleportAgentGlobalCoords(agent, global, pos, lookAt); + } + public void llTeleportAgentHome(string agent) { m_LSL_Functions.llTeleportAgentHome(agent); -- cgit v1.1 From a927787434a952bc12d7255b2de8ac723c6fd6cc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Jun 2012 23:30:11 +0100 Subject: Add last frame time monitor to MonitorModule now that this value is useful --- OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs index 4a8c369..e135c21 100644 --- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs @@ -341,6 +341,14 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring m => m.Scene.StatsReporter.LastReportedSimStats[11], m => string.Format("{0} ms", m.GetValue()))); + m_staticMonitors.Add( + new GenericMonitor( + m_scene, + "SpareFrameTimeMonitor", + "Spare Frame Time", + m => m.Scene.StatsReporter.LastReportedSimStats[21], + m => string.Format("{0} ms", m.GetValue()))); + m_alerts.Add(new DeadlockAlert(m_staticMonitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor)); foreach (IAlert alert in m_alerts) -- cgit v1.1 From daad0a3e110699660c12e30283597db1a7344984 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Jun 2012 23:30:58 +0100 Subject: Revert "Bind ~ and ! operators in LSL tighter in order to resolve issues in LSL where these aren't evaluated propertly." This reverts commit a8a9d13dc07bc9e23ebf439cbea5ece6ae002315. Accidentally committed, this patch might not be the correct approach. --- .../ScriptEngine/Shared/CodeTools/lsl.parser.cs | 7936 ++++++++++---------- 1 file changed, 3979 insertions(+), 3957 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.parser.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.parser.cs index 8428c96..ca56cd6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.parser.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.parser.cs @@ -6338,488 +6338,494 @@ public yyLSLSyntax 16,0,488,1,74, 1253,1,328,1302,1, 1048,2014,16,0,488, -1,82,1280,1,1840, -2015,16,0,488,1, -1591,2016,16,0,488, -1,1341,2017,16,0, -488,1,1096,1312,1, -93,1318,1,352,1349, -1,107,1338,1,1114, -1343,1,118,2018,16, -0,488,1,1123,2019, -16,0,488,1,371, -1365,1,1628,2020,16, -0,488,1,375,1376, -1,1882,2021,16,0, -488,1,377,1381,1, -379,1386,1,380,1391, -1,883,2022,16,0, -488,1,373,1409,1, -130,2023,16,0,488, -1,143,2024,16,0, -488,1,387,2025,16, -0,488,1,2664,2026, -16,0,488,1,1159, -2027,16,0,488,1, -157,2028,16,0,488, -1,1413,2029,16,0, -488,1,1665,2030,16, -0,488,1,412,2031, -16,0,488,1,1377, -2032,16,0,488,1, -172,2033,16,0,488, -1,1939,2034,16,0, -488,1,437,2035,16, -0,488,1,188,2036, -16,0,488,1,942, -2037,16,0,488,1, -1195,2038,16,0,488, -1,1449,2039,16,0, -488,1,1701,2040,16, -0,488,1,447,1511, -1,205,2041,16,0, -488,1,827,2042,16, -0,488,1,223,2043, -16,0,488,1,476, -1543,1,477,1549,1, -1231,2044,16,0,488, +1,82,2015,16,0, +488,1,1840,2016,16, +0,488,1,1591,2017, +16,0,488,1,1341, +2018,16,0,488,1, +1096,1312,1,93,1318, +1,352,1349,1,107, +2019,16,0,488,1, +1114,1343,1,118,2020, +16,0,488,1,1123, +2021,16,0,488,1, +371,1365,1,1628,2022, +16,0,488,1,375, +1376,1,1882,2023,16, +0,488,1,377,1381, +1,379,1386,1,380, +1391,1,883,2024,16, +0,488,1,373,1409, +1,130,2025,16,0, +488,1,143,2026,16, +0,488,1,387,2027, +16,0,488,1,2664, +2028,16,0,488,1, +1159,2029,16,0,488, +1,157,2030,16,0, +488,1,1413,2031,16, +0,488,1,1665,2032, +16,0,488,1,412, +2033,16,0,488,1, +1377,2034,16,0,488, +1,172,2035,16,0, +488,1,1939,2036,16, +0,488,1,437,2037, +16,0,488,1,188, +2038,16,0,488,1, +942,2039,16,0,488, +1,1195,2040,16,0, +488,1,1449,2041,16, +0,488,1,1701,2042, +16,0,488,1,447, +1511,1,205,2043,16, +0,488,1,827,2044, +16,0,488,1,223, +2045,16,0,488,1, +476,1543,1,477,1549, +1,1231,2046,16,0, +488,1,479,1559,1, +480,1564,1,1485,2047, +16,0,488,1,1737, +2048,16,0,488,1, +242,2049,16,0,488, +1,478,1583,1,1001, +1588,1,1002,1593,1, +19,2050,19,225,1, +19,2051,5,176,1, +256,2052,16,0,223, +1,1261,2053,16,0, +223,1,1011,1102,1, +1012,2054,16,0,455, +1,2458,876,1,262, +1119,1,1267,2055,16, +0,455,1,2021,718, +1,1521,2056,16,0, +455,1,1775,2057,16, +0,223,1,2029,725, +1,2030,731,1,2031, +736,1,2032,741,1, +2033,746,1,277,2058, +16,0,223,1,2035, +752,1,2037,757,1, +2039,762,1,32,2059, +16,0,223,1,2464, +899,1,2293,2060,16, +0,223,1,2043,774, +1,2045,779,1,2299, +2061,16,0,455,1, +41,2062,16,0,223, +1,42,2063,16,0, +455,1,40,1177,1, +44,1183,1,43,2064, +16,0,223,1,1804, +2065,16,0,223,1, +48,1190,1,49,1196, +1,47,1184,1,51, +1206,1,52,2066,16, +0,223,1,50,1201, +1,305,1211,1,1096, +1312,1,1515,2067,16, +0,223,1,2318,2068, +16,0,223,1,283, +1172,1,63,1222,1, +66,1228,1,67,1233, +1,68,1238,1,69, +1243,1,70,1248,1, +71,2069,16,0,223, +1,73,2070,16,0, +455,1,74,1253,1, +1013,1258,1,76,2071, +16,0,223,1,1834, +2072,16,0,223,1, +2337,2073,16,0,223, +1,79,2074,16,0, +223,1,1335,2075,16, +0,223,1,299,2076, +16,0,223,1,82, +2077,16,0,455,1, +1840,2078,16,0,455, +1,1297,2079,16,0, +223,1,85,2080,16, +0,223,1,1341,2081, +16,0,455,1,89, +2082,16,0,223,1, +1303,2083,16,0,455, +1,509,2084,16,0, +223,1,93,1318,1, +322,2085,16,0,223, +1,97,2086,16,0, +223,1,2041,768,1, +1555,2087,16,0,455, +1,827,2088,16,0, +455,1,102,2089,16, +0,223,1,1860,821, +1,1803,787,1,2364, +827,1,107,2090,16, +0,455,1,1114,1343, +1,112,2091,16,0, +223,1,1117,2092,16, +0,223,1,352,1349, +1,1873,835,1,118, +2093,16,0,455,1, +1123,2094,16,0,455, +1,371,1365,1,515, +2095,16,0,455,1, +1377,2096,16,0,455, +1,124,2097,16,0, +223,1,1882,2098,16, +0,455,1,377,1381, +1,379,1386,1,380, +1391,1,130,2099,16, +0,455,1,346,2100, +16,0,223,1,2075, +2101,16,0,223,1, +373,1409,1,387,2102, +16,0,455,1,137, +2103,16,0,223,1, +143,2104,16,0,455, +1,1901,2105,16,0, +223,1,1048,2106,16, +0,455,1,2658,2107, +16,0,223,1,1153, +2108,16,0,223,1, +375,1376,1,151,2109, +16,0,223,1,1407, +2110,16,0,223,1, +1659,2111,16,0,223, +1,2413,2112,16,0, +223,1,1159,2113,16, +0,455,1,381,2114, +16,0,223,1,157, +2115,16,0,455,1, +1413,2116,16,0,455, +1,883,2117,16,0, +455,1,1371,2118,16, +0,223,1,328,1302, +1,2105,814,1,2106, +2119,16,0,223,1, +166,2120,16,0,223, +1,525,2121,16,0, +223,1,1622,2122,16, +0,223,1,406,2123, +16,0,223,1,1574, +799,1,172,2124,16, +0,455,1,1931,861, +1,412,2125,16,0, +455,1,1933,2126,16, +0,223,1,1876,2127, +16,0,223,1,431, +2128,16,0,223,1, +1585,2129,16,0,223, +1,182,2130,16,0, +223,1,1628,2131,16, +0,455,1,1189,2132, +16,0,223,1,437, +2133,16,0,455,1, +1591,2134,16,0,455, +1,188,2135,16,0, +455,1,1695,2136,16, +0,223,1,2198,2137, +16,0,223,1,1195, +2138,16,0,455,1, +1449,2139,16,0,455, +1,1701,2140,16,0, +455,1,447,2141,16, +0,223,1,199,2142, +16,0,223,1,2459, +882,1,1958,2143,16, +0,223,1,2462,889, +1,1657,894,1,205, +2144,16,0,455,1, +459,2145,16,0,223, +1,462,2146,16,0, +223,1,1665,2147,16, +0,455,1,217,2148, +16,0,223,1,2227, +908,1,942,2149,16, +0,455,1,1225,2150, +16,0,223,1,223, +2151,16,0,455,1, +1479,2152,16,0,223, +1,1731,2153,16,0, +223,1,477,1549,1, +1231,2154,16,0,455, 1,479,1559,1,480, -1564,1,1485,2045,16, -0,488,1,1737,2046, -16,0,488,1,242, -2047,16,0,488,1, -478,1583,1,1001,1588, -1,1002,1593,1,19, -2048,19,225,1,19, -2049,5,176,1,256, -2050,16,0,223,1, -1261,2051,16,0,223, -1,1011,1102,1,1012, -2052,16,0,455,1, -2458,876,1,262,1119, -1,1267,2053,16,0, -455,1,2021,718,1, -1521,2054,16,0,455, -1,1775,2055,16,0, -223,1,2029,725,1, -2030,731,1,2031,736, -1,2032,741,1,2033, -746,1,277,2056,16, -0,223,1,2035,752, -1,2037,757,1,2039, -762,1,32,2057,16, -0,223,1,2464,899, -1,2293,2058,16,0, -223,1,2043,774,1, -2045,779,1,2299,2059, -16,0,455,1,41, -2060,16,0,223,1, -42,2061,16,0,455, -1,40,1177,1,44, -1183,1,43,2062,16, -0,223,1,1804,2063, -16,0,223,1,48, +1564,1,1485,2155,16, +0,455,1,1737,2156, +16,0,455,1,1989, +916,1,1990,2157,16, +0,223,1,1443,2158, +16,0,223,1,236, +2159,16,0,223,1, +2136,842,1,2664,2160, +16,0,455,1,476, +1543,1,242,2161,16, +0,455,1,478,1583, +1,1939,2162,16,0, +455,1,1001,1588,1, +1002,1593,1,1756,2163, +16,0,223,1,20, +2164,19,442,1,20, +2165,5,84,1,1011, +1102,1,1012,2166,16, +0,440,1,1013,1258, +1,262,1119,1,1267, +2167,16,0,440,1, +515,2168,16,0,440, +1,1521,2169,16,0, +440,1,525,1216,1, +283,1172,1,2299,2170, +16,0,440,1,42, +2171,16,0,440,1, +40,1177,1,44,1183, +1,47,1184,1,1303, +2172,16,0,440,1, +1555,2173,16,0,440, +1,50,1201,1,48, 1190,1,49,1196,1, -47,1184,1,51,1206, -1,52,2064,16,0, -223,1,50,1201,1, -305,1211,1,1096,1312, -1,1515,2065,16,0, -223,1,2318,2066,16, -0,223,1,283,1172, -1,63,1222,1,66, +51,1206,1,63,1222, +1,305,1211,1,66, 1228,1,67,1233,1, 68,1238,1,69,1243, -1,70,1248,1,71, -2067,16,0,223,1, -73,2068,16,0,455, -1,74,1253,1,1013, -1258,1,76,2069,16, -0,223,1,1834,2070, -16,0,223,1,2337, -2071,16,0,223,1, -79,2072,16,0,223, -1,1335,2073,16,0, -223,1,299,2074,16, -0,223,1,82,1280, -1,1840,2075,16,0, -455,1,1297,2076,16, -0,223,1,85,2077, -16,0,223,1,1341, -2078,16,0,455,1, -89,2079,16,0,223, -1,1303,2080,16,0, -455,1,509,2081,16, -0,223,1,93,1318, -1,322,2082,16,0, -223,1,97,2083,16, -0,223,1,2041,768, -1,1555,2084,16,0, -455,1,827,2085,16, -0,455,1,102,2086, -16,0,223,1,1860, -821,1,1803,787,1, -2364,827,1,107,1338, -1,1114,1343,1,112, -2087,16,0,223,1, -1117,2088,16,0,223, -1,352,1349,1,1873, -835,1,118,2089,16, -0,455,1,1123,2090, -16,0,455,1,371, -1365,1,515,2091,16, -0,455,1,1377,2092, -16,0,455,1,124, -2093,16,0,223,1, -1882,2094,16,0,455, -1,377,1381,1,379, -1386,1,380,1391,1, -130,2095,16,0,455, -1,346,2096,16,0, -223,1,2075,2097,16, -0,223,1,373,1409, -1,387,2098,16,0, -455,1,137,2099,16, -0,223,1,143,2100, -16,0,455,1,1901, -2101,16,0,223,1, -1048,2102,16,0,455, -1,2658,2103,16,0, -223,1,1153,2104,16, -0,223,1,375,1376, -1,151,2105,16,0, -223,1,1407,2106,16, -0,223,1,1659,2107, -16,0,223,1,2413, -2108,16,0,223,1, -1159,2109,16,0,455, -1,381,2110,16,0, -223,1,157,2111,16, -0,455,1,1413,2112, -16,0,455,1,883, -2113,16,0,455,1, -1371,2114,16,0,223, -1,328,1302,1,2105, -814,1,2106,2115,16, -0,223,1,166,2116, -16,0,223,1,525, -2117,16,0,223,1, -1622,2118,16,0,223, -1,406,2119,16,0, -223,1,1574,799,1, -172,2120,16,0,455, -1,1931,861,1,412, -2121,16,0,455,1, -1933,2122,16,0,223, -1,1876,2123,16,0, -223,1,431,2124,16, -0,223,1,1585,2125, -16,0,223,1,182, -2126,16,0,223,1, -1628,2127,16,0,455, -1,1189,2128,16,0, -223,1,437,2129,16, -0,455,1,1591,2130, -16,0,455,1,188, -2131,16,0,455,1, -1695,2132,16,0,223, -1,2198,2133,16,0, -223,1,1195,2134,16, -0,455,1,1449,2135, -16,0,455,1,1701, -2136,16,0,455,1, -447,2137,16,0,223, -1,199,2138,16,0, -223,1,2459,882,1, -1958,2139,16,0,223, -1,2462,889,1,1657, -894,1,205,2140,16, -0,455,1,459,2141, -16,0,223,1,462, -2142,16,0,223,1, -1665,2143,16,0,455, -1,217,2144,16,0, -223,1,2227,908,1, -942,2145,16,0,455, -1,1225,2146,16,0, -223,1,223,2147,16, -0,455,1,1479,2148, -16,0,223,1,1731, -2149,16,0,223,1, -477,1549,1,1231,2150, -16,0,455,1,479, +1,70,1248,1,73, +2174,16,0,440,1, +74,1253,1,328,2175, +16,0,440,1,1048, +2176,16,0,440,1, +82,2177,16,0,440, +1,1840,2178,16,0, +440,1,1591,2179,16, +0,440,1,1341,2180, +16,0,440,1,1096, +1312,1,93,1318,1, +352,2181,16,0,440, +1,107,2182,16,0, +440,1,1114,1343,1, +118,2183,16,0,440, +1,1123,2184,16,0, +440,1,371,1365,1, +1628,2185,16,0,440, +1,375,1376,1,1882, +2186,16,0,440,1, +377,1381,1,379,1386, +1,380,1391,1,883, +2187,16,0,440,1, +373,1409,1,130,2188, +16,0,440,1,143, +2189,16,0,440,1, +387,2190,16,0,440, +1,2664,2191,16,0, +440,1,1159,2192,16, +0,440,1,157,2193, +16,0,440,1,1413, +2194,16,0,440,1, +1665,2195,16,0,440, +1,412,2196,16,0, +440,1,1377,2197,16, +0,440,1,172,2198, +16,0,440,1,1939, +2199,16,0,440,1, +437,2200,16,0,440, +1,188,2201,16,0, +440,1,942,2202,16, +0,440,1,1195,2203, +16,0,440,1,1449, +2204,16,0,440,1, +1701,2205,16,0,440, +1,447,1511,1,205, +2206,16,0,440,1, +827,2207,16,0,440, +1,223,2208,16,0, +440,1,476,1543,1, +477,1549,1,1231,2209, +16,0,440,1,479, 1559,1,480,1564,1, -1485,2151,16,0,455, -1,1737,2152,16,0, -455,1,1989,916,1, -1990,2153,16,0,223, -1,1443,2154,16,0, -223,1,236,2155,16, -0,223,1,2136,842, -1,2664,2156,16,0, -455,1,476,1543,1, -242,2157,16,0,455, -1,478,1583,1,1939, -2158,16,0,455,1, -1001,1588,1,1002,1593, -1,1756,2159,16,0, -223,1,20,2160,19, -442,1,20,2161,5, +1485,2210,16,0,440, +1,1737,2211,16,0, +440,1,242,2212,16, +0,440,1,478,1583, +1,1001,1588,1,1002, +1593,1,21,2213,19, +432,1,21,2214,5, 84,1,1011,1102,1, -1012,2162,16,0,440, +1012,2215,16,0,430, 1,1013,1258,1,262, -1119,1,1267,2163,16, -0,440,1,515,2164, -16,0,440,1,1521, -2165,16,0,440,1, +1119,1,1267,2216,16, +0,430,1,515,2217, +16,0,430,1,1521, +2218,16,0,430,1, 525,1216,1,283,1172, -1,2299,2166,16,0, -440,1,42,2167,16, -0,440,1,40,1177, +1,2299,2219,16,0, +430,1,42,2220,16, +0,430,1,40,1177, 1,44,1183,1,47, -1184,1,1303,2168,16, -0,440,1,1555,2169, -16,0,440,1,50, +1184,1,1303,2221,16, +0,430,1,1555,2222, +16,0,430,1,50, 1201,1,48,1190,1, 49,1196,1,51,1206, 1,63,1222,1,305, 1211,1,66,1228,1, 67,1233,1,68,1238, 1,69,1243,1,70, -1248,1,73,2170,16, -0,440,1,74,1253, -1,328,2171,16,0, -440,1,1048,2172,16, -0,440,1,82,1280, -1,1840,2173,16,0, -440,1,1591,2174,16, -0,440,1,1341,2175, -16,0,440,1,1096, -1312,1,93,1318,1, -352,2176,16,0,440, -1,107,1338,1,1114, -1343,1,118,2177,16, -0,440,1,1123,2178, -16,0,440,1,371, -1365,1,1628,2179,16, -0,440,1,375,1376, -1,1882,2180,16,0, -440,1,377,1381,1, -379,1386,1,380,1391, -1,883,2181,16,0, -440,1,373,1409,1, -130,2182,16,0,440, -1,143,2183,16,0, -440,1,387,2184,16, -0,440,1,2664,2185, -16,0,440,1,1159, -2186,16,0,440,1, -157,2187,16,0,440, -1,1413,2188,16,0, -440,1,1665,2189,16, -0,440,1,412,2190, -16,0,440,1,1377, -2191,16,0,440,1, -172,2192,16,0,440, -1,1939,2193,16,0, -440,1,437,2194,16, -0,440,1,188,2195, -16,0,440,1,942, -2196,16,0,440,1, -1195,2197,16,0,440, -1,1449,2198,16,0, -440,1,1701,2199,16, -0,440,1,447,1511, -1,205,2200,16,0, -440,1,827,2201,16, -0,440,1,223,2202, -16,0,440,1,476, -1543,1,477,1549,1, -1231,2203,16,0,440, -1,479,1559,1,480, -1564,1,1485,2204,16, -0,440,1,1737,2205, -16,0,440,1,242, -2206,16,0,440,1, -478,1583,1,1001,1588, -1,1002,1593,1,21, -2207,19,432,1,21, -2208,5,84,1,1011, -1102,1,1012,2209,16, -0,430,1,1013,1258, -1,262,1119,1,1267, -2210,16,0,430,1, -515,2211,16,0,430, -1,1521,2212,16,0, -430,1,525,1216,1, -283,1172,1,2299,2213, -16,0,430,1,42, -2214,16,0,430,1, -40,1177,1,44,1183, -1,47,1184,1,1303, -2215,16,0,430,1, -1555,2216,16,0,430, -1,50,1201,1,48, -1190,1,49,1196,1, -51,1206,1,63,1222, -1,305,1211,1,66, -1228,1,67,1233,1, -68,1238,1,69,1243, -1,70,1248,1,73, -2217,16,0,430,1, -74,1253,1,328,2218, -16,0,430,1,1048, -2219,16,0,430,1, -82,1280,1,1840,2220, -16,0,430,1,1591, -2221,16,0,430,1, -1341,2222,16,0,430, -1,1096,1312,1,93, -1318,1,352,2223,16, -0,430,1,107,1338, -1,1114,1343,1,118, -2224,16,0,430,1, -1123,2225,16,0,430, -1,371,1365,1,1628, -2226,16,0,430,1, -375,1376,1,1882,2227, -16,0,430,1,377, -1381,1,379,1386,1, -380,1391,1,883,2228, -16,0,430,1,373, -1409,1,130,2229,16, -0,430,1,143,2230, -16,0,430,1,387, +1248,1,73,2223,16, +0,430,1,74,1253, +1,328,2224,16,0, +430,1,1048,2225,16, +0,430,1,82,2226, +16,0,430,1,1840, +2227,16,0,430,1, +1591,2228,16,0,430, +1,1341,2229,16,0, +430,1,1096,1312,1, +93,1318,1,352,2230, +16,0,430,1,107, 2231,16,0,430,1, -2664,2232,16,0,430, -1,1159,2233,16,0, -430,1,157,2234,16, -0,430,1,1413,2235, -16,0,430,1,1665, -2236,16,0,430,1, -412,2237,16,0,430, -1,1377,2238,16,0, -430,1,172,2239,16, -0,430,1,1939,2240, -16,0,430,1,437, -2241,16,0,430,1, -188,2242,16,0,430, -1,942,2243,16,0, -430,1,1195,2244,16, -0,430,1,1449,2245, -16,0,430,1,1701, -2246,16,0,430,1, -447,1511,1,205,2247, -16,0,430,1,827, -2248,16,0,430,1, -223,2249,16,0,430, -1,476,1543,1,477, -1549,1,1231,2250,16, -0,430,1,479,1559, -1,480,1564,1,1485, -2251,16,0,430,1, -1737,2252,16,0,430, -1,242,2253,16,0, -430,1,478,1583,1, -1001,1588,1,1002,1593, -1,22,2254,19,383, -1,22,2255,5,84, -1,1011,1102,1,1012, -2256,16,0,381,1, -1013,1258,1,262,1119, -1,1267,2257,16,0, -381,1,515,2258,16, -0,381,1,1521,2259, -16,0,381,1,525, -1216,1,283,1172,1, -2299,2260,16,0,381, -1,42,2261,16,0, -381,1,40,1177,1, -44,1183,1,47,1184, -1,1303,2262,16,0, -381,1,1555,2263,16, -0,381,1,50,1201, -1,48,1190,1,49, -1196,1,51,1206,1, -63,1222,1,305,1211, -1,66,1228,1,67, -1233,1,68,1238,1, -69,1243,1,70,1248, -1,73,2264,16,0, -381,1,74,1253,1, -328,2265,16,0,381, -1,1048,2266,16,0, -381,1,82,1280,1, -1840,2267,16,0,381, -1,1591,2268,16,0, -381,1,1341,2269,16, -0,381,1,1096,1312, -1,93,1318,1,352, -2270,16,0,381,1, -107,1338,1,1114,1343, -1,118,2271,16,0, -381,1,1123,2272,16, +1114,1343,1,118,2232, +16,0,430,1,1123, +2233,16,0,430,1, +371,1365,1,1628,2234, +16,0,430,1,375, +1376,1,1882,2235,16, +0,430,1,377,1381, +1,379,1386,1,380, +1391,1,883,2236,16, +0,430,1,373,1409, +1,130,2237,16,0, +430,1,143,2238,16, +0,430,1,387,2239, +16,0,430,1,2664, +2240,16,0,430,1, +1159,2241,16,0,430, +1,157,2242,16,0, +430,1,1413,2243,16, +0,430,1,1665,2244, +16,0,430,1,412, +2245,16,0,430,1, +1377,2246,16,0,430, +1,172,2247,16,0, +430,1,1939,2248,16, +0,430,1,437,2249, +16,0,430,1,188, +2250,16,0,430,1, +942,2251,16,0,430, +1,1195,2252,16,0, +430,1,1449,2253,16, +0,430,1,1701,2254, +16,0,430,1,447, +1511,1,205,2255,16, +0,430,1,827,2256, +16,0,430,1,223, +2257,16,0,430,1, +476,1543,1,477,1549, +1,1231,2258,16,0, +430,1,479,1559,1, +480,1564,1,1485,2259, +16,0,430,1,1737, +2260,16,0,430,1, +242,2261,16,0,430, +1,478,1583,1,1001, +1588,1,1002,1593,1, +22,2262,19,383,1, +22,2263,5,84,1, +1011,1102,1,1012,2264, +16,0,381,1,1013, +1258,1,262,1119,1, +1267,2265,16,0,381, +1,515,2266,16,0, +381,1,1521,2267,16, +0,381,1,525,1216, +1,283,1172,1,2299, +2268,16,0,381,1, +42,2269,16,0,381, +1,40,1177,1,44, +1183,1,47,1184,1, +1303,2270,16,0,381, +1,1555,2271,16,0, +381,1,50,1201,1, +48,1190,1,49,1196, +1,51,1206,1,63, +1222,1,305,1211,1, +66,1228,1,67,1233, +1,68,1238,1,69, +1243,1,70,1248,1, +73,2272,16,0,381, +1,74,1253,1,328, +2273,16,0,381,1, +1048,2274,16,0,381, +1,82,2275,16,0, +381,1,1840,2276,16, +0,381,1,1591,2277, +16,0,381,1,1341, +2278,16,0,381,1, +1096,1312,1,93,1318, +1,352,2279,16,0, +381,1,107,2280,16, +0,381,1,1114,1343, +1,118,2281,16,0, +381,1,1123,2282,16, 0,381,1,371,1365, -1,1628,2273,16,0, +1,1628,2283,16,0, 381,1,375,1376,1, -1882,2274,16,0,381, +1882,2284,16,0,381, 1,377,1381,1,379, 1386,1,380,1391,1, -883,2275,16,0,381, +883,2285,16,0,381, 1,373,1409,1,130, -2276,16,0,381,1, -143,2277,16,0,381, -1,387,2278,16,0, -381,1,2664,2279,16, -0,381,1,1159,2280, +2286,16,0,381,1, +143,2287,16,0,381, +1,387,2288,16,0, +381,1,2664,2289,16, +0,381,1,1159,2290, 16,0,381,1,157, -2281,16,0,381,1, -1413,2282,16,0,381, -1,1665,2283,16,0, -381,1,412,2284,16, -0,381,1,1377,2285, +2291,16,0,381,1, +1413,2292,16,0,381, +1,1665,2293,16,0, +381,1,412,2294,16, +0,381,1,1377,2295, 16,0,381,1,172, -2286,16,0,381,1, -1939,2287,16,0,381, -1,437,2288,16,0, -381,1,188,2289,16, -0,381,1,942,2290, +2296,16,0,381,1, +1939,2297,16,0,381, +1,437,2298,16,0, +381,1,188,2299,16, +0,381,1,942,2300, 16,0,381,1,1195, -2291,16,0,381,1, -1449,2292,16,0,381, -1,1701,2293,16,0, +2301,16,0,381,1, +1449,2302,16,0,381, +1,1701,2303,16,0, 381,1,447,1511,1, -205,2294,16,0,381, -1,827,2295,16,0, -381,1,223,2296,16, +205,2304,16,0,381, +1,827,2305,16,0, +381,1,223,2306,16, 0,381,1,476,1543, 1,477,1549,1,1231, -2297,16,0,381,1, +2307,16,0,381,1, 479,1559,1,480,1564, -1,1485,2298,16,0, -381,1,1737,2299,16, -0,381,1,242,2300, +1,1485,2308,16,0, +381,1,1737,2309,16, +0,381,1,242,2310, 16,0,381,1,478, 1583,1,1001,1588,1, -1002,1593,1,23,2301, -19,504,1,23,2302, -5,38,1,1901,2303, +1002,1593,1,23,2311, +19,504,1,23,2312, +5,38,1,1901,2313, 16,0,502,1,2075, -2304,16,0,502,1, +2314,16,0,502,1, 1860,821,1,1803,787, -1,1804,2305,16,0, -502,1,2413,2306,16, -0,502,1,2198,2307, +1,1804,2315,16,0, +502,1,2413,2316,16, +0,502,1,2198,2317, 16,0,502,1,1873, 835,1,1657,894,1, -1989,916,1,1990,2308, +1989,916,1,1990,2318, 16,0,502,1,1775, -2309,16,0,502,1, -32,2310,16,0,502, +2319,16,0,502,1, +32,2320,16,0,502, 1,2105,814,1,2106, -2311,16,0,502,1, +2321,16,0,502,1, 2364,827,1,2227,908, -1,2337,2312,16,0, +1,2337,2322,16,0, 502,1,2021,718,1, 2458,876,1,2459,882, 1,2462,889,1,2136, @@ -6832,1195 +6838,1207 @@ public yyLSLSyntax 861,1,2041,768,1, 2043,774,1,2045,779, 1,1574,799,1,1958, -2313,16,0,502,1, -24,2314,19,177,1, -24,2315,5,5,1, -44,2316,16,0,175, -1,377,2317,16,0, -540,1,40,2318,16, -0,674,1,63,2319, +2323,16,0,502,1, +24,2324,19,177,1, +24,2325,5,5,1, +44,2326,16,0,175, +1,377,2327,16,0, +540,1,40,2328,16, +0,674,1,63,2329, 16,0,196,1,373, -2320,16,0,536,1, -25,2321,19,291,1, -25,2322,5,177,1, -256,2323,16,0,545, -1,1261,2324,16,0, +2330,16,0,536,1, +25,2331,19,291,1, +25,2332,5,177,1, +256,2333,16,0,545, +1,1261,2334,16,0, 545,1,1011,1102,1, -1012,2325,16,0,289, +1012,2335,16,0,289, 1,2458,876,1,262, -1119,1,1267,2326,16, +1119,1,1267,2336,16, 0,289,1,2021,718, -1,1521,2327,16,0, -289,1,1775,2328,16, +1,1521,2337,16,0, +289,1,1775,2338,16, 0,545,1,2029,725, 1,2030,731,1,2031, 736,1,2032,741,1, -2033,746,1,277,2329, +2033,746,1,277,2339, 16,0,545,1,2035, 752,1,2037,757,1, -2039,762,1,32,2330, +2039,762,1,32,2340, 16,0,545,1,2464, -899,1,2293,2331,16, +899,1,2293,2341,16, 0,545,1,2043,774, 1,2045,779,1,2299, -2332,16,0,289,1, -41,2333,16,0,545, -1,42,2334,16,0, +2342,16,0,289,1, +41,2343,16,0,545, +1,42,2344,16,0, 289,1,40,1177,1, -44,1183,1,43,2335, +44,1183,1,43,2345, 16,0,545,1,1804, -2336,16,0,545,1, +2346,16,0,545,1, 48,1190,1,49,1196, 1,47,1184,1,51, -1206,1,52,2337,16, +1206,1,52,2347,16, 0,545,1,50,1201, 1,305,1211,1,1096, -1312,1,1515,2338,16, -0,545,1,2318,2339, +1312,1,1515,2348,16, +0,545,1,2318,2349, 16,0,545,1,62, -2340,16,0,545,1, +2350,16,0,545,1, 63,1222,1,66,1228, 1,67,1233,1,68, 1238,1,69,1243,1, -70,1248,1,71,2341, +70,1248,1,71,2351, 16,0,545,1,283, -1172,1,73,2342,16, +1172,1,73,2352,16, 0,289,1,74,1253, 1,1013,1258,1,76, -2343,16,0,545,1, -1834,2344,16,0,545, -1,2337,2345,16,0, -545,1,79,2346,16, -0,545,1,1335,2347, +2353,16,0,545,1, +1834,2354,16,0,545, +1,2337,2355,16,0, +545,1,79,2356,16, +0,545,1,1335,2357, 16,0,545,1,299, -2348,16,0,545,1, -82,1280,1,1840,2349, -16,0,289,1,1297, -2350,16,0,545,1, -85,2351,16,0,545, -1,1341,2352,16,0, -289,1,89,2353,16, -0,545,1,1303,2354, -16,0,289,1,509, -2355,16,0,545,1, -93,1318,1,322,2356, -16,0,545,1,97, -2357,16,0,545,1, -2041,768,1,1555,2358, -16,0,289,1,827, -2359,16,0,289,1, -102,2360,16,0,545, -1,1860,821,1,1803, -787,1,2364,827,1, -107,1338,1,1114,1343, -1,112,2361,16,0, -545,1,1117,2362,16, -0,545,1,352,1349, -1,1873,835,1,118, -1355,1,1123,2363,16, -0,289,1,371,1365, -1,515,2364,16,0, -289,1,1377,2365,16, -0,289,1,124,2366, -16,0,545,1,1882, -2367,16,0,289,1, -377,1381,1,379,1386, -1,380,1391,1,130, -1414,1,346,2368,16, -0,545,1,2075,2369, -16,0,545,1,373, -1409,1,387,2370,16, -0,289,1,137,2371, -16,0,545,1,143, -2372,16,0,289,1, -1901,2373,16,0,545, -1,1048,1344,1,2658, -2374,16,0,545,1, -1153,2375,16,0,545, -1,375,1376,1,151, -2376,16,0,545,1, -1407,2377,16,0,545, -1,1659,2378,16,0, -545,1,2413,2379,16, -0,545,1,1159,2380, -16,0,289,1,381, +2358,16,0,545,1, +82,2359,16,0,289, +1,1840,2360,16,0, +289,1,1297,2361,16, +0,545,1,85,2362, +16,0,545,1,1341, +2363,16,0,289,1, +89,2364,16,0,545, +1,1303,2365,16,0, +289,1,509,2366,16, +0,545,1,93,1318, +1,322,2367,16,0, +545,1,97,2368,16, +0,545,1,2041,768, +1,1555,2369,16,0, +289,1,827,2370,16, +0,289,1,102,2371, +16,0,545,1,1860, +821,1,1803,787,1, +2364,827,1,107,2372, +16,0,289,1,1114, +1343,1,112,2373,16, +0,545,1,1117,2374, +16,0,545,1,352, +1349,1,1873,835,1, +118,1355,1,1123,2375, +16,0,289,1,371, +1365,1,515,2376,16, +0,289,1,1377,2377, +16,0,289,1,124, +2378,16,0,545,1, +1882,2379,16,0,289, +1,377,1381,1,379, +1386,1,380,1391,1, +130,1414,1,346,2380, +16,0,545,1,2075, 2381,16,0,545,1, -157,2382,16,0,289, -1,1413,2383,16,0, -289,1,883,2384,16, -0,289,1,1371,2385, -16,0,545,1,328, -1302,1,2105,814,1, -2106,2386,16,0,545, -1,166,2387,16,0, -545,1,525,2388,16, -0,545,1,1622,2389, -16,0,545,1,406, -2390,16,0,545,1, -1574,799,1,172,1469, -1,1931,861,1,412, -2391,16,0,289,1, -1933,2392,16,0,545, -1,1876,2393,16,0, -545,1,431,2394,16, -0,545,1,1585,2395, -16,0,545,1,182, -2396,16,0,545,1, -1628,2397,16,0,289, -1,1189,2398,16,0, -545,1,437,2399,16, -0,289,1,1591,2400, -16,0,289,1,188, -1518,1,1695,2401,16, -0,545,1,2198,2402, -16,0,545,1,1195, -2403,16,0,289,1, -1449,2404,16,0,289, -1,1701,2405,16,0, -289,1,447,2406,16, -0,545,1,199,2407, -16,0,545,1,2459, -882,1,1958,2408,16, -0,545,1,2462,889, -1,1657,894,1,205, -2409,16,0,289,1, -459,2410,16,0,545, -1,462,2411,16,0, -545,1,1665,2412,16, -0,289,1,217,2413, -16,0,545,1,2227, -908,1,942,1490,1, -1225,2414,16,0,545, -1,223,2415,16,0, -289,1,1479,2416,16, -0,545,1,1731,2417, -16,0,545,1,477, -1549,1,1231,2418,16, -0,289,1,479,1559, +373,1409,1,387,2382, +16,0,289,1,137, +2383,16,0,545,1, +143,2384,16,0,289, +1,1901,2385,16,0, +545,1,1048,1344,1, +2658,2386,16,0,545, +1,1153,2387,16,0, +545,1,375,1376,1, +151,2388,16,0,545, +1,1407,2389,16,0, +545,1,1659,2390,16, +0,545,1,2413,2391, +16,0,545,1,1159, +2392,16,0,289,1, +381,2393,16,0,545, +1,157,2394,16,0, +289,1,1413,2395,16, +0,289,1,883,2396, +16,0,289,1,1371, +2397,16,0,545,1, +328,1302,1,2105,814, +1,2106,2398,16,0, +545,1,166,2399,16, +0,545,1,525,2400, +16,0,545,1,1622, +2401,16,0,545,1, +406,2402,16,0,545, +1,1574,799,1,172, +1469,1,1931,861,1, +412,2403,16,0,289, +1,1933,2404,16,0, +545,1,1876,2405,16, +0,545,1,431,2406, +16,0,545,1,1585, +2407,16,0,545,1, +182,2408,16,0,545, +1,1628,2409,16,0, +289,1,1189,2410,16, +0,545,1,437,2411, +16,0,289,1,1591, +2412,16,0,289,1, +188,1518,1,1695,2413, +16,0,545,1,2198, +2414,16,0,545,1, +1195,2415,16,0,289, +1,1449,2416,16,0, +289,1,1701,2417,16, +0,289,1,447,2418, +16,0,545,1,199, +2419,16,0,545,1, +2459,882,1,1958,2420, +16,0,545,1,2462, +889,1,1657,894,1, +205,2421,16,0,289, +1,459,2422,16,0, +545,1,462,2423,16, +0,545,1,1665,2424, +16,0,289,1,217, +2425,16,0,545,1, +2227,908,1,942,1490, +1,1225,2426,16,0, +545,1,223,2427,16, +0,289,1,1479,2428, +16,0,545,1,1731, +2429,16,0,545,1, +477,1549,1,1231,2430, +16,0,289,1,479, +1559,1,480,1564,1, +1485,2431,16,0,289, +1,1737,2432,16,0, +289,1,1989,916,1, +1990,2433,16,0,545, +1,1443,2434,16,0, +545,1,236,2435,16, +0,545,1,2136,842, +1,2664,2436,16,0, +289,1,476,1543,1, +242,2437,16,0,289, +1,478,1583,1,1939, +2438,16,0,289,1, +1001,1588,1,1002,1593, +1,1756,2439,16,0, +545,1,26,2440,19, +308,1,26,2441,5, +84,1,1011,1102,1, +1012,2442,16,0,306, +1,1013,1258,1,262, +1119,1,1267,2443,16, +0,306,1,515,2444, +16,0,660,1,1521, +2445,16,0,306,1, +525,1216,1,283,1172, +1,2299,2446,16,0, +306,1,42,2447,16, +0,306,1,40,1177, +1,44,1183,1,47, +1184,1,1303,2448,16, +0,306,1,1555,2449, +16,0,306,1,50, +1201,1,48,1190,1, +49,1196,1,51,1206, +1,63,1222,1,305, +1211,1,66,1228,1, +67,1233,1,68,1238, +1,69,1243,1,70, +1248,1,73,2450,16, +0,306,1,74,1253, +1,328,1302,1,1048, +1344,1,82,2451,16, +0,306,1,1840,2452, +16,0,306,1,1591, +2453,16,0,306,1, +1341,2454,16,0,306, +1,1096,1312,1,93, +1318,1,352,1349,1, +107,2455,16,0,306, +1,1114,1343,1,118, +1355,1,1123,2456,16, +0,306,1,371,1365, +1,1628,2457,16,0, +306,1,375,1376,1, +1882,2458,16,0,306, +1,377,1381,1,379, +1386,1,380,1391,1, +883,2459,16,0,306, +1,373,1409,1,130, +1414,1,143,2460,16, +0,306,1,387,2461, +16,0,306,1,2664, +2462,16,0,306,1, +1159,2463,16,0,306, +1,157,2464,16,0, +306,1,1413,2465,16, +0,306,1,1665,2466, +16,0,306,1,412, +2467,16,0,306,1, +1377,2468,16,0,306, +1,172,1469,1,1939, +2469,16,0,306,1, +437,2470,16,0,588, +1,188,1518,1,942, +1490,1,1195,2471,16, +0,306,1,1449,2472, +16,0,306,1,1701, +2473,16,0,306,1, +447,1511,1,205,2474, +16,0,306,1,827, +2475,16,0,306,1, +223,2476,16,0,306, +1,476,1543,1,477, +1549,1,1231,2477,16, +0,306,1,479,1559, 1,480,1564,1,1485, -2419,16,0,289,1, -1737,2420,16,0,289, -1,1989,916,1,1990, -2421,16,0,545,1, -1443,2422,16,0,545, -1,236,2423,16,0, -545,1,2136,842,1, -2664,2424,16,0,289, -1,476,1543,1,242, -2425,16,0,289,1, -478,1583,1,1939,2426, -16,0,289,1,1001, -1588,1,1002,1593,1, -1756,2427,16,0,545, -1,26,2428,19,308, -1,26,2429,5,84, -1,1011,1102,1,1012, -2430,16,0,306,1, -1013,1258,1,262,1119, -1,1267,2431,16,0, -306,1,515,2432,16, -0,660,1,1521,2433, -16,0,306,1,525, -1216,1,283,1172,1, -2299,2434,16,0,306, -1,42,2435,16,0, -306,1,40,1177,1, -44,1183,1,47,1184, -1,1303,2436,16,0, -306,1,1555,2437,16, -0,306,1,50,1201, -1,48,1190,1,49, -1196,1,51,1206,1, -63,1222,1,305,1211, -1,66,1228,1,67, -1233,1,68,1238,1, -69,1243,1,70,1248, -1,73,2438,16,0, -306,1,74,1253,1, -328,1302,1,1048,1344, -1,82,1280,1,1840, -2439,16,0,306,1, -1591,2440,16,0,306, -1,1341,2441,16,0, -306,1,1096,1312,1, -93,1318,1,352,1349, -1,107,1338,1,1114, -1343,1,118,1355,1, -1123,2442,16,0,306, -1,371,1365,1,1628, -2443,16,0,306,1, -375,1376,1,1882,2444, -16,0,306,1,377, -1381,1,379,1386,1, -380,1391,1,883,2445, -16,0,306,1,373, -1409,1,130,1414,1, -143,2446,16,0,306, -1,387,2447,16,0, -306,1,2664,2448,16, -0,306,1,1159,2449, -16,0,306,1,157, -2450,16,0,306,1, -1413,2451,16,0,306, -1,1665,2452,16,0, -306,1,412,2453,16, -0,306,1,1377,2454, -16,0,306,1,172, -1469,1,1939,2455,16, -0,306,1,437,2456, -16,0,588,1,188, -1518,1,942,1490,1, -1195,2457,16,0,306, -1,1449,2458,16,0, -306,1,1701,2459,16, -0,306,1,447,1511, -1,205,2460,16,0, -306,1,827,2461,16, -0,306,1,223,2462, -16,0,306,1,476, -1543,1,477,1549,1, -1231,2463,16,0,306, -1,479,1559,1,480, -1564,1,1485,2464,16, -0,306,1,1737,2465, -16,0,306,1,242, -2466,16,0,306,1, -478,1583,1,1001,1588, -1,1002,1593,1,27, -2467,19,598,1,27, -2468,5,95,1,256, -2469,16,0,596,1, -1261,2470,16,0,596, -1,509,2471,16,0, -596,1,1515,2472,16, -0,596,1,2021,718, -1,1775,2473,16,0, -596,1,2029,725,1, -2030,731,1,2031,736, -1,2032,741,1,2033, -746,1,277,2474,16, -0,596,1,2035,752, -1,2037,757,1,2039, -762,1,32,2475,16, -0,596,1,2041,768, -1,2293,2476,16,0, -596,1,2043,774,1, -2045,779,1,41,2477, -16,0,596,1,1297, -2478,16,0,596,1, -43,2479,16,0,596, -1,1803,787,1,1804, -2480,16,0,596,1, -299,2481,16,0,596, -1,52,2482,16,0, -596,1,2318,2483,16, -0,596,1,62,2484, -16,0,596,1,2075, -2485,16,0,596,1, -1574,799,1,71,2486, -16,0,596,1,76, -2487,16,0,596,1, -1834,2488,16,0,596, -1,2337,2489,16,0, -596,1,79,2490,16, -0,596,1,1335,2491, -16,0,596,1,322, -2492,16,0,596,1, -85,2493,16,0,596, -1,89,2494,16,0, -596,1,346,2495,16, -0,596,1,2105,814, -1,2106,2496,16,0, -596,1,97,2497,16, -0,596,1,1860,821, -1,2364,827,1,102, -2498,16,0,596,1, -112,2499,16,0,596, -1,1117,2500,16,0, -596,1,1873,835,1, -1876,2501,16,0,596, -1,124,2502,16,0, -596,1,2136,842,1, -381,2503,16,0,596, -1,525,2504,16,0, -596,1,137,2505,16, -0,596,1,1901,2506, -16,0,596,1,2658, -2507,16,0,596,1, -1153,2508,16,0,596, -1,151,2509,16,0, -596,1,1407,2510,16, -0,596,1,1659,2511, -16,0,596,1,2413, -2512,16,0,596,1, -406,2513,16,0,596, -1,1371,2514,16,0, -596,1,166,2515,16, -0,596,1,1622,2516, -16,0,596,1,1931, -861,1,1933,2517,16, -0,596,1,431,2518, -16,0,596,1,1585, +2478,16,0,306,1, +1737,2479,16,0,306, +1,242,2480,16,0, +306,1,478,1583,1, +1001,1588,1,1002,1593, +1,27,2481,19,598, +1,27,2482,5,95, +1,256,2483,16,0, +596,1,1261,2484,16, +0,596,1,509,2485, +16,0,596,1,1515, +2486,16,0,596,1, +2021,718,1,1775,2487, +16,0,596,1,2029, +725,1,2030,731,1, +2031,736,1,2032,741, +1,2033,746,1,277, +2488,16,0,596,1, +2035,752,1,2037,757, +1,2039,762,1,32, +2489,16,0,596,1, +2041,768,1,2293,2490, +16,0,596,1,2043, +774,1,2045,779,1, +41,2491,16,0,596, +1,1297,2492,16,0, +596,1,43,2493,16, +0,596,1,1803,787, +1,1804,2494,16,0, +596,1,299,2495,16, +0,596,1,52,2496, +16,0,596,1,2318, +2497,16,0,596,1, +62,2498,16,0,596, +1,2075,2499,16,0, +596,1,1574,799,1, +71,2500,16,0,596, +1,76,2501,16,0, +596,1,1834,2502,16, +0,596,1,2337,2503, +16,0,596,1,79, +2504,16,0,596,1, +1335,2505,16,0,596, +1,322,2506,16,0, +596,1,85,2507,16, +0,596,1,89,2508, +16,0,596,1,346, +2509,16,0,596,1, +2105,814,1,2106,2510, +16,0,596,1,97, +2511,16,0,596,1, +1860,821,1,2364,827, +1,102,2512,16,0, +596,1,112,2513,16, +0,596,1,1117,2514, +16,0,596,1,1873, +835,1,1876,2515,16, +0,596,1,124,2516, +16,0,596,1,2136, +842,1,381,2517,16, +0,596,1,525,2518, +16,0,596,1,137, 2519,16,0,596,1, -182,2520,16,0,596, -1,1189,2521,16,0, -596,1,1443,2522,16, -0,596,1,1695,2523, -16,0,596,1,2198, +1901,2520,16,0,596, +1,2658,2521,16,0, +596,1,1153,2522,16, +0,596,1,151,2523, +16,0,596,1,1407, 2524,16,0,596,1, -447,2525,16,0,596, -1,2458,876,1,2459, -882,1,1958,2526,16, -0,596,1,2462,889, -1,1657,894,1,2464, -899,1,199,2527,16, -0,596,1,459,2528, -16,0,596,1,462, +1659,2525,16,0,596, +1,2413,2526,16,0, +596,1,406,2527,16, +0,596,1,1371,2528, +16,0,596,1,166, 2529,16,0,596,1, -217,2530,16,0,596, -1,2227,908,1,1225, +1622,2530,16,0,596, +1,1931,861,1,1933, 2531,16,0,596,1, -1479,2532,16,0,596, -1,1731,2533,16,0, -596,1,1989,916,1, -1990,2534,16,0,596, -1,236,2535,16,0, -596,1,1756,2536,16, -0,596,1,28,2537, -19,629,1,28,2538, -5,60,1,328,1302, -1,223,1533,1,1096, -1312,1,118,1355,1, -883,1397,1,525,1216, -1,1001,1588,1,130, -1414,1,459,1688,1, -1114,1343,1,352,1349, -1,447,1511,1,464, -1683,1,1011,1102,1, -1013,1258,1,242,1578, -1,143,1419,1,40, -1177,1,41,1659,1, -42,1662,1,479,1559, -1,44,1183,1,481, -1646,1,373,1409,1, -47,1184,1,157,1443, -1,49,1196,1,50, -1201,1,48,1190,1, -379,1386,1,380,1391, -1,51,1206,1,476, -1543,1,371,1365,1, -478,1583,1,1048,1344, -1,375,1376,1,172, -1469,1,262,1119,1, -283,1172,1,63,1222, +431,2532,16,0,596, +1,1585,2533,16,0, +596,1,182,2534,16, +0,596,1,1189,2535, +16,0,596,1,1443, +2536,16,0,596,1, +1695,2537,16,0,596, +1,2198,2538,16,0, +596,1,447,2539,16, +0,596,1,2458,876, +1,2459,882,1,1958, +2540,16,0,596,1, +2462,889,1,1657,894, +1,2464,899,1,199, +2541,16,0,596,1, +459,2542,16,0,596, +1,462,2543,16,0, +596,1,217,2544,16, +0,596,1,2227,908, +1,1225,2545,16,0, +596,1,1479,2546,16, +0,596,1,1731,2547, +16,0,596,1,1989, +916,1,1990,2548,16, +0,596,1,236,2549, +16,0,596,1,1756, +2550,16,0,596,1, +28,2551,19,629,1, +28,2552,5,60,1, +328,1302,1,223,1533, +1,1096,1312,1,118, +1355,1,883,1397,1, +525,1216,1,1001,1588, +1,130,1414,1,459, +1688,1,1114,1343,1, +352,1349,1,447,1511, +1,464,1683,1,1011, +1102,1,1013,1258,1, +242,1578,1,143,1419, +1,40,1177,1,41, +1659,1,42,1662,1, +479,1559,1,44,1183, +1,481,1646,1,373, +1409,1,47,1184,1, +157,1443,1,49,1196, +1,50,1201,1,48, +1190,1,379,1386,1, +380,1391,1,51,1206, +1,476,1543,1,371, +1365,1,478,1583,1, +1048,1344,1,375,1376, +1,172,1469,1,262, +1119,1,283,1172,1, +63,1222,1,67,1233, +1,68,1238,1,69, +1243,1,66,1228,1, +461,2553,16,0,627, +1,74,1253,1,377, +1381,1,1002,1593,1, +70,1248,1,188,1518, +1,82,1280,1,305, +1211,1,477,1549,1, +827,1331,1,93,1318, +1,480,1564,1,205, +1523,1,942,1490,1, +107,1338,1,29,2554, +19,280,1,29,2555, +5,84,1,1011,1102, +1,1012,2556,16,0, +278,1,1013,1258,1, +262,1119,1,1267,2557, +16,0,278,1,515, +2558,16,0,278,1, +1521,2559,16,0,278, +1,525,1216,1,283, +1172,1,2299,2560,16, +0,278,1,42,2561, +16,0,278,1,40, +1177,1,44,1183,1, +47,1184,1,1303,2562, +16,0,278,1,1555, +2563,16,0,278,1, +50,1201,1,48,1190, +1,49,1196,1,51, +1206,1,63,1222,1, +305,1211,1,66,1228, 1,67,1233,1,68, 1238,1,69,1243,1, -66,1228,1,461,2539, -16,0,627,1,74, -1253,1,377,1381,1, -1002,1593,1,70,1248, -1,188,1518,1,82, -1280,1,305,1211,1, -477,1549,1,827,1331, -1,93,1318,1,480, -1564,1,205,1523,1, -942,1490,1,107,1338, -1,29,2540,19,280, -1,29,2541,5,84, +70,1248,1,73,2564, +16,0,278,1,74, +1253,1,328,1302,1, +1048,1344,1,82,2565, +16,0,278,1,1840, +2566,16,0,278,1, +1591,2567,16,0,278, +1,1341,2568,16,0, +278,1,1096,1312,1, +93,1318,1,352,1349, +1,107,2569,16,0, +278,1,1114,1343,1, +118,1355,1,1123,2570, +16,0,278,1,371, +1365,1,1628,2571,16, +0,278,1,375,1376, +1,1882,2572,16,0, +278,1,377,1381,1, +379,1386,1,380,1391, +1,883,2573,16,0, +278,1,373,1409,1, +130,1414,1,143,1419, +1,387,2574,16,0, +278,1,2664,2575,16, +0,278,1,1159,2576, +16,0,278,1,157, +1443,1,1413,2577,16, +0,278,1,1665,2578, +16,0,278,1,412, +2579,16,0,278,1, +1377,2580,16,0,278, +1,172,1469,1,1939, +2581,16,0,278,1, +437,2582,16,0,278, +1,188,1518,1,942, +1490,1,1195,2583,16, +0,278,1,1449,2584, +16,0,278,1,1701, +2585,16,0,278,1, +447,1511,1,205,2586, +16,0,278,1,827, +2587,16,0,278,1, +223,2588,16,0,278, +1,476,1543,1,477, +1549,1,1231,2589,16, +0,278,1,479,1559, +1,480,1564,1,1485, +2590,16,0,278,1, +1737,2591,16,0,278, +1,242,2592,16,0, +278,1,478,1583,1, +1001,1588,1,1002,1593, +1,30,2593,19,268, +1,30,2594,5,84, 1,1011,1102,1,1012, -2542,16,0,278,1, +2595,16,0,266,1, 1013,1258,1,262,1119, -1,1267,2543,16,0, -278,1,515,2544,16, -0,278,1,1521,2545, -16,0,278,1,525, +1,1267,2596,16,0, +266,1,515,2597,16, +0,266,1,1521,2598, +16,0,266,1,525, 1216,1,283,1172,1, -2299,2546,16,0,278, -1,42,2547,16,0, -278,1,40,1177,1, +2299,2599,16,0,266, +1,42,2600,16,0, +266,1,40,1177,1, 44,1183,1,47,1184, -1,1303,2548,16,0, -278,1,1555,2549,16, -0,278,1,50,1201, +1,1303,2601,16,0, +266,1,1555,2602,16, +0,266,1,50,1201, 1,48,1190,1,49, 1196,1,51,1206,1, 63,1222,1,305,1211, 1,66,1228,1,67, 1233,1,68,1238,1, 69,1243,1,70,1248, -1,73,2550,16,0, -278,1,74,1253,1, +1,73,2603,16,0, +266,1,74,1253,1, 328,1302,1,1048,1344, -1,82,1280,1,1840, -2551,16,0,278,1, -1591,2552,16,0,278, -1,1341,2553,16,0, -278,1,1096,1312,1, -93,1318,1,352,1349, -1,107,1338,1,1114, -1343,1,118,1355,1, -1123,2554,16,0,278, -1,371,1365,1,1628, -2555,16,0,278,1, -375,1376,1,1882,2556, -16,0,278,1,377, -1381,1,379,1386,1, -380,1391,1,883,2557, -16,0,278,1,373, -1409,1,130,1414,1, -143,1419,1,387,2558, -16,0,278,1,2664, -2559,16,0,278,1, -1159,2560,16,0,278, -1,157,1443,1,1413, -2561,16,0,278,1, -1665,2562,16,0,278, -1,412,2563,16,0, -278,1,1377,2564,16, -0,278,1,172,1469, -1,1939,2565,16,0, -278,1,437,2566,16, -0,278,1,188,1518, -1,942,1490,1,1195, -2567,16,0,278,1, -1449,2568,16,0,278, -1,1701,2569,16,0, -278,1,447,1511,1, -205,2570,16,0,278, -1,827,2571,16,0, -278,1,223,2572,16, -0,278,1,476,1543, -1,477,1549,1,1231, -2573,16,0,278,1, -479,1559,1,480,1564, -1,1485,2574,16,0, -278,1,1737,2575,16, -0,278,1,242,2576, -16,0,278,1,478, -1583,1,1001,1588,1, -1002,1593,1,30,2577, -19,268,1,30,2578, -5,84,1,1011,1102, -1,1012,2579,16,0, -266,1,1013,1258,1, -262,1119,1,1267,2580, -16,0,266,1,515, -2581,16,0,266,1, -1521,2582,16,0,266, -1,525,1216,1,283, -1172,1,2299,2583,16, -0,266,1,42,2584, -16,0,266,1,40, -1177,1,44,1183,1, -47,1184,1,1303,2585, -16,0,266,1,1555, -2586,16,0,266,1, -50,1201,1,48,1190, -1,49,1196,1,51, -1206,1,63,1222,1, -305,1211,1,66,1228, -1,67,1233,1,68, -1238,1,69,1243,1, -70,1248,1,73,2587, -16,0,266,1,74, -1253,1,328,1302,1, -1048,1344,1,82,1280, -1,1840,2588,16,0, -266,1,1591,2589,16, -0,266,1,1341,2590, -16,0,266,1,1096, -1312,1,93,1318,1, -352,1349,1,107,1338, -1,1114,1343,1,118, -1355,1,1123,2591,16, -0,266,1,371,1365, -1,1628,2592,16,0, -266,1,375,1376,1, -1882,2593,16,0,266, -1,377,1381,1,379, -1386,1,380,1391,1, -883,2594,16,0,266, -1,373,1409,1,130, -1414,1,143,1419,1, -387,2595,16,0,266, -1,2664,2596,16,0, -266,1,1159,2597,16, -0,266,1,157,1443, -1,1413,2598,16,0, -266,1,1665,2599,16, -0,266,1,412,2600, -16,0,266,1,1377, -2601,16,0,266,1, -172,1469,1,1939,2602, -16,0,266,1,437, -2603,16,0,266,1, -188,1518,1,942,1490, -1,1195,2604,16,0, -266,1,1449,2605,16, -0,266,1,1701,2606, -16,0,266,1,447, -1511,1,205,2607,16, -0,266,1,827,2608, -16,0,266,1,223, -2609,16,0,266,1, -476,1543,1,477,1549, -1,1231,2610,16,0, -266,1,479,1559,1, -480,1564,1,1485,2611, -16,0,266,1,1737, +1,82,2604,16,0, +266,1,1840,2605,16, +0,266,1,1591,2606, +16,0,266,1,1341, +2607,16,0,266,1, +1096,1312,1,93,1318, +1,352,1349,1,107, +2608,16,0,266,1, +1114,1343,1,118,1355, +1,1123,2609,16,0, +266,1,371,1365,1, +1628,2610,16,0,266, +1,375,1376,1,1882, +2611,16,0,266,1, +377,1381,1,379,1386, +1,380,1391,1,883, 2612,16,0,266,1, -242,2613,16,0,266, -1,478,1583,1,1001, -1588,1,1002,1593,1, -31,2614,19,253,1, -31,2615,5,84,1, -1011,1102,1,1012,2616, -16,0,251,1,1013, -1258,1,262,1119,1, -1267,2617,16,0,251, -1,515,2618,16,0, -251,1,1521,2619,16, -0,251,1,525,1216, -1,283,1172,1,2299, -2620,16,0,251,1, -42,2621,16,0,251, -1,40,1177,1,44, -1183,1,47,1184,1, -1303,2622,16,0,251, -1,1555,2623,16,0, -251,1,50,1201,1, -48,1190,1,49,1196, -1,51,1206,1,63, -1222,1,305,1211,1, -66,1228,1,67,1233, -1,68,1238,1,69, -1243,1,70,1248,1, -73,2624,16,0,251, -1,74,1253,1,328, -1302,1,1048,1344,1, -82,1280,1,1840,2625, -16,0,251,1,1591, -2626,16,0,251,1, -1341,2627,16,0,251, -1,1096,1312,1,93, -1318,1,352,1349,1, -107,1338,1,1114,1343, +373,1409,1,130,1414, +1,143,1419,1,387, +2613,16,0,266,1, +2664,2614,16,0,266, +1,1159,2615,16,0, +266,1,157,1443,1, +1413,2616,16,0,266, +1,1665,2617,16,0, +266,1,412,2618,16, +0,266,1,1377,2619, +16,0,266,1,172, +1469,1,1939,2620,16, +0,266,1,437,2621, +16,0,266,1,188, +1518,1,942,1490,1, +1195,2622,16,0,266, +1,1449,2623,16,0, +266,1,1701,2624,16, +0,266,1,447,1511, +1,205,2625,16,0, +266,1,827,2626,16, +0,266,1,223,2627, +16,0,266,1,476, +1543,1,477,1549,1, +1231,2628,16,0,266, +1,479,1559,1,480, +1564,1,1485,2629,16, +0,266,1,1737,2630, +16,0,266,1,242, +2631,16,0,266,1, +478,1583,1,1001,1588, +1,1002,1593,1,31, +2632,19,253,1,31, +2633,5,84,1,1011, +1102,1,1012,2634,16, +0,251,1,1013,1258, +1,262,1119,1,1267, +2635,16,0,251,1, +515,2636,16,0,251, +1,1521,2637,16,0, +251,1,525,1216,1, +283,1172,1,2299,2638, +16,0,251,1,42, +2639,16,0,251,1, +40,1177,1,44,1183, +1,47,1184,1,1303, +2640,16,0,251,1, +1555,2641,16,0,251, +1,50,1201,1,48, +1190,1,49,1196,1, +51,1206,1,63,1222, +1,305,1211,1,66, +1228,1,67,1233,1, +68,1238,1,69,1243, +1,70,1248,1,73, +2642,16,0,251,1, +74,1253,1,328,1302, +1,1048,1344,1,82, +2643,16,0,251,1, +1840,2644,16,0,251, +1,1591,2645,16,0, +251,1,1341,2646,16, +0,251,1,1096,1312, +1,93,1318,1,352, +1349,1,107,2647,16, +0,251,1,1114,1343, 1,118,1355,1,1123, -2628,16,0,251,1, -371,1365,1,1628,2629, +2648,16,0,251,1, +371,1365,1,1628,2649, 16,0,251,1,375, -1376,1,1882,2630,16, +1376,1,1882,2650,16, 0,251,1,377,1381, 1,379,1386,1,380, -1391,1,883,2631,16, +1391,1,883,2651,16, 0,251,1,373,1409, 1,130,1414,1,143, -2632,16,0,251,1, -387,2633,16,0,251, -1,2664,2634,16,0, -251,1,1159,2635,16, -0,251,1,157,2636, +2652,16,0,251,1, +387,2653,16,0,251, +1,2664,2654,16,0, +251,1,1159,2655,16, +0,251,1,157,2656, 16,0,251,1,1413, -2637,16,0,251,1, -1665,2638,16,0,251, -1,412,2639,16,0, -251,1,1377,2640,16, +2657,16,0,251,1, +1665,2658,16,0,251, +1,412,2659,16,0, +251,1,1377,2660,16, 0,251,1,172,1469, -1,1939,2641,16,0, -251,1,437,2642,16, +1,1939,2661,16,0, +251,1,437,2662,16, 0,251,1,188,1518, 1,942,1490,1,1195, -2643,16,0,251,1, -1449,2644,16,0,251, -1,1701,2645,16,0, +2663,16,0,251,1, +1449,2664,16,0,251, +1,1701,2665,16,0, 251,1,447,1511,1, -205,2646,16,0,251, -1,827,2647,16,0, -251,1,223,2648,16, +205,2666,16,0,251, +1,827,2667,16,0, +251,1,223,2668,16, 0,251,1,476,1543, 1,477,1549,1,1231, -2649,16,0,251,1, +2669,16,0,251,1, 479,1559,1,480,1564, -1,1485,2650,16,0, -251,1,1737,2651,16, -0,251,1,242,2652, +1,1485,2670,16,0, +251,1,1737,2671,16, +0,251,1,242,2672, 16,0,251,1,478, 1583,1,1001,1588,1, -1002,1593,1,32,2653, -19,246,1,32,2654, +1002,1593,1,32,2673, +19,246,1,32,2674, 5,84,1,1011,1102, -1,1012,2655,16,0, +1,1012,2675,16,0, 244,1,1013,1258,1, -262,1119,1,1267,2656, +262,1119,1,1267,2676, 16,0,244,1,515, -2657,16,0,244,1, -1521,2658,16,0,244, +2677,16,0,244,1, +1521,2678,16,0,244, 1,525,1216,1,283, -1172,1,2299,2659,16, -0,244,1,42,2660, +1172,1,2299,2679,16, +0,244,1,42,2680, 16,0,244,1,40, 1177,1,44,1183,1, -47,1184,1,1303,2661, +47,1184,1,1303,2681, 16,0,244,1,1555, -2662,16,0,244,1, +2682,16,0,244,1, 50,1201,1,48,1190, 1,49,1196,1,51, 1206,1,63,1222,1, 305,1211,1,66,1228, 1,67,1233,1,68, 1238,1,69,1243,1, -70,1248,1,73,2663, +70,1248,1,73,2683, 16,0,244,1,74, 1253,1,328,1302,1, -1048,1344,1,82,1280, -1,1840,2664,16,0, -244,1,1591,2665,16, -0,244,1,1341,2666, -16,0,244,1,1096, -1312,1,93,1318,1, -352,1349,1,107,1338, +1048,1344,1,82,2684, +16,0,244,1,1840, +2685,16,0,244,1, +1591,2686,16,0,244, +1,1341,2687,16,0, +244,1,1096,1312,1, +93,1318,1,352,1349, +1,107,2688,16,0, +244,1,1114,1343,1, +118,1355,1,1123,2689, +16,0,244,1,371, +1365,1,1628,2690,16, +0,244,1,375,1376, +1,1882,2691,16,0, +244,1,377,1381,1, +379,1386,1,380,1391, +1,883,2692,16,0, +244,1,373,1409,1, +130,1414,1,143,2693, +16,0,244,1,387, +2694,16,0,244,1, +2664,2695,16,0,244, +1,1159,2696,16,0, +244,1,157,2697,16, +0,244,1,1413,2698, +16,0,244,1,1665, +2699,16,0,244,1, +412,2700,16,0,244, +1,1377,2701,16,0, +244,1,172,1469,1, +1939,2702,16,0,244, +1,437,2703,16,0, +244,1,188,1518,1, +942,1490,1,1195,2704, +16,0,244,1,1449, +2705,16,0,244,1, +1701,2706,16,0,244, +1,447,1511,1,205, +2707,16,0,244,1, +827,2708,16,0,244, +1,223,2709,16,0, +244,1,476,1543,1, +477,1549,1,1231,2710, +16,0,244,1,479, +1559,1,480,1564,1, +1485,2711,16,0,244, +1,1737,2712,16,0, +244,1,242,2713,16, +0,244,1,478,1583, +1,1001,1588,1,1002, +1593,1,33,2714,19, +332,1,33,2715,5, +84,1,1011,1102,1, +1012,2716,16,0,330, +1,1013,1258,1,262, +1119,1,1267,2717,16, +0,330,1,515,2718, +16,0,330,1,1521, +2719,16,0,330,1, +525,1216,1,283,1172, +1,2299,2720,16,0, +330,1,42,2721,16, +0,330,1,40,1177, +1,44,1183,1,47, +1184,1,1303,2722,16, +0,330,1,1555,2723, +16,0,330,1,50, +1201,1,48,1190,1, +49,1196,1,51,1206, +1,63,1222,1,305, +1211,1,66,1228,1, +67,1233,1,68,1238, +1,69,1243,1,70, +1248,1,73,2724,16, +0,330,1,74,1253, +1,328,1302,1,1048, +1344,1,82,2725,16, +0,330,1,1840,2726, +16,0,330,1,1591, +2727,16,0,330,1, +1341,2728,16,0,330, +1,1096,1312,1,93, +1318,1,352,1349,1, +107,2729,16,0,330, 1,1114,1343,1,118, -1355,1,1123,2667,16, -0,244,1,371,1365, -1,1628,2668,16,0, -244,1,375,1376,1, -1882,2669,16,0,244, +1355,1,1123,2730,16, +0,330,1,371,1365, +1,1628,2731,16,0, +330,1,375,1376,1, +1882,2732,16,0,330, 1,377,1381,1,379, 1386,1,380,1391,1, -883,2670,16,0,244, +883,2733,16,0,330, 1,373,1409,1,130, -1414,1,143,2671,16, -0,244,1,387,2672, -16,0,244,1,2664, -2673,16,0,244,1, -1159,2674,16,0,244, -1,157,2675,16,0, -244,1,1413,2676,16, -0,244,1,1665,2677, -16,0,244,1,412, -2678,16,0,244,1, -1377,2679,16,0,244, -1,172,1469,1,1939, -2680,16,0,244,1, -437,2681,16,0,244, -1,188,1518,1,942, -1490,1,1195,2682,16, -0,244,1,1449,2683, -16,0,244,1,1701, -2684,16,0,244,1, -447,1511,1,205,2685, -16,0,244,1,827, -2686,16,0,244,1, -223,2687,16,0,244, -1,476,1543,1,477, -1549,1,1231,2688,16, -0,244,1,479,1559, -1,480,1564,1,1485, -2689,16,0,244,1, -1737,2690,16,0,244, -1,242,2691,16,0, -244,1,478,1583,1, +1414,1,143,1419,1, +387,2734,16,0,330, +1,2664,2735,16,0, +330,1,1159,2736,16, +0,330,1,157,1443, +1,1413,2737,16,0, +330,1,1665,2738,16, +0,330,1,412,2739, +16,0,330,1,1377, +2740,16,0,330,1, +172,1469,1,1939,2741, +16,0,330,1,437, +2742,16,0,330,1, +188,1518,1,942,1490, +1,1195,2743,16,0, +330,1,1449,2744,16, +0,330,1,1701,2745, +16,0,330,1,447, +1511,1,205,2746,16, +0,330,1,827,2747, +16,0,330,1,223, +2748,16,0,330,1, +476,1543,1,477,1549, +1,1231,2749,16,0, +330,1,479,1559,1, +480,1564,1,1485,2750, +16,0,330,1,1737, +2751,16,0,330,1, +242,1578,1,478,1583, +1,1001,1588,1,1002, +1593,1,34,2752,19, +322,1,34,2753,5, +84,1,1011,1102,1, +1012,2754,16,0,320, +1,1013,1258,1,262, +1119,1,1267,2755,16, +0,320,1,515,2756, +16,0,320,1,1521, +2757,16,0,320,1, +525,1216,1,283,1172, +1,2299,2758,16,0, +320,1,42,2759,16, +0,320,1,40,1177, +1,44,1183,1,47, +1184,1,1303,2760,16, +0,320,1,1555,2761, +16,0,320,1,50, +1201,1,48,1190,1, +49,1196,1,51,1206, +1,63,1222,1,305, +1211,1,66,1228,1, +67,1233,1,68,1238, +1,69,1243,1,70, +1248,1,73,2762,16, +0,320,1,74,1253, +1,328,1302,1,1048, +1344,1,82,2763,16, +0,320,1,1840,2764, +16,0,320,1,1591, +2765,16,0,320,1, +1341,2766,16,0,320, +1,1096,1312,1,93, +1318,1,352,1349,1, +107,2767,16,0,320, +1,1114,1343,1,118, +1355,1,1123,2768,16, +0,320,1,371,1365, +1,1628,2769,16,0, +320,1,375,1376,1, +1882,2770,16,0,320, +1,377,1381,1,379, +1386,1,380,1391,1, +883,2771,16,0,320, +1,373,1409,1,130, +1414,1,143,1419,1, +387,2772,16,0,320, +1,2664,2773,16,0, +320,1,1159,2774,16, +0,320,1,157,1443, +1,1413,2775,16,0, +320,1,1665,2776,16, +0,320,1,412,2777, +16,0,320,1,1377, +2778,16,0,320,1, +172,1469,1,1939,2779, +16,0,320,1,437, +2780,16,0,320,1, +188,1518,1,942,1490, +1,1195,2781,16,0, +320,1,1449,2782,16, +0,320,1,1701,2783, +16,0,320,1,447, +1511,1,205,1523,1, +827,2784,16,0,320, +1,223,1533,1,476, +1543,1,477,1549,1, +1231,2785,16,0,320, +1,479,1559,1,480, +1564,1,1485,2786,16, +0,320,1,1737,2787, +16,0,320,1,242, +1578,1,478,1583,1, 1001,1588,1,1002,1593, -1,33,2692,19,332, -1,33,2693,5,84, +1,35,2788,19,311, +1,35,2789,5,84, 1,1011,1102,1,1012, -2694,16,0,330,1, +2790,16,0,309,1, 1013,1258,1,262,1119, -1,1267,2695,16,0, -330,1,515,2696,16, -0,330,1,1521,2697, -16,0,330,1,525, +1,1267,2791,16,0, +309,1,515,2792,16, +0,309,1,1521,2793, +16,0,309,1,525, 1216,1,283,1172,1, -2299,2698,16,0,330, -1,42,2699,16,0, -330,1,40,1177,1, +2299,2794,16,0,309, +1,42,2795,16,0, +309,1,40,1177,1, 44,1183,1,47,1184, -1,1303,2700,16,0, -330,1,1555,2701,16, -0,330,1,50,1201, +1,1303,2796,16,0, +309,1,1555,2797,16, +0,309,1,50,1201, 1,48,1190,1,49, 1196,1,51,1206,1, 63,1222,1,305,1211, 1,66,1228,1,67, 1233,1,68,1238,1, 69,1243,1,70,1248, -1,73,2702,16,0, -330,1,74,1253,1, +1,73,2798,16,0, +309,1,74,1253,1, 328,1302,1,1048,1344, -1,82,1280,1,1840, -2703,16,0,330,1, -1591,2704,16,0,330, -1,1341,2705,16,0, -330,1,1096,1312,1, -93,1318,1,352,1349, -1,107,1338,1,1114, -1343,1,118,1355,1, -1123,2706,16,0,330, -1,371,1365,1,1628, -2707,16,0,330,1, -375,1376,1,1882,2708, -16,0,330,1,377, -1381,1,379,1386,1, -380,1391,1,883,2709, -16,0,330,1,373, -1409,1,130,1414,1, -143,1419,1,387,2710, -16,0,330,1,2664, -2711,16,0,330,1, -1159,2712,16,0,330, -1,157,1443,1,1413, -2713,16,0,330,1, -1665,2714,16,0,330, -1,412,2715,16,0, -330,1,1377,2716,16, -0,330,1,172,1469, -1,1939,2717,16,0, -330,1,437,2718,16, -0,330,1,188,1518, -1,942,1490,1,1195, -2719,16,0,330,1, -1449,2720,16,0,330, -1,1701,2721,16,0, -330,1,447,1511,1, -205,2722,16,0,330, -1,827,2723,16,0, -330,1,223,2724,16, -0,330,1,476,1543, -1,477,1549,1,1231, -2725,16,0,330,1, -479,1559,1,480,1564, -1,1485,2726,16,0, -330,1,1737,2727,16, -0,330,1,242,1578, -1,478,1583,1,1001, -1588,1,1002,1593,1, -34,2728,19,322,1, -34,2729,5,84,1, -1011,1102,1,1012,2730, -16,0,320,1,1013, -1258,1,262,1119,1, -1267,2731,16,0,320, -1,515,2732,16,0, -320,1,1521,2733,16, -0,320,1,525,1216, -1,283,1172,1,2299, -2734,16,0,320,1, -42,2735,16,0,320, -1,40,1177,1,44, -1183,1,47,1184,1, -1303,2736,16,0,320, -1,1555,2737,16,0, -320,1,50,1201,1, -48,1190,1,49,1196, -1,51,1206,1,63, -1222,1,305,1211,1, -66,1228,1,67,1233, -1,68,1238,1,69, -1243,1,70,1248,1, -73,2738,16,0,320, -1,74,1253,1,328, -1302,1,1048,1344,1, -82,1280,1,1840,2739, -16,0,320,1,1591, -2740,16,0,320,1, -1341,2741,16,0,320, -1,1096,1312,1,93, -1318,1,352,1349,1, -107,1338,1,1114,1343, -1,118,1355,1,1123, -2742,16,0,320,1, -371,1365,1,1628,2743, -16,0,320,1,375, -1376,1,1882,2744,16, -0,320,1,377,1381, -1,379,1386,1,380, -1391,1,883,2745,16, -0,320,1,373,1409, -1,130,1414,1,143, -1419,1,387,2746,16, -0,320,1,2664,2747, -16,0,320,1,1159, -2748,16,0,320,1, -157,1443,1,1413,2749, -16,0,320,1,1665, -2750,16,0,320,1, -412,2751,16,0,320, -1,1377,2752,16,0, -320,1,172,1469,1, -1939,2753,16,0,320, -1,437,2754,16,0, -320,1,188,1518,1, -942,1490,1,1195,2755, -16,0,320,1,1449, -2756,16,0,320,1, -1701,2757,16,0,320, -1,447,1511,1,205, -1523,1,827,2758,16, -0,320,1,223,1533, +1,82,2799,16,0, +309,1,1840,2800,16, +0,309,1,1591,2801, +16,0,309,1,1341, +2802,16,0,309,1, +1096,1312,1,93,1318, +1,352,1349,1,107, +2803,16,0,309,1, +1114,1343,1,118,1355, +1,1123,2804,16,0, +309,1,371,1365,1, +1628,2805,16,0,309, +1,375,1376,1,1882, +2806,16,0,309,1, +377,1381,1,379,1386, +1,380,1391,1,883, +2807,16,0,309,1, +373,1409,1,130,1414, +1,143,1419,1,387, +2808,16,0,309,1, +2664,2809,16,0,309, +1,1159,2810,16,0, +309,1,157,1443,1, +1413,2811,16,0,309, +1,1665,2812,16,0, +309,1,412,2813,16, +0,309,1,1377,2814, +16,0,309,1,172, +1469,1,1939,2815,16, +0,309,1,437,2816, +16,0,309,1,188, +1518,1,942,1490,1, +1195,2817,16,0,309, +1,1449,2818,16,0, +309,1,1701,2819,16, +0,309,1,447,1511, +1,205,1523,1,827, +2820,16,0,309,1, +223,2821,16,0,309, 1,476,1543,1,477, -1549,1,1231,2759,16, -0,320,1,479,1559, +1549,1,1231,2822,16, +0,309,1,479,1559, 1,480,1564,1,1485, -2760,16,0,320,1, -1737,2761,16,0,320, +2823,16,0,309,1, +1737,2824,16,0,309, 1,242,1578,1,478, 1583,1,1001,1588,1, -1002,1593,1,35,2762, -19,311,1,35,2763, -5,84,1,1011,1102, -1,1012,2764,16,0, -309,1,1013,1258,1, -262,1119,1,1267,2765, -16,0,309,1,515, -2766,16,0,309,1, -1521,2767,16,0,309, -1,525,1216,1,283, -1172,1,2299,2768,16, -0,309,1,42,2769, -16,0,309,1,40, -1177,1,44,1183,1, -47,1184,1,1303,2770, -16,0,309,1,1555, -2771,16,0,309,1, -50,1201,1,48,1190, -1,49,1196,1,51, -1206,1,63,1222,1, -305,1211,1,66,1228, -1,67,1233,1,68, -1238,1,69,1243,1, -70,1248,1,73,2772, -16,0,309,1,74, -1253,1,328,1302,1, -1048,1344,1,82,1280, -1,1840,2773,16,0, -309,1,1591,2774,16, -0,309,1,1341,2775, -16,0,309,1,1096, -1312,1,93,1318,1, -352,1349,1,107,1338, -1,1114,1343,1,118, -1355,1,1123,2776,16, -0,309,1,371,1365, -1,1628,2777,16,0, -309,1,375,1376,1, -1882,2778,16,0,309, -1,377,1381,1,379, -1386,1,380,1391,1, -883,2779,16,0,309, -1,373,1409,1,130, -1414,1,143,1419,1, -387,2780,16,0,309, -1,2664,2781,16,0, -309,1,1159,2782,16, -0,309,1,157,1443, -1,1413,2783,16,0, -309,1,1665,2784,16, -0,309,1,412,2785, -16,0,309,1,1377, -2786,16,0,309,1, -172,1469,1,1939,2787, -16,0,309,1,437, -2788,16,0,309,1, -188,1518,1,942,1490, -1,1195,2789,16,0, -309,1,1449,2790,16, -0,309,1,1701,2791, -16,0,309,1,447, -1511,1,205,1523,1, -827,2792,16,0,309, -1,223,2793,16,0, -309,1,476,1543,1, -477,1549,1,1231,2794, -16,0,309,1,479, -1559,1,480,1564,1, -1485,2795,16,0,309, -1,1737,2796,16,0, -309,1,242,1578,1, -478,1583,1,1001,1588, -1,1002,1593,1,36, -2797,19,216,1,36, -2798,5,94,1,256, -2799,16,0,214,1, -1261,2800,16,0,214, -1,509,2801,16,0, -214,1,1515,2802,16, -0,214,1,2021,718, -1,1775,2803,16,0, -214,1,2029,725,1, -2030,731,1,2031,736, -1,2032,741,1,2033, -746,1,277,2804,16, -0,214,1,2035,752, -1,2037,757,1,2039, -762,1,32,2805,16, -0,214,1,2041,768, -1,2293,2806,16,0, -214,1,2043,774,1, -2045,779,1,41,2807, -16,0,214,1,1297, -2808,16,0,214,1, -43,2809,16,0,214, -1,1803,787,1,1804, -2810,16,0,214,1, -299,2811,16,0,214, -1,52,2812,16,0, -214,1,2318,2813,16, -0,214,1,2075,2814, -16,0,214,1,1574, -799,1,71,2815,16, -0,214,1,76,2816, -16,0,214,1,1834, -2817,16,0,214,1, -2337,2818,16,0,214, -1,79,2819,16,0, -214,1,1335,2820,16, -0,214,1,322,2821, -16,0,214,1,85, -2822,16,0,214,1, -89,2823,16,0,214, -1,346,2824,16,0, -214,1,2105,814,1, -2106,2825,16,0,214, -1,97,2826,16,0, -214,1,1860,821,1, -2364,827,1,102,2827, -16,0,214,1,112, +1002,1593,1,36,2825, +19,216,1,36,2826, +5,94,1,256,2827, +16,0,214,1,1261, 2828,16,0,214,1, -1117,2829,16,0,214, -1,1873,835,1,1876, -2830,16,0,214,1, -124,2831,16,0,214, -1,2136,842,1,381, -2832,16,0,214,1, -525,2833,16,0,214, -1,137,2834,16,0, -214,1,1901,2835,16, -0,214,1,2658,2836, -16,0,214,1,1153, +509,2829,16,0,214, +1,1515,2830,16,0, +214,1,2021,718,1, +1775,2831,16,0,214, +1,2029,725,1,2030, +731,1,2031,736,1, +2032,741,1,2033,746, +1,277,2832,16,0, +214,1,2035,752,1, +2037,757,1,2039,762, +1,32,2833,16,0, +214,1,2041,768,1, +2293,2834,16,0,214, +1,2043,774,1,2045, +779,1,41,2835,16, +0,214,1,1297,2836, +16,0,214,1,43, 2837,16,0,214,1, -151,2838,16,0,214, -1,1407,2839,16,0, -214,1,1659,2840,16, -0,214,1,2413,2841, -16,0,214,1,406, -2842,16,0,214,1, -1371,2843,16,0,214, -1,166,2844,16,0, -214,1,1622,2845,16, -0,214,1,1931,861, -1,1933,2846,16,0, -214,1,431,2847,16, -0,214,1,1585,2848, -16,0,214,1,182, -2849,16,0,214,1, -1189,2850,16,0,214, -1,1443,2851,16,0, -214,1,1695,2852,16, -0,214,1,2198,2853, -16,0,214,1,447, -2854,16,0,214,1, -2458,876,1,2459,882, -1,1958,2855,16,0, -214,1,2462,889,1, -1657,894,1,2464,899, -1,199,2856,16,0, -214,1,459,2857,16, -0,214,1,462,2858, -16,0,214,1,217, +1803,787,1,1804,2838, +16,0,214,1,299, +2839,16,0,214,1, +52,2840,16,0,214, +1,2318,2841,16,0, +214,1,2075,2842,16, +0,214,1,1574,799, +1,71,2843,16,0, +214,1,76,2844,16, +0,214,1,1834,2845, +16,0,214,1,2337, +2846,16,0,214,1, +79,2847,16,0,214, +1,1335,2848,16,0, +214,1,322,2849,16, +0,214,1,85,2850, +16,0,214,1,89, +2851,16,0,214,1, +346,2852,16,0,214, +1,2105,814,1,2106, +2853,16,0,214,1, +97,2854,16,0,214, +1,1860,821,1,2364, +827,1,102,2855,16, +0,214,1,112,2856, +16,0,214,1,1117, +2857,16,0,214,1, +1873,835,1,1876,2858, +16,0,214,1,124, 2859,16,0,214,1, -2227,908,1,1225,2860, -16,0,214,1,1479, +2136,842,1,381,2860, +16,0,214,1,525, 2861,16,0,214,1, -1731,2862,16,0,214, -1,1989,916,1,1990, -2863,16,0,214,1, -236,2864,16,0,214, -1,1756,2865,16,0, -214,1,37,2866,19, -233,1,37,2867,5, -94,1,256,2868,16, -0,231,1,1261,2869, -16,0,231,1,509, -2870,16,0,231,1, -1515,2871,16,0,231, -1,2021,718,1,1775, -2872,16,0,231,1, -2029,725,1,2030,731, -1,2031,736,1,2032, -741,1,2033,746,1, -277,2873,16,0,231, -1,2035,752,1,2037, -757,1,2039,762,1, -32,2874,16,0,231, -1,2041,768,1,2293, -2875,16,0,231,1, -2043,774,1,2045,779, -1,41,2876,16,0, -231,1,1297,2877,16, -0,231,1,43,2878, -16,0,231,1,1803, -787,1,1804,2879,16, -0,231,1,299,2880, -16,0,231,1,52, -2881,16,0,231,1, -2318,2882,16,0,231, -1,2075,2883,16,0, -231,1,1574,799,1, -71,2884,16,0,231, -1,76,2885,16,0, -231,1,1834,2886,16, -0,231,1,2337,2887, -16,0,231,1,79, -2888,16,0,231,1, -1335,2889,16,0,231, -1,322,2890,16,0, -231,1,85,2891,16, -0,231,1,89,2892, -16,0,231,1,346, -2893,16,0,231,1, -2105,814,1,2106,2894, -16,0,231,1,97, -2895,16,0,231,1, -1860,821,1,2364,827, -1,102,2896,16,0, -231,1,112,2897,16, -0,231,1,1117,2898, -16,0,231,1,1873, -835,1,1876,2899,16, -0,231,1,124,2900, -16,0,231,1,2136, -842,1,381,2901,16, -0,231,1,525,2902, -16,0,231,1,137, -2903,16,0,231,1, -1901,2904,16,0,231, -1,2658,2905,16,0, -231,1,1153,2906,16, -0,231,1,151,2907, -16,0,231,1,1407, -2908,16,0,231,1, -1659,2909,16,0,231, -1,2413,2910,16,0, -231,1,406,2911,16, -0,231,1,1371,2912, -16,0,231,1,166, -2913,16,0,231,1, -1622,2914,16,0,231, -1,1931,861,1,1933, -2915,16,0,231,1, -431,2916,16,0,231, -1,1585,2917,16,0, -231,1,182,2918,16, -0,231,1,1189,2919, -16,0,231,1,1443, -2920,16,0,231,1, -1695,2921,16,0,231, -1,2198,2922,16,0, -231,1,447,2923,16, -0,231,1,2458,876, -1,2459,882,1,1958, -2924,16,0,231,1, -2462,889,1,1657,894, -1,2464,899,1,199, -2925,16,0,231,1, -459,2926,16,0,231, -1,462,2927,16,0, -231,1,217,2928,16, -0,231,1,2227,908, -1,1225,2929,16,0, -231,1,1479,2930,16, -0,231,1,1731,2931, -16,0,231,1,1989, -916,1,1990,2932,16, -0,231,1,236,2933, -16,0,231,1,1756, -2934,16,0,231,1, -38,2935,19,230,1, -38,2936,5,84,1, -1011,1102,1,1012,2937, -16,0,228,1,1013, -1258,1,262,1119,1, -1267,2938,16,0,228, -1,515,2939,16,0, -228,1,1521,2940,16, -0,228,1,525,1216, -1,283,1172,1,2299, -2941,16,0,228,1, -42,2942,16,0,228, -1,40,1177,1,44, -1183,1,47,1184,1, -1303,2943,16,0,228, -1,1555,2944,16,0, -228,1,50,1201,1, -48,1190,1,49,1196, -1,51,1206,1,63, -1222,1,305,1211,1, -66,1228,1,67,1233, -1,68,1238,1,69, -1243,1,70,1248,1, -73,2945,16,0,228, -1,74,1253,1,328, -1302,1,1048,1344,1, -82,1280,1,1840,2946, -16,0,228,1,1591, -2947,16,0,228,1, -1341,2948,16,0,228, -1,1096,1312,1,93, -1318,1,352,1349,1, -107,1338,1,1114,1343, +137,2862,16,0,214, +1,1901,2863,16,0, +214,1,2658,2864,16, +0,214,1,1153,2865, +16,0,214,1,151, +2866,16,0,214,1, +1407,2867,16,0,214, +1,1659,2868,16,0, +214,1,2413,2869,16, +0,214,1,406,2870, +16,0,214,1,1371, +2871,16,0,214,1, +166,2872,16,0,214, +1,1622,2873,16,0, +214,1,1931,861,1, +1933,2874,16,0,214, +1,431,2875,16,0, +214,1,1585,2876,16, +0,214,1,182,2877, +16,0,214,1,1189, +2878,16,0,214,1, +1443,2879,16,0,214, +1,1695,2880,16,0, +214,1,2198,2881,16, +0,214,1,447,2882, +16,0,214,1,2458, +876,1,2459,882,1, +1958,2883,16,0,214, +1,2462,889,1,1657, +894,1,2464,899,1, +199,2884,16,0,214, +1,459,2885,16,0, +214,1,462,2886,16, +0,214,1,217,2887, +16,0,214,1,2227, +908,1,1225,2888,16, +0,214,1,1479,2889, +16,0,214,1,1731, +2890,16,0,214,1, +1989,916,1,1990,2891, +16,0,214,1,236, +2892,16,0,214,1, +1756,2893,16,0,214, +1,37,2894,19,233, +1,37,2895,5,94, +1,256,2896,16,0, +231,1,1261,2897,16, +0,231,1,509,2898, +16,0,231,1,1515, +2899,16,0,231,1, +2021,718,1,1775,2900, +16,0,231,1,2029, +725,1,2030,731,1, +2031,736,1,2032,741, +1,2033,746,1,277, +2901,16,0,231,1, +2035,752,1,2037,757, +1,2039,762,1,32, +2902,16,0,231,1, +2041,768,1,2293,2903, +16,0,231,1,2043, +774,1,2045,779,1, +41,2904,16,0,231, +1,1297,2905,16,0, +231,1,43,2906,16, +0,231,1,1803,787, +1,1804,2907,16,0, +231,1,299,2908,16, +0,231,1,52,2909, +16,0,231,1,2318, +2910,16,0,231,1, +2075,2911,16,0,231, +1,1574,799,1,71, +2912,16,0,231,1, +76,2913,16,0,231, +1,1834,2914,16,0, +231,1,2337,2915,16, +0,231,1,79,2916, +16,0,231,1,1335, +2917,16,0,231,1, +322,2918,16,0,231, +1,85,2919,16,0, +231,1,89,2920,16, +0,231,1,346,2921, +16,0,231,1,2105, +814,1,2106,2922,16, +0,231,1,97,2923, +16,0,231,1,1860, +821,1,2364,827,1, +102,2924,16,0,231, +1,112,2925,16,0, +231,1,1117,2926,16, +0,231,1,1873,835, +1,1876,2927,16,0, +231,1,124,2928,16, +0,231,1,2136,842, +1,381,2929,16,0, +231,1,525,2930,16, +0,231,1,137,2931, +16,0,231,1,1901, +2932,16,0,231,1, +2658,2933,16,0,231, +1,1153,2934,16,0, +231,1,151,2935,16, +0,231,1,1407,2936, +16,0,231,1,1659, +2937,16,0,231,1, +2413,2938,16,0,231, +1,406,2939,16,0, +231,1,1371,2940,16, +0,231,1,166,2941, +16,0,231,1,1622, +2942,16,0,231,1, +1931,861,1,1933,2943, +16,0,231,1,431, +2944,16,0,231,1, +1585,2945,16,0,231, +1,182,2946,16,0, +231,1,1189,2947,16, +0,231,1,1443,2948, +16,0,231,1,1695, +2949,16,0,231,1, +2198,2950,16,0,231, +1,447,2951,16,0, +231,1,2458,876,1, +2459,882,1,1958,2952, +16,0,231,1,2462, +889,1,1657,894,1, +2464,899,1,199,2953, +16,0,231,1,459, +2954,16,0,231,1, +462,2955,16,0,231, +1,217,2956,16,0, +231,1,2227,908,1, +1225,2957,16,0,231, +1,1479,2958,16,0, +231,1,1731,2959,16, +0,231,1,1989,916, +1,1990,2960,16,0, +231,1,236,2961,16, +0,231,1,1756,2962, +16,0,231,1,38, +2963,19,230,1,38, +2964,5,84,1,1011, +1102,1,1012,2965,16, +0,228,1,1013,1258, +1,262,1119,1,1267, +2966,16,0,228,1, +515,2967,16,0,228, +1,1521,2968,16,0, +228,1,525,1216,1, +283,1172,1,2299,2969, +16,0,228,1,42, +2970,16,0,228,1, +40,1177,1,44,1183, +1,47,1184,1,1303, +2971,16,0,228,1, +1555,2972,16,0,228, +1,50,1201,1,48, +1190,1,49,1196,1, +51,1206,1,63,1222, +1,305,1211,1,66, +1228,1,67,1233,1, +68,1238,1,69,1243, +1,70,1248,1,73, +2973,16,0,228,1, +74,1253,1,328,1302, +1,1048,1344,1,82, +2974,16,0,228,1, +1840,2975,16,0,228, +1,1591,2976,16,0, +228,1,1341,2977,16, +0,228,1,1096,1312, +1,93,1318,1,352, +1349,1,107,2978,16, +0,228,1,1114,1343, 1,118,1355,1,1123, -2949,16,0,228,1, -371,1365,1,1628,2950, +2979,16,0,228,1, +371,1365,1,1628,2980, 16,0,228,1,375, -1376,1,1882,2951,16, +1376,1,1882,2981,16, 0,228,1,377,1381, 1,379,1386,1,380, 1391,1,883,1397,1, 373,1409,1,130,1414, 1,143,1419,1,387, -2952,16,0,228,1, -2664,2953,16,0,228, -1,1159,2954,16,0, +2982,16,0,228,1, +2664,2983,16,0,228, +1,1159,2984,16,0, 228,1,157,1443,1, -1413,2955,16,0,228, -1,1665,2956,16,0, -228,1,412,2957,16, -0,228,1,1377,2958, +1413,2985,16,0,228, +1,1665,2986,16,0, +228,1,412,2987,16, +0,228,1,1377,2988, 16,0,228,1,172, -1469,1,1939,2959,16, -0,228,1,437,2960, +1469,1,1939,2989,16, +0,228,1,437,2990, 16,0,228,1,188, 1518,1,942,1490,1, -1195,2961,16,0,228, -1,1449,2962,16,0, -228,1,1701,2963,16, +1195,2991,16,0,228, +1,1449,2992,16,0, +228,1,1701,2993,16, 0,228,1,447,1511, 1,205,1523,1,827, 1331,1,223,1533,1, 476,1543,1,477,1549, -1,1231,2964,16,0, +1,1231,2994,16,0, 228,1,479,1559,1, -480,1564,1,1485,2965, +480,1564,1,1485,2995, 16,0,228,1,1737, -2966,16,0,228,1, +2996,16,0,228,1, 242,1578,1,478,1583, 1,1001,1588,1,1002, -1593,1,39,2967,19, -222,1,39,2968,5, +1593,1,39,2997,19, +222,1,39,2998,5, 84,1,1011,1102,1, -1012,2969,16,0,220, +1012,2999,16,0,220, 1,1013,1258,1,262, -1119,1,1267,2970,16, -0,220,1,515,2971, +1119,1,1267,3000,16, +0,220,1,515,3001, 16,0,220,1,1521, -2972,16,0,220,1, +3002,16,0,220,1, 525,1216,1,283,1172, -1,2299,2973,16,0, -220,1,42,2974,16, +1,2299,3003,16,0, +220,1,42,3004,16, 0,220,1,40,1177, 1,44,1183,1,47, -1184,1,1303,2975,16, -0,220,1,1555,2976, +1184,1,1303,3005,16, +0,220,1,1555,3006, 16,0,220,1,50, 1201,1,48,1190,1, 49,1196,1,51,1206, @@ -8028,276 +8046,230 @@ public yyLSLSyntax 1211,1,66,1228,1, 67,1233,1,68,1238, 1,69,1243,1,70, -1248,1,73,2977,16, +1248,1,73,3007,16, 0,220,1,74,1253, 1,328,1302,1,1048, -1344,1,82,1280,1, -1840,2978,16,0,220, -1,1591,2979,16,0, -220,1,1341,2980,16, -0,220,1,1096,1312, -1,93,1318,1,352, -1349,1,107,1338,1, -1114,1343,1,118,1355, -1,1123,2981,16,0, -220,1,371,1365,1, -1628,2982,16,0,220, -1,375,1376,1,1882, -2983,16,0,220,1, -377,1381,1,379,1386, -1,380,1391,1,883, -1397,1,373,1409,1, -130,1414,1,143,1419, -1,387,2984,16,0, -220,1,2664,2985,16, -0,220,1,1159,2986, -16,0,220,1,157, -1443,1,1413,2987,16, -0,220,1,1665,2988, -16,0,220,1,412, -2989,16,0,220,1, -1377,2990,16,0,220, -1,172,1469,1,1939, -2991,16,0,220,1, -437,2992,16,0,220, -1,188,1518,1,942, -1490,1,1195,2993,16, -0,220,1,1449,2994, -16,0,220,1,1701, -2995,16,0,220,1, -447,1511,1,205,1523, -1,827,1331,1,223, -1533,1,476,1543,1, -477,1549,1,1231,2996, -16,0,220,1,479, -1559,1,480,1564,1, -1485,2997,16,0,220, -1,1737,2998,16,0, -220,1,242,1578,1, -478,1583,1,1001,1588, -1,1002,1593,1,40, -2999,19,210,1,40, -3000,5,84,1,1011, -1102,1,1012,3001,16, -0,208,1,1013,1258, -1,262,1119,1,1267, -3002,16,0,208,1, -515,3003,16,0,208, -1,1521,3004,16,0, -208,1,525,1216,1, -283,1172,1,2299,3005, -16,0,208,1,42, -3006,16,0,208,1, -40,1177,1,44,1183, -1,47,1184,1,1303, -3007,16,0,208,1, -1555,3008,16,0,208, -1,50,1201,1,48, -1190,1,49,1196,1, -51,1206,1,63,1222, -1,305,1211,1,66, -1228,1,67,1233,1, -68,1238,1,69,1243, -1,70,1248,1,73, -3009,16,0,208,1, -74,1253,1,328,1302, -1,1048,1344,1,82, -1280,1,1840,3010,16, -0,208,1,1591,3011, -16,0,208,1,1341, -3012,16,0,208,1, -1096,1312,1,93,1318, -1,352,1349,1,107, -1338,1,1114,1343,1, -118,3013,16,0,208, -1,1123,3014,16,0, -208,1,371,1365,1, -1628,3015,16,0,208, -1,375,1376,1,1882, -3016,16,0,208,1, -377,1381,1,379,1386, -1,380,1391,1,883, -3017,16,0,208,1, -373,1409,1,130,3018, -16,0,208,1,143, -3019,16,0,208,1, -387,3020,16,0,208, -1,2664,3021,16,0, -208,1,1159,3022,16, -0,208,1,157,3023, -16,0,208,1,1413, -3024,16,0,208,1, -1665,3025,16,0,208, -1,412,3026,16,0, -208,1,1377,3027,16, -0,208,1,172,3028, -16,0,208,1,1939, -3029,16,0,208,1, -437,3030,16,0,208, -1,188,3031,16,0, -208,1,942,1490,1, -1195,3032,16,0,208, -1,1449,3033,16,0, -208,1,1701,3034,16, -0,208,1,447,1511, -1,205,3035,16,0, -208,1,827,3036,16, -0,208,1,223,3037, -16,0,208,1,476, -1543,1,477,1549,1, -1231,3038,16,0,208, -1,479,1559,1,480, -1564,1,1485,3039,16, -0,208,1,1737,3040, -16,0,208,1,242, -3041,16,0,208,1, -478,1583,1,1001,1588, -1,1002,1593,1,41, -3042,19,172,1,41, -3043,5,84,1,1011, -1102,1,1012,3044,16, -0,170,1,1013,1258, -1,262,1119,1,1267, -3045,16,0,170,1, -515,3046,16,0,170, -1,1521,3047,16,0, -170,1,525,1216,1, -283,1172,1,2299,3048, -16,0,170,1,42, -3049,16,0,170,1, -40,1177,1,44,1183, -1,47,1184,1,1303, -3050,16,0,170,1, -1555,3051,16,0,170, -1,50,1201,1,48, -1190,1,49,1196,1, -51,1206,1,63,1222, -1,305,1211,1,66, -1228,1,67,1233,1, -68,1238,1,69,1243, -1,70,1248,1,73, -3052,16,0,170,1, -74,1253,1,328,1302, -1,1048,1344,1,82, -1280,1,1840,3053,16, -0,170,1,1591,3054, +1344,1,82,3008,16, +0,220,1,1840,3009, +16,0,220,1,1591, +3010,16,0,220,1, +1341,3011,16,0,220, +1,1096,1312,1,93, +1318,1,352,1349,1, +107,3012,16,0,220, +1,1114,1343,1,118, +1355,1,1123,3013,16, +0,220,1,371,1365, +1,1628,3014,16,0, +220,1,375,1376,1, +1882,3015,16,0,220, +1,377,1381,1,379, +1386,1,380,1391,1, +883,1397,1,373,1409, +1,130,1414,1,143, +1419,1,387,3016,16, +0,220,1,2664,3017, +16,0,220,1,1159, +3018,16,0,220,1, +157,1443,1,1413,3019, +16,0,220,1,1665, +3020,16,0,220,1, +412,3021,16,0,220, +1,1377,3022,16,0, +220,1,172,1469,1, +1939,3023,16,0,220, +1,437,3024,16,0, +220,1,188,1518,1, +942,1490,1,1195,3025, +16,0,220,1,1449, +3026,16,0,220,1, +1701,3027,16,0,220, +1,447,1511,1,205, +1523,1,827,1331,1, +223,1533,1,476,1543, +1,477,1549,1,1231, +3028,16,0,220,1, +479,1559,1,480,1564, +1,1485,3029,16,0, +220,1,1737,3030,16, +0,220,1,242,1578, +1,478,1583,1,1001, +1588,1,1002,1593,1, +40,3031,19,210,1, +40,3032,5,84,1, +1011,1102,1,1012,3033, +16,0,208,1,1013, +1258,1,262,1119,1, +1267,3034,16,0,208, +1,515,3035,16,0, +208,1,1521,3036,16, +0,208,1,525,1216, +1,283,1172,1,2299, +3037,16,0,208,1, +42,3038,16,0,208, +1,40,1177,1,44, +1183,1,47,1184,1, +1303,3039,16,0,208, +1,1555,3040,16,0, +208,1,50,1201,1, +48,1190,1,49,1196, +1,51,1206,1,63, +1222,1,305,1211,1, +66,1228,1,67,1233, +1,68,1238,1,69, +1243,1,70,1248,1, +73,3041,16,0,208, +1,74,1253,1,328, +1302,1,1048,1344,1, +82,3042,16,0,208, +1,1840,3043,16,0, +208,1,1591,3044,16, +0,208,1,1341,3045, +16,0,208,1,1096, +1312,1,93,1318,1, +352,1349,1,107,3046, +16,0,208,1,1114, +1343,1,118,3047,16, +0,208,1,1123,3048, +16,0,208,1,371, +1365,1,1628,3049,16, +0,208,1,375,1376, +1,1882,3050,16,0, +208,1,377,1381,1, +379,1386,1,380,1391, +1,883,3051,16,0, +208,1,373,1409,1, +130,3052,16,0,208, +1,143,3053,16,0, +208,1,387,3054,16, +0,208,1,2664,3055, +16,0,208,1,1159, +3056,16,0,208,1, +157,3057,16,0,208, +1,1413,3058,16,0, +208,1,1665,3059,16, +0,208,1,412,3060, +16,0,208,1,1377, +3061,16,0,208,1, +172,3062,16,0,208, +1,1939,3063,16,0, +208,1,437,3064,16, +0,208,1,188,3065, +16,0,208,1,942, +1490,1,1195,3066,16, +0,208,1,1449,3067, +16,0,208,1,1701, +3068,16,0,208,1, +447,1511,1,205,3069, +16,0,208,1,827, +3070,16,0,208,1, +223,3071,16,0,208, +1,476,1543,1,477, +1549,1,1231,3072,16, +0,208,1,479,1559, +1,480,1564,1,1485, +3073,16,0,208,1, +1737,3074,16,0,208, +1,242,3075,16,0, +208,1,478,1583,1, +1001,1588,1,1002,1593, +1,41,3076,19,172, +1,41,3077,5,84, +1,1011,1102,1,1012, +3078,16,0,170,1, +1013,1258,1,262,1119, +1,1267,3079,16,0, +170,1,515,3080,16, +0,170,1,1521,3081, +16,0,170,1,525, +1216,1,283,1172,1, +2299,3082,16,0,170, +1,42,3083,16,0, +170,1,40,1177,1, +44,1183,1,47,1184, +1,1303,3084,16,0, +170,1,1555,3085,16, +0,170,1,50,1201, +1,48,1190,1,49, +1196,1,51,1206,1, +63,1222,1,305,1211, +1,66,1228,1,67, +1233,1,68,1238,1, +69,1243,1,70,1248, +1,73,3086,16,0, +170,1,74,1253,1, +328,1302,1,1048,1344, +1,82,3087,16,0, +170,1,1840,3088,16, +0,170,1,1591,3089, 16,0,170,1,1341, -3055,16,0,170,1, +3090,16,0,170,1, 1096,1312,1,93,1318, 1,352,1349,1,107, -1338,1,1114,1343,1, -118,3056,16,0,170, -1,1123,3057,16,0, -170,1,371,1365,1, -1628,3058,16,0,170, -1,375,1376,1,1882, -3059,16,0,170,1, -377,1381,1,379,1386, -1,380,1391,1,883, -3060,16,0,170,1, -373,1409,1,130,3061, -16,0,170,1,143, -3062,16,0,170,1, -387,3063,16,0,170, -1,2664,3064,16,0, -170,1,1159,3065,16, -0,170,1,157,3066, -16,0,170,1,1413, -3067,16,0,170,1, -1665,3068,16,0,170, -1,412,3069,16,0, -170,1,1377,3070,16, -0,170,1,172,3071, -16,0,170,1,1939, -3072,16,0,170,1, -437,3073,16,0,170, -1,188,3074,16,0, -170,1,942,1490,1, -1195,3075,16,0,170, -1,1449,3076,16,0, -170,1,1701,3077,16, -0,170,1,447,1511, -1,205,3078,16,0, -170,1,827,3079,16, -0,170,1,223,3080, -16,0,170,1,476, -1543,1,477,1549,1, -1231,3081,16,0,170, -1,479,1559,1,480, -1564,1,1485,3082,16, -0,170,1,1737,3083, -16,0,170,1,242, -3084,16,0,170,1, -478,1583,1,1001,1588, -1,1002,1593,1,42, -3085,19,394,1,42, -3086,5,38,1,1901, -3087,16,0,392,1, -2075,3088,16,0,392, -1,1860,821,1,1803, -787,1,1804,3089,16, -0,392,1,2413,3090, -16,0,392,1,2198, -3091,16,0,392,1, -1873,835,1,1657,894, -1,1989,916,1,1990, -3092,16,0,392,1, -1775,3093,16,0,392, -1,32,3094,16,0, -392,1,2105,814,1, -2106,3095,16,0,392, -1,2364,827,1,2227, -908,1,2337,3096,16, -0,392,1,2021,718, -1,2458,876,1,2459, -882,1,2462,889,1, -2136,842,1,2464,899, -1,2029,725,1,2030, -731,1,2031,736,1, -2032,741,1,2033,746, -1,2035,752,1,2037, -757,1,2039,762,1, -1931,861,1,2041,768, -1,2043,774,1,2045, -779,1,1574,799,1, -1958,3097,16,0,392, -1,43,3098,19,453, -1,43,3099,5,25, -1,2035,752,1,2037, -757,1,2039,762,1, -2041,768,1,2227,908, -1,2043,774,1,1657, -894,1,1860,821,1, -2136,842,1,2021,718, -1,2459,882,1,1574, -799,1,2105,3100,16, -0,578,1,1931,861, -1,1873,835,1,2031, -736,1,1803,787,1, -1989,3101,16,0,451, -1,2464,899,1,2029, -725,1,2030,731,1, -2364,827,1,2032,741, -1,2033,746,1,2045, -779,1,44,3102,19, -264,1,44,3103,5, -38,1,1901,3104,16, -0,262,1,2075,3105, -16,0,262,1,1860, +3091,16,0,170,1, +1114,1343,1,118,3092, +16,0,170,1,1123, +3093,16,0,170,1, +371,1365,1,1628,3094, +16,0,170,1,375, +1376,1,1882,3095,16, +0,170,1,377,1381, +1,379,1386,1,380, +1391,1,883,3096,16, +0,170,1,373,1409, +1,130,3097,16,0, +170,1,143,3098,16, +0,170,1,387,3099, +16,0,170,1,2664, +3100,16,0,170,1, +1159,3101,16,0,170, +1,157,3102,16,0, +170,1,1413,3103,16, +0,170,1,1665,3104, +16,0,170,1,412, +3105,16,0,170,1, +1377,3106,16,0,170, +1,172,3107,16,0, +170,1,1939,3108,16, +0,170,1,437,3109, +16,0,170,1,188, +3110,16,0,170,1, +942,1490,1,1195,3111, +16,0,170,1,1449, +3112,16,0,170,1, +1701,3113,16,0,170, +1,447,1511,1,205, +3114,16,0,170,1, +827,3115,16,0,170, +1,223,3116,16,0, +170,1,476,1543,1, +477,1549,1,1231,3117, +16,0,170,1,479, +1559,1,480,1564,1, +1485,3118,16,0,170, +1,1737,3119,16,0, +170,1,242,3120,16, +0,170,1,478,1583, +1,1001,1588,1,1002, +1593,1,42,3121,19, +394,1,42,3122,5, +38,1,1901,3123,16, +0,392,1,2075,3124, +16,0,392,1,1860, 821,1,1803,787,1, -1804,3106,16,0,262, -1,2413,3107,16,0, -262,1,2198,3108,16, -0,262,1,1873,835, +1804,3125,16,0,392, +1,2413,3126,16,0, +392,1,2198,3127,16, +0,392,1,1873,835, 1,1657,894,1,1989, -916,1,1990,3109,16, -0,262,1,1775,3110, -16,0,262,1,32, -3111,16,0,262,1, -2105,814,1,2106,3112, -16,0,262,1,2364, +916,1,1990,3128,16, +0,392,1,1775,3129, +16,0,392,1,32, +3130,16,0,392,1, +2105,814,1,2106,3131, +16,0,392,1,2364, 827,1,2227,908,1, -2337,3113,16,0,262, +2337,3132,16,0,392, 1,2021,718,1,2458, 876,1,2459,882,1, 2462,889,1,2136,842, @@ -8309,59 +8281,76 @@ public yyLSLSyntax 2039,762,1,1931,861, 1,2041,768,1,2043, 774,1,2045,779,1, -1574,799,1,1958,3114, -16,0,262,1,45, -3115,19,287,1,45, -3116,5,39,1,1901, -3117,16,0,315,1, -2075,3118,16,0,315, -1,1860,821,1,1803, -787,1,1804,3119,16, -0,315,1,2413,3120, -16,0,315,1,2198, -3121,16,0,315,1, -1873,835,1,1657,894, -1,1989,916,1,1990, -3122,16,0,315,1, -1775,3123,16,0,315, -1,32,3124,16,0, -315,1,2105,814,1, -2106,3125,16,0,315, -1,2364,827,1,2227, -908,1,2337,3126,16, -0,315,1,2021,718, -1,2458,876,1,2459, -882,1,2462,889,1, -2136,842,1,2464,899, -1,2029,725,1,2030, -731,1,2031,736,1, -2032,741,1,2033,746, -1,2035,752,1,2037, -757,1,2039,762,1, -1931,861,1,2041,768, -1,2043,774,1,2045, -779,1,1832,3127,16, -0,285,1,1574,799, -1,1958,3128,16,0, -315,1,46,3129,19, -671,1,46,3130,5, -38,1,1901,3131,16, -0,669,1,2075,3132, -16,0,669,1,1860, +1574,799,1,1958,3133, +16,0,392,1,43, +3134,19,453,1,43, +3135,5,25,1,2035, +752,1,2037,757,1, +2039,762,1,2041,768, +1,2227,908,1,2043, +774,1,1657,894,1, +1860,821,1,2136,842, +1,2021,718,1,2459, +882,1,1574,799,1, +2105,3136,16,0,578, +1,1931,861,1,1873, +835,1,2031,736,1, +1803,787,1,1989,3137, +16,0,451,1,2464, +899,1,2029,725,1, +2030,731,1,2364,827, +1,2032,741,1,2033, +746,1,2045,779,1, +44,3138,19,264,1, +44,3139,5,38,1, +1901,3140,16,0,262, +1,2075,3141,16,0, +262,1,1860,821,1, +1803,787,1,1804,3142, +16,0,262,1,2413, +3143,16,0,262,1, +2198,3144,16,0,262, +1,1873,835,1,1657, +894,1,1989,916,1, +1990,3145,16,0,262, +1,1775,3146,16,0, +262,1,32,3147,16, +0,262,1,2105,814, +1,2106,3148,16,0, +262,1,2364,827,1, +2227,908,1,2337,3149, +16,0,262,1,2021, +718,1,2458,876,1, +2459,882,1,2462,889, +1,2136,842,1,2464, +899,1,2029,725,1, +2030,731,1,2031,736, +1,2032,741,1,2033, +746,1,2035,752,1, +2037,757,1,2039,762, +1,1931,861,1,2041, +768,1,2043,774,1, +2045,779,1,1574,799, +1,1958,3150,16,0, +262,1,45,3151,19, +287,1,45,3152,5, +39,1,1901,3153,16, +0,315,1,2075,3154, +16,0,315,1,1860, 821,1,1803,787,1, -1804,3133,16,0,669, -1,2413,3134,16,0, -669,1,2198,3135,16, -0,669,1,1873,835, +1804,3155,16,0,315, +1,2413,3156,16,0, +315,1,2198,3157,16, +0,315,1,1873,835, 1,1657,894,1,1989, -916,1,1990,3136,16, -0,669,1,1775,3137, -16,0,669,1,32, -3138,16,0,669,1, -2105,814,1,2106,3139, -16,0,669,1,2364, +916,1,1990,3158,16, +0,315,1,1775,3159, +16,0,315,1,32, +3160,16,0,315,1, +2105,814,1,2106,3161, +16,0,315,1,2364, 827,1,2227,908,1, -2337,3140,16,0,669, +2337,3162,16,0,315, 1,2021,718,1,2458, 876,1,2459,882,1, 2462,889,1,2136,842, @@ -8373,67 +8362,111 @@ public yyLSLSyntax 2039,762,1,1931,861, 1,2041,768,1,2043, 774,1,2045,779,1, -1574,799,1,1958,3141, -16,0,669,1,47, -3142,19,466,1,47, -3143,5,19,1,0, -3144,16,0,464,1, -2706,3145,16,0,464, -1,2634,691,1,2636, -3146,16,0,464,1, -2639,707,1,2714,3147, -17,3148,15,3149,4, -36,37,0,71,0, -108,0,111,0,98, -0,97,0,108,0, -68,0,101,0,102, -0,105,0,110,0, -105,0,116,0,105, -0,111,0,110,0, -115,0,1,-1,1, -5,3150,20,3151,4, -38,71,0,108,0, +1832,3163,16,0,285, +1,1574,799,1,1958, +3164,16,0,315,1, +46,3165,19,671,1, +46,3166,5,38,1, +1901,3167,16,0,669, +1,2075,3168,16,0, +669,1,1860,821,1, +1803,787,1,1804,3169, +16,0,669,1,2413, +3170,16,0,669,1, +2198,3171,16,0,669, +1,1873,835,1,1657, +894,1,1989,916,1, +1990,3172,16,0,669, +1,1775,3173,16,0, +669,1,32,3174,16, +0,669,1,2105,814, +1,2106,3175,16,0, +669,1,2364,827,1, +2227,908,1,2337,3176, +16,0,669,1,2021, +718,1,2458,876,1, +2459,882,1,2462,889, +1,2136,842,1,2464, +899,1,2029,725,1, +2030,731,1,2031,736, +1,2032,741,1,2033, +746,1,2035,752,1, +2037,757,1,2039,762, +1,1931,861,1,2041, +768,1,2043,774,1, +2045,779,1,1574,799, +1,1958,3177,16,0, +669,1,47,3178,19, +466,1,47,3179,5, +19,1,0,3180,16, +0,464,1,2706,3181, +16,0,464,1,2634, +691,1,2636,3182,16, +0,464,1,2639,707, +1,2714,3183,17,3184, +15,3185,4,36,37, +0,71,0,108,0, 111,0,98,0,97, 0,108,0,68,0, 101,0,102,0,105, 0,110,0,105,0, 116,0,105,0,111, 0,110,0,115,0, -95,0,50,0,1, -145,1,3,1,3, -1,2,3152,22,1, -4,1,2558,697,1, -2716,3153,17,3154,15, -3149,1,-1,1,5, -3155,20,3156,4,38, -71,0,108,0,111, -0,98,0,97,0, -108,0,68,0,101, -0,102,0,105,0, -110,0,105,0,116, -0,105,0,111,0, -110,0,115,0,95, -0,49,0,1,144, -1,3,1,2,1, -1,3157,22,1,3, -1,2022,3158,16,0, -567,1,2459,882,1, -2715,3159,17,3160,15, -3149,1,-1,1,5, -3161,20,3162,4,38, -71,0,108,0,111, -0,98,0,97,0, -108,0,68,0,101, -0,102,0,105,0, -110,0,105,0,116, -0,105,0,111,0, -110,0,115,0,95, -0,51,0,1,146, -1,3,1,2,1, -1,3163,22,1,5, -1,2464,899,1,2466, -3164,17,3165,15,3166, -4,50,37,0,71, +1,-1,1,5,3186, +20,3187,4,38,71, +0,108,0,111,0, +98,0,97,0,108, +0,68,0,101,0, +102,0,105,0,110, +0,105,0,116,0, +105,0,111,0,110, +0,115,0,95,0, +50,0,1,145,1, +3,1,3,1,2, +3188,22,1,4,1, +2558,697,1,2716,3189, +17,3190,15,3185,1, +-1,1,5,3191,20, +3192,4,38,71,0, +108,0,111,0,98, +0,97,0,108,0, +68,0,101,0,102, +0,105,0,110,0, +105,0,116,0,105, +0,111,0,110,0, +115,0,95,0,49, +0,1,144,1,3, +1,2,1,1,3193, +22,1,3,1,2022, +3194,16,0,567,1, +2459,882,1,2715,3195, +17,3196,15,3185,1, +-1,1,5,3197,20, +3198,4,38,71,0, +108,0,111,0,98, +0,97,0,108,0, +68,0,101,0,102, +0,105,0,110,0, +105,0,116,0,105, +0,111,0,110,0, +115,0,95,0,51, +0,1,146,1,3, +1,2,1,1,3199, +22,1,5,1,2464, +899,1,2466,3200,17, +3201,15,3202,4,50, +37,0,71,0,108, +0,111,0,98,0, +97,0,108,0,70, +0,117,0,110,0, +99,0,116,0,105, +0,111,0,110,0, +68,0,101,0,102, +0,105,0,110,0, +105,0,116,0,105, +0,111,0,110,0, +1,-1,1,5,3203, +20,3204,4,52,71, 0,108,0,111,0, 98,0,97,0,108, 0,70,0,117,0, @@ -8443,82 +8476,53 @@ public yyLSLSyntax 0,102,0,105,0, 110,0,105,0,116, 0,105,0,111,0, -110,0,1,-1,1, -5,3167,20,3168,4, -52,71,0,108,0, -111,0,98,0,97, -0,108,0,70,0, -117,0,110,0,99, -0,116,0,105,0, -111,0,110,0,68, +110,0,95,0,50, +0,1,151,1,3, +1,7,1,6,3205, +22,1,10,1,2640, +685,1,2713,3206,17, +3207,15,3185,1,-1, +1,5,3208,20,3209, +4,38,71,0,108, +0,111,0,98,0, +97,0,108,0,68, 0,101,0,102,0, 105,0,110,0,105, 0,116,0,105,0, -111,0,110,0,95, -0,50,0,1,151, -1,3,1,7,1, -6,3169,22,1,10, -1,2640,685,1,2713, -3170,17,3171,15,3149, -1,-1,1,5,3172, -20,3173,4,38,71, -0,108,0,111,0, -98,0,97,0,108, +111,0,110,0,115, +0,95,0,52,0, +1,147,1,3,1, +3,1,2,3210,22, +1,6,1,2655,3211, +17,3212,15,3202,1, +-1,1,5,3213,20, +3214,4,52,71,0, +108,0,111,0,98, +0,97,0,108,0, +70,0,117,0,110, +0,99,0,116,0, +105,0,111,0,110, 0,68,0,101,0, 102,0,105,0,110, 0,105,0,116,0, 105,0,111,0,110, -0,115,0,95,0, -52,0,1,147,1, -3,1,3,1,2, -3174,22,1,6,1, -2655,3175,17,3176,15, -3166,1,-1,1,5, -3177,20,3178,4,52, -71,0,108,0,111, -0,98,0,97,0, -108,0,70,0,117, -0,110,0,99,0, -116,0,105,0,111, -0,110,0,68,0, -101,0,102,0,105, -0,110,0,105,0, +0,95,0,49,0, +1,150,1,3,1, +6,1,5,3215,22, +1,9,1,2694,3216, +17,3217,15,3218,4, +52,37,0,71,0, +108,0,111,0,98, +0,97,0,108,0, +86,0,97,0,114, +0,105,0,97,0, +98,0,108,0,101, +0,68,0,101,0, +99,0,108,0,97, +0,114,0,97,0, 116,0,105,0,111, -0,110,0,95,0, -49,0,1,150,1, -3,1,6,1,5, -3179,22,1,9,1, -2694,3180,17,3181,15, -3182,4,52,37,0, -71,0,108,0,111, -0,98,0,97,0, -108,0,86,0,97, -0,114,0,105,0, -97,0,98,0,108, -0,101,0,68,0, -101,0,99,0,108, -0,97,0,114,0, -97,0,116,0,105, -0,111,0,110,0, -1,-1,1,5,3183, -20,3184,4,54,71, -0,108,0,111,0, -98,0,97,0,108, -0,86,0,97,0, -114,0,105,0,97, -0,98,0,108,0, -101,0,68,0,101, -0,99,0,108,0, -97,0,114,0,97, -0,116,0,105,0, -111,0,110,0,95, -0,49,0,1,148, -1,3,1,3,1, -2,3185,22,1,7, -1,2695,3186,16,0, -464,1,2683,3187,17, -3188,15,3182,1,-1, -1,5,3189,20,3190, +0,110,0,1,-1, +1,5,3219,20,3220, 4,54,71,0,108, 0,111,0,98,0, 97,0,108,0,86, @@ -8529,72 +8533,121 @@ public yyLSLSyntax 0,108,0,97,0, 114,0,97,0,116, 0,105,0,111,0, -110,0,95,0,50, -0,1,149,1,3, -1,5,1,4,3191, -22,1,8,1,48, -3192,19,339,1,48, -3193,5,54,1,0, -3194,16,0,337,1, -2075,3195,16,0,495, -1,1860,821,1,1803, -787,1,1804,3196,16, -0,495,1,2413,3197, -16,0,495,1,2634, -691,1,1873,835,1, -1657,894,1,2639,707, -1,2640,685,1,1989, -916,1,1990,3198,16, -0,495,1,2459,882, -1,1775,3199,16,0, -495,1,32,3200,16, -0,495,1,2105,814, -1,2106,3201,16,0, -495,1,2466,3164,1, -2655,3175,1,2683,3187, -1,2227,908,1,2337, -3202,16,0,495,1, -2558,697,1,2694,3180, -1,2695,3203,16,0, -337,1,2021,718,1, -2458,876,1,1901,3204, -16,0,495,1,2462, -889,1,2136,842,1, -2464,899,1,2029,725, -1,2030,731,1,2031, -736,1,2032,741,1, -2033,746,1,2035,752, -1,2364,827,1,2715, -3159,1,2039,762,1, +110,0,95,0,49, +0,1,148,1,3, +1,3,1,2,3221, +22,1,7,1,2695, +3222,16,0,464,1, +2683,3223,17,3224,15, +3218,1,-1,1,5, +3225,20,3226,4,54, +71,0,108,0,111, +0,98,0,97,0, +108,0,86,0,97, +0,114,0,105,0, +97,0,98,0,108, +0,101,0,68,0, +101,0,99,0,108, +0,97,0,114,0, +97,0,116,0,105, +0,111,0,110,0, +95,0,50,0,1, +149,1,3,1,5, +1,4,3227,22,1, +8,1,48,3228,19, +339,1,48,3229,5, +54,1,0,3230,16, +0,337,1,2075,3231, +16,0,495,1,1860, +821,1,1803,787,1, +1804,3232,16,0,495, +1,2413,3233,16,0, +495,1,2634,691,1, +1873,835,1,1657,894, +1,2639,707,1,2640, +685,1,1989,916,1, +1990,3234,16,0,495, +1,2459,882,1,1775, +3235,16,0,495,1, +32,3236,16,0,495, +1,2105,814,1,2106, +3237,16,0,495,1, +2466,3200,1,2655,3211, +1,2683,3223,1,2227, +908,1,2337,3238,16, +0,495,1,2558,697, +1,2694,3216,1,2695, +3239,16,0,337,1, +2021,718,1,2458,876, +1,1901,3240,16,0, +495,1,2462,889,1, +2136,842,1,2464,899, +1,2029,725,1,2030, +731,1,2031,736,1, +2032,741,1,2033,746, +1,2035,752,1,2364, +827,1,2715,3195,1, +2039,762,1,1931,861, +1,2041,768,1,2043, +774,1,2045,779,1, +2198,3241,16,0,495, +1,2706,3242,16,0, +337,1,2037,757,1, +2713,3206,1,2714,3183, +1,1574,799,1,2716, +3189,1,2636,3243,16, +0,337,1,1958,3244, +16,0,495,1,49, +3245,19,500,1,49, +3246,5,38,1,1901, +3247,16,0,498,1, +2075,3248,16,0,498, +1,1860,821,1,1803, +787,1,1804,3249,16, +0,498,1,2413,3250, +16,0,498,1,2198, +3251,16,0,498,1, +1873,835,1,1657,894, +1,1989,916,1,1990, +3252,16,0,498,1, +1775,3253,16,0,498, +1,32,3254,16,0, +498,1,2105,814,1, +2106,3255,16,0,498, +1,2364,827,1,2227, +908,1,2337,3256,16, +0,498,1,2021,718, +1,2458,876,1,2459, +882,1,2462,889,1, +2136,842,1,2464,899, +1,2029,725,1,2030, +731,1,2031,736,1, +2032,741,1,2033,746, +1,2035,752,1,2037, +757,1,2039,762,1, 1931,861,1,2041,768, 1,2043,774,1,2045, -779,1,2198,3205,16, -0,495,1,2706,3206, -16,0,337,1,2037, -757,1,2713,3170,1, -2714,3147,1,1574,799, -1,2716,3153,1,2636, -3207,16,0,337,1, -1958,3208,16,0,495, -1,49,3209,19,500, -1,49,3210,5,38, -1,1901,3211,16,0, -498,1,2075,3212,16, -0,498,1,1860,821, +779,1,1574,799,1, +1958,3257,16,0,498, +1,50,3258,19,614, +1,50,3259,5,38, +1,1901,3260,16,0, +612,1,2075,3261,16, +0,612,1,1860,821, 1,1803,787,1,1804, -3213,16,0,498,1, -2413,3214,16,0,498, -1,2198,3215,16,0, -498,1,1873,835,1, +3262,16,0,612,1, +2413,3263,16,0,612, +1,2198,3264,16,0, +612,1,1873,835,1, 1657,894,1,1989,916, -1,1990,3216,16,0, -498,1,1775,3217,16, -0,498,1,32,3218, -16,0,498,1,2105, -814,1,2106,3219,16, -0,498,1,2364,827, +1,1990,3265,16,0, +612,1,1775,3266,16, +0,612,1,32,3267, +16,0,612,1,2105, +814,1,2106,3268,16, +0,612,1,2364,827, 1,2227,908,1,2337, -3220,16,0,498,1, +3269,16,0,612,1, 2021,718,1,2458,876, 1,2459,882,1,2462, 889,1,2136,842,1, @@ -8606,2127 +8659,2076 @@ public yyLSLSyntax 762,1,1931,861,1, 2041,768,1,2043,774, 1,2045,779,1,1574, -799,1,1958,3221,16, -0,498,1,50,3222, -19,614,1,50,3223, -5,38,1,1901,3224, -16,0,612,1,2075, -3225,16,0,612,1, -1860,821,1,1803,787, -1,1804,3226,16,0, -612,1,2413,3227,16, -0,612,1,2198,3228, -16,0,612,1,1873, -835,1,1657,894,1, -1989,916,1,1990,3229, -16,0,612,1,1775, -3230,16,0,612,1, -32,3231,16,0,612, -1,2105,814,1,2106, -3232,16,0,612,1, -2364,827,1,2227,908, -1,2337,3233,16,0, -612,1,2021,718,1, -2458,876,1,2459,882, -1,2462,889,1,2136, -842,1,2464,899,1, -2029,725,1,2030,731, -1,2031,736,1,2032, -741,1,2033,746,1, -2035,752,1,2037,757, -1,2039,762,1,1931, -861,1,2041,768,1, -2043,774,1,2045,779, -1,1574,799,1,1958, -3234,16,0,612,1, -51,3235,19,127,1, -51,3236,5,53,1, -0,3237,16,0,125, -1,2075,3238,16,0, -125,1,1860,821,1, -1803,787,1,1804,3239, -16,0,125,1,10, -3240,16,0,125,1, -2413,3241,16,0,125, -1,2198,3242,16,0, -125,1,1873,835,1, -21,3243,16,0,125, -1,1657,894,1,2030, -731,1,2642,3244,16, -0,125,1,1989,916, -1,1990,3245,16,0, -125,1,2459,882,1, -1775,3246,16,0,125, -1,32,3247,16,0, -125,1,2105,814,1, -2106,3248,16,0,125, -1,2655,3175,1,2683, -3187,1,2227,908,1, -2337,3249,16,0,125, -1,52,3250,16,0, -125,1,2694,3180,1, -2695,3251,16,0,125, -1,2021,718,1,2458, -876,1,1901,3252,16, -0,125,1,2462,889, -1,2136,842,1,2464, -899,1,2029,725,1, -2466,3164,1,2031,736, -1,2032,741,1,2033, -746,1,2035,752,1, -2364,827,1,2715,3159, -1,2039,762,1,1931, -861,1,2041,768,1, -2043,774,1,2045,779, -1,2037,757,1,2713, -3170,1,2714,3147,1, -1574,799,1,2716,3153, -1,1958,3253,16,0, -125,1,2506,3254,16, -0,125,1,52,3255, -19,124,1,52,3256, -5,53,1,0,3257, -16,0,122,1,2075, -3258,16,0,122,1, +799,1,1958,3270,16, +0,612,1,51,3271, +19,127,1,51,3272, +5,53,1,0,3273, +16,0,125,1,2075, +3274,16,0,125,1, 1860,821,1,1803,787, -1,1804,3259,16,0, -122,1,10,3260,16, -0,122,1,2413,3261, -16,0,122,1,2198, -3262,16,0,122,1, -1873,835,1,21,3263, -16,0,122,1,1657, +1,1804,3275,16,0, +125,1,10,3276,16, +0,125,1,2413,3277, +16,0,125,1,2198, +3278,16,0,125,1, +1873,835,1,21,3279, +16,0,125,1,1657, 894,1,2030,731,1, -2642,3264,16,0,122, +2642,3280,16,0,125, 1,1989,916,1,1990, -3265,16,0,122,1, -2459,882,1,1775,3266, -16,0,122,1,32, -3267,16,0,122,1, -2105,814,1,2106,3268, -16,0,122,1,2655, -3175,1,2683,3187,1, -2227,908,1,2337,3269, -16,0,122,1,52, -3270,16,0,122,1, -2694,3180,1,2695,3271, -16,0,122,1,2021, +3281,16,0,125,1, +2459,882,1,1775,3282, +16,0,125,1,32, +3283,16,0,125,1, +2105,814,1,2106,3284, +16,0,125,1,2655, +3211,1,2683,3223,1, +2227,908,1,2337,3285, +16,0,125,1,52, +3286,16,0,125,1, +2694,3216,1,2695,3287, +16,0,125,1,2021, 718,1,2458,876,1, -1901,3272,16,0,122, +1901,3288,16,0,125, 1,2462,889,1,2136, 842,1,2464,899,1, -2029,725,1,2466,3164, +2029,725,1,2466,3200, 1,2031,736,1,2032, 741,1,2033,746,1, 2035,752,1,2364,827, -1,2715,3159,1,2039, +1,2715,3195,1,2039, 762,1,1931,861,1, 2041,768,1,2043,774, 1,2045,779,1,2037, -757,1,2713,3170,1, -2714,3147,1,1574,799, -1,2716,3153,1,1958, -3273,16,0,122,1, -2506,3274,16,0,122, -1,53,3275,19,121, -1,53,3276,5,53, -1,0,3277,16,0, -119,1,2075,3278,16, -0,119,1,1860,821, +757,1,2713,3206,1, +2714,3183,1,1574,799, +1,2716,3189,1,1958, +3289,16,0,125,1, +2506,3290,16,0,125, +1,52,3291,19,124, +1,52,3292,5,53, +1,0,3293,16,0, +122,1,2075,3294,16, +0,122,1,1860,821, 1,1803,787,1,1804, -3279,16,0,119,1, -10,3280,16,0,119, -1,2413,3281,16,0, -119,1,2198,3282,16, -0,119,1,1873,835, -1,21,3283,16,0, -119,1,1657,894,1, -2030,731,1,2642,3284, -16,0,119,1,1989, -916,1,1990,3285,16, -0,119,1,2459,882, -1,1775,3286,16,0, -119,1,32,3287,16, -0,119,1,2105,814, -1,2106,3288,16,0, -119,1,2655,3175,1, -2683,3187,1,2227,908, -1,2337,3289,16,0, -119,1,52,3290,16, -0,119,1,2694,3180, -1,2695,3291,16,0, -119,1,2021,718,1, -2458,876,1,1901,3292, -16,0,119,1,2462, +3295,16,0,122,1, +10,3296,16,0,122, +1,2413,3297,16,0, +122,1,2198,3298,16, +0,122,1,1873,835, +1,21,3299,16,0, +122,1,1657,894,1, +2030,731,1,2642,3300, +16,0,122,1,1989, +916,1,1990,3301,16, +0,122,1,2459,882, +1,1775,3302,16,0, +122,1,32,3303,16, +0,122,1,2105,814, +1,2106,3304,16,0, +122,1,2655,3211,1, +2683,3223,1,2227,908, +1,2337,3305,16,0, +122,1,52,3306,16, +0,122,1,2694,3216, +1,2695,3307,16,0, +122,1,2021,718,1, +2458,876,1,1901,3308, +16,0,122,1,2462, 889,1,2136,842,1, 2464,899,1,2029,725, -1,2466,3164,1,2031, +1,2466,3200,1,2031, 736,1,2032,741,1, 2033,746,1,2035,752, 1,2364,827,1,2715, -3159,1,2039,762,1, +3195,1,2039,762,1, 1931,861,1,2041,768, 1,2043,774,1,2045, 779,1,2037,757,1, -2713,3170,1,2714,3147, +2713,3206,1,2714,3183, 1,1574,799,1,2716, -3153,1,1958,3293,16, -0,119,1,2506,3294, -16,0,119,1,54, -3295,19,118,1,54, -3296,5,53,1,0, -3297,16,0,116,1, -2075,3298,16,0,116, +3189,1,1958,3309,16, +0,122,1,2506,3310, +16,0,122,1,53, +3311,19,121,1,53, +3312,5,53,1,0, +3313,16,0,119,1, +2075,3314,16,0,119, 1,1860,821,1,1803, -787,1,1804,3299,16, -0,116,1,10,3300, -16,0,116,1,2413, -3301,16,0,116,1, -2198,3302,16,0,116, +787,1,1804,3315,16, +0,119,1,10,3316, +16,0,119,1,2413, +3317,16,0,119,1, +2198,3318,16,0,119, 1,1873,835,1,21, -3303,16,0,116,1, +3319,16,0,119,1, 1657,894,1,2030,731, -1,2642,3304,16,0, -116,1,1989,916,1, -1990,3305,16,0,116, +1,2642,3320,16,0, +119,1,1989,916,1, +1990,3321,16,0,119, 1,2459,882,1,1775, -3306,16,0,116,1, -32,3307,16,0,116, +3322,16,0,119,1, +32,3323,16,0,119, 1,2105,814,1,2106, -3308,16,0,116,1, -2655,3175,1,2683,3187, +3324,16,0,119,1, +2655,3211,1,2683,3223, 1,2227,908,1,2337, -3309,16,0,116,1, -52,3310,16,0,116, -1,2694,3180,1,2695, -3311,16,0,116,1, +3325,16,0,119,1, +52,3326,16,0,119, +1,2694,3216,1,2695, +3327,16,0,119,1, 2021,718,1,2458,876, -1,1901,3312,16,0, -116,1,2462,889,1, +1,1901,3328,16,0, +119,1,2462,889,1, 2136,842,1,2464,899, 1,2029,725,1,2466, -3164,1,2031,736,1, +3200,1,2031,736,1, 2032,741,1,2033,746, 1,2035,752,1,2364, -827,1,2715,3159,1, +827,1,2715,3195,1, 2039,762,1,1931,861, 1,2041,768,1,2043, 774,1,2045,779,1, -2037,757,1,2713,3170, -1,2714,3147,1,1574, -799,1,2716,3153,1, -1958,3313,16,0,116, -1,2506,3314,16,0, -116,1,55,3315,19, -115,1,55,3316,5, -53,1,0,3317,16, -0,113,1,2075,3318, -16,0,113,1,1860, +2037,757,1,2713,3206, +1,2714,3183,1,1574, +799,1,2716,3189,1, +1958,3329,16,0,119, +1,2506,3330,16,0, +119,1,54,3331,19, +118,1,54,3332,5, +53,1,0,3333,16, +0,116,1,2075,3334, +16,0,116,1,1860, 821,1,1803,787,1, -1804,3319,16,0,113, -1,10,3320,16,0, -113,1,2413,3321,16, -0,113,1,2198,3322, -16,0,113,1,1873, -835,1,21,3323,16, -0,113,1,1657,894, +1804,3335,16,0,116, +1,10,3336,16,0, +116,1,2413,3337,16, +0,116,1,2198,3338, +16,0,116,1,1873, +835,1,21,3339,16, +0,116,1,1657,894, 1,2030,731,1,2642, -3324,16,0,113,1, -1989,916,1,1990,3325, -16,0,113,1,2459, -882,1,1775,3326,16, -0,113,1,32,3327, -16,0,113,1,2105, -814,1,2106,3328,16, -0,113,1,2655,3175, -1,2683,3187,1,2227, -908,1,2337,3329,16, -0,113,1,52,3330, -16,0,113,1,2694, -3180,1,2695,3331,16, -0,113,1,2021,718, +3340,16,0,116,1, +1989,916,1,1990,3341, +16,0,116,1,2459, +882,1,1775,3342,16, +0,116,1,32,3343, +16,0,116,1,2105, +814,1,2106,3344,16, +0,116,1,2655,3211, +1,2683,3223,1,2227, +908,1,2337,3345,16, +0,116,1,52,3346, +16,0,116,1,2694, +3216,1,2695,3347,16, +0,116,1,2021,718, 1,2458,876,1,1901, -3332,16,0,113,1, +3348,16,0,116,1, 2462,889,1,2136,842, 1,2464,899,1,2029, -725,1,2466,3164,1, +725,1,2466,3200,1, 2031,736,1,2032,741, 1,2033,746,1,2035, 752,1,2364,827,1, -2715,3159,1,2039,762, +2715,3195,1,2039,762, 1,1931,861,1,2041, 768,1,2043,774,1, 2045,779,1,2037,757, -1,2713,3170,1,2714, -3147,1,1574,799,1, -2716,3153,1,1958,3333, -16,0,113,1,2506, -3334,16,0,113,1, -56,3335,19,112,1, -56,3336,5,53,1, -0,3337,16,0,110, -1,2075,3338,16,0, -110,1,1860,821,1, -1803,787,1,1804,3339, -16,0,110,1,10, -3340,16,0,110,1, -2413,3341,16,0,110, -1,2198,3342,16,0, -110,1,1873,835,1, -21,3343,16,0,110, +1,2713,3206,1,2714, +3183,1,1574,799,1, +2716,3189,1,1958,3349, +16,0,116,1,2506, +3350,16,0,116,1, +55,3351,19,115,1, +55,3352,5,53,1, +0,3353,16,0,113, +1,2075,3354,16,0, +113,1,1860,821,1, +1803,787,1,1804,3355, +16,0,113,1,10, +3356,16,0,113,1, +2413,3357,16,0,113, +1,2198,3358,16,0, +113,1,1873,835,1, +21,3359,16,0,113, 1,1657,894,1,2030, -731,1,2642,3344,16, -0,110,1,1989,916, -1,1990,3345,16,0, -110,1,2459,882,1, -1775,3346,16,0,110, -1,32,3347,16,0, -110,1,2105,814,1, -2106,3348,16,0,110, -1,2655,3175,1,2683, -3187,1,2227,908,1, -2337,3349,16,0,110, -1,52,3350,16,0, -110,1,2694,3180,1, -2695,3351,16,0,110, +731,1,2642,3360,16, +0,113,1,1989,916, +1,1990,3361,16,0, +113,1,2459,882,1, +1775,3362,16,0,113, +1,32,3363,16,0, +113,1,2105,814,1, +2106,3364,16,0,113, +1,2655,3211,1,2683, +3223,1,2227,908,1, +2337,3365,16,0,113, +1,52,3366,16,0, +113,1,2694,3216,1, +2695,3367,16,0,113, 1,2021,718,1,2458, -876,1,1901,3352,16, -0,110,1,2462,889, +876,1,1901,3368,16, +0,113,1,2462,889, 1,2136,842,1,2464, 899,1,2029,725,1, -2466,3164,1,2031,736, +2466,3200,1,2031,736, 1,2032,741,1,2033, 746,1,2035,752,1, -2364,827,1,2715,3159, +2364,827,1,2715,3195, 1,2039,762,1,1931, 861,1,2041,768,1, 2043,774,1,2045,779, 1,2037,757,1,2713, -3170,1,2714,3147,1, -1574,799,1,2716,3153, -1,1958,3353,16,0, -110,1,2506,3354,16, -0,110,1,57,3355, -19,109,1,57,3356, -5,53,1,0,3357, -16,0,107,1,2075, -3358,16,0,107,1, +3206,1,2714,3183,1, +1574,799,1,2716,3189, +1,1958,3369,16,0, +113,1,2506,3370,16, +0,113,1,56,3371, +19,112,1,56,3372, +5,53,1,0,3373, +16,0,110,1,2075, +3374,16,0,110,1, 1860,821,1,1803,787, -1,1804,3359,16,0, -107,1,10,3360,16, -0,107,1,2413,3361, -16,0,107,1,2198, -3362,16,0,107,1, -1873,835,1,21,3363, -16,0,107,1,1657, +1,1804,3375,16,0, +110,1,10,3376,16, +0,110,1,2413,3377, +16,0,110,1,2198, +3378,16,0,110,1, +1873,835,1,21,3379, +16,0,110,1,1657, 894,1,2030,731,1, -2642,3364,16,0,107, +2642,3380,16,0,110, 1,1989,916,1,1990, -3365,16,0,107,1, -2459,882,1,1775,3366, -16,0,107,1,32, -3367,16,0,107,1, -2105,814,1,2106,3368, -16,0,107,1,2655, -3175,1,2683,3187,1, -2227,908,1,2337,3369, -16,0,107,1,52, -3370,16,0,107,1, -2694,3180,1,2695,3371, -16,0,107,1,2021, +3381,16,0,110,1, +2459,882,1,1775,3382, +16,0,110,1,32, +3383,16,0,110,1, +2105,814,1,2106,3384, +16,0,110,1,2655, +3211,1,2683,3223,1, +2227,908,1,2337,3385, +16,0,110,1,52, +3386,16,0,110,1, +2694,3216,1,2695,3387, +16,0,110,1,2021, 718,1,2458,876,1, -1901,3372,16,0,107, +1901,3388,16,0,110, 1,2462,889,1,2136, 842,1,2464,899,1, -2029,725,1,2466,3164, +2029,725,1,2466,3200, 1,2031,736,1,2032, 741,1,2033,746,1, 2035,752,1,2364,827, -1,2715,3159,1,2039, +1,2715,3195,1,2039, 762,1,1931,861,1, 2041,768,1,2043,774, 1,2045,779,1,2037, -757,1,2713,3170,1, -2714,3147,1,1574,799, -1,2716,3153,1,1958, -3373,16,0,107,1, -2506,3374,16,0,107, -1,58,3375,19,429, -1,58,3376,5,9, -1,2519,1618,1,2557, -1627,1,2521,3377,16, -0,427,1,2559,1633, -1,2597,3378,16,0, -427,1,2561,3379,16, -0,427,1,2459,882, -1,2464,899,1,2470, -3380,16,0,427,1, -59,3381,19,426,1, -59,3382,5,9,1, -2519,1618,1,2557,1627, -1,2521,3383,16,0, -424,1,2559,1633,1, -2597,3384,16,0,424, -1,2561,3385,16,0, -424,1,2459,882,1, -2464,899,1,2470,3386, -16,0,424,1,60, -3387,19,423,1,60, -3388,5,9,1,2519, +757,1,2713,3206,1, +2714,3183,1,1574,799, +1,2716,3189,1,1958, +3389,16,0,110,1, +2506,3390,16,0,110, +1,57,3391,19,109, +1,57,3392,5,53, +1,0,3393,16,0, +107,1,2075,3394,16, +0,107,1,1860,821, +1,1803,787,1,1804, +3395,16,0,107,1, +10,3396,16,0,107, +1,2413,3397,16,0, +107,1,2198,3398,16, +0,107,1,1873,835, +1,21,3399,16,0, +107,1,1657,894,1, +2030,731,1,2642,3400, +16,0,107,1,1989, +916,1,1990,3401,16, +0,107,1,2459,882, +1,1775,3402,16,0, +107,1,32,3403,16, +0,107,1,2105,814, +1,2106,3404,16,0, +107,1,2655,3211,1, +2683,3223,1,2227,908, +1,2337,3405,16,0, +107,1,52,3406,16, +0,107,1,2694,3216, +1,2695,3407,16,0, +107,1,2021,718,1, +2458,876,1,1901,3408, +16,0,107,1,2462, +889,1,2136,842,1, +2464,899,1,2029,725, +1,2466,3200,1,2031, +736,1,2032,741,1, +2033,746,1,2035,752, +1,2364,827,1,2715, +3195,1,2039,762,1, +1931,861,1,2041,768, +1,2043,774,1,2045, +779,1,2037,757,1, +2713,3206,1,2714,3183, +1,1574,799,1,2716, +3189,1,1958,3409,16, +0,107,1,2506,3410, +16,0,107,1,58, +3411,19,429,1,58, +3412,5,9,1,2519, 1618,1,2557,1627,1, -2521,3389,16,0,421, +2521,3413,16,0,427, 1,2559,1633,1,2597, -3390,16,0,421,1, -2561,3391,16,0,421, +3414,16,0,427,1, +2561,3415,16,0,427, 1,2459,882,1,2464, -899,1,2470,3392,16, -0,421,1,61,3393, -19,420,1,61,3394, +899,1,2470,3416,16, +0,427,1,59,3417, +19,426,1,59,3418, 5,9,1,2519,1618, 1,2557,1627,1,2521, -3395,16,0,418,1, -2559,1633,1,2597,3396, -16,0,418,1,2561, -3397,16,0,418,1, +3419,16,0,424,1, +2559,1633,1,2597,3420, +16,0,424,1,2561, +3421,16,0,424,1, 2459,882,1,2464,899, -1,2470,3398,16,0, -418,1,62,3399,19, -417,1,62,3400,5, +1,2470,3422,16,0, +424,1,60,3423,19, +423,1,60,3424,5, 9,1,2519,1618,1, -2557,1627,1,2521,3401, -16,0,415,1,2559, -1633,1,2597,3402,16, -0,415,1,2561,3403, -16,0,415,1,2459, +2557,1627,1,2521,3425, +16,0,421,1,2559, +1633,1,2597,3426,16, +0,421,1,2561,3427, +16,0,421,1,2459, 882,1,2464,899,1, -2470,3404,16,0,415, -1,63,3405,19,414, -1,63,3406,5,9, +2470,3428,16,0,421, +1,61,3429,19,420, +1,61,3430,5,9, 1,2519,1618,1,2557, -1627,1,2521,3407,16, -0,412,1,2559,1633, -1,2597,3408,16,0, -412,1,2561,3409,16, -0,412,1,2459,882, +1627,1,2521,3431,16, +0,418,1,2559,1633, +1,2597,3432,16,0, +418,1,2561,3433,16, +0,418,1,2459,882, 1,2464,899,1,2470, -3410,16,0,412,1, -64,3411,19,653,1, -64,3412,5,9,1, +3434,16,0,418,1, +62,3435,19,417,1, +62,3436,5,9,1, 2519,1618,1,2557,1627, -1,2521,3413,16,0, -651,1,2559,1633,1, -2597,3414,16,0,651, -1,2561,3415,16,0, -651,1,2459,882,1, -2464,899,1,2470,3416, -16,0,651,1,65, -3417,19,410,1,65, -3418,5,9,1,2519, +1,2521,3437,16,0, +415,1,2559,1633,1, +2597,3438,16,0,415, +1,2561,3439,16,0, +415,1,2459,882,1, +2464,899,1,2470,3440, +16,0,415,1,63, +3441,19,414,1,63, +3442,5,9,1,2519, 1618,1,2557,1627,1, -2521,3419,16,0,408, +2521,3443,16,0,412, 1,2559,1633,1,2597, -3420,16,0,408,1, -2561,3421,16,0,408, +3444,16,0,412,1, +2561,3445,16,0,412, 1,2459,882,1,2464, -899,1,2470,3422,16, -0,408,1,66,3423, -19,493,1,66,3424, +899,1,2470,3446,16, +0,412,1,64,3447, +19,653,1,64,3448, 5,9,1,2519,1618, 1,2557,1627,1,2521, -3425,16,0,491,1, -2559,1633,1,2597,3426, -16,0,491,1,2561, -3427,16,0,491,1, +3449,16,0,651,1, +2559,1633,1,2597,3450, +16,0,651,1,2561, +3451,16,0,651,1, 2459,882,1,2464,899, -1,2470,3428,16,0, -491,1,67,3429,19, -406,1,67,3430,5, +1,2470,3452,16,0, +651,1,65,3453,19, +410,1,65,3454,5, 9,1,2519,1618,1, -2557,1627,1,2521,3431, -16,0,404,1,2559, -1633,1,2597,3432,16, -0,404,1,2561,3433, -16,0,404,1,2459, +2557,1627,1,2521,3455, +16,0,408,1,2559, +1633,1,2597,3456,16, +0,408,1,2561,3457, +16,0,408,1,2459, 882,1,2464,899,1, -2470,3434,16,0,404, -1,68,3435,19,403, -1,68,3436,5,9, +2470,3458,16,0,408, +1,66,3459,19,493, +1,66,3460,5,9, 1,2519,1618,1,2557, -1627,1,2521,3437,16, -0,401,1,2559,1633, -1,2597,3438,16,0, -401,1,2561,3439,16, -0,401,1,2459,882, +1627,1,2521,3461,16, +0,491,1,2559,1633, +1,2597,3462,16,0, +491,1,2561,3463,16, +0,491,1,2459,882, 1,2464,899,1,2470, -3440,16,0,401,1, -69,3441,19,486,1, -69,3442,5,9,1, +3464,16,0,491,1, +67,3465,19,406,1, +67,3466,5,9,1, 2519,1618,1,2557,1627, -1,2521,3443,16,0, -484,1,2559,1633,1, -2597,3444,16,0,484, -1,2561,3445,16,0, -484,1,2459,882,1, -2464,899,1,2470,3446, -16,0,484,1,70, -3447,19,399,1,70, -3448,5,9,1,2519, +1,2521,3467,16,0, +404,1,2559,1633,1, +2597,3468,16,0,404, +1,2561,3469,16,0, +404,1,2459,882,1, +2464,899,1,2470,3470, +16,0,404,1,68, +3471,19,403,1,68, +3472,5,9,1,2519, 1618,1,2557,1627,1, -2521,3449,16,0,397, +2521,3473,16,0,401, 1,2559,1633,1,2597, -3450,16,0,397,1, -2561,3451,16,0,397, +3474,16,0,401,1, +2561,3475,16,0,401, 1,2459,882,1,2464, -899,1,2470,3452,16, -0,397,1,71,3453, -19,483,1,71,3454, +899,1,2470,3476,16, +0,401,1,69,3477, +19,486,1,69,3478, 5,9,1,2519,1618, 1,2557,1627,1,2521, -3455,16,0,481,1, -2559,1633,1,2597,3456, -16,0,481,1,2561, -3457,16,0,481,1, +3479,16,0,484,1, +2559,1633,1,2597,3480, +16,0,484,1,2561, +3481,16,0,484,1, 2459,882,1,2464,899, -1,2470,3458,16,0, -481,1,72,3459,19, -480,1,72,3460,5, +1,2470,3482,16,0, +484,1,70,3483,19, +399,1,70,3484,5, 9,1,2519,1618,1, -2557,1627,1,2521,3461, -16,0,478,1,2559, -1633,1,2597,3462,16, -0,478,1,2561,3463, -16,0,478,1,2459, +2557,1627,1,2521,3485, +16,0,397,1,2559, +1633,1,2597,3486,16, +0,397,1,2561,3487, +16,0,397,1,2459, 882,1,2464,899,1, -2470,3464,16,0,478, -1,73,3465,19,477, -1,73,3466,5,9, +2470,3488,16,0,397, +1,71,3489,19,483, +1,71,3490,5,9, 1,2519,1618,1,2557, -1627,1,2521,3467,16, -0,475,1,2559,1633, -1,2597,3468,16,0, -475,1,2561,3469,16, -0,475,1,2459,882, +1627,1,2521,3491,16, +0,481,1,2559,1633, +1,2597,3492,16,0, +481,1,2561,3493,16, +0,481,1,2459,882, 1,2464,899,1,2470, -3470,16,0,475,1, -74,3471,19,474,1, -74,3472,5,9,1, +3494,16,0,481,1, +72,3495,19,480,1, +72,3496,5,9,1, 2519,1618,1,2557,1627, -1,2521,3473,16,0, -472,1,2559,1633,1, -2597,3474,16,0,472, -1,2561,3475,16,0, -472,1,2459,882,1, -2464,899,1,2470,3476, -16,0,472,1,75, -3477,19,390,1,75, -3478,5,9,1,2519, +1,2521,3497,16,0, +478,1,2559,1633,1, +2597,3498,16,0,478, +1,2561,3499,16,0, +478,1,2459,882,1, +2464,899,1,2470,3500, +16,0,478,1,73, +3501,19,477,1,73, +3502,5,9,1,2519, 1618,1,2557,1627,1, -2521,3479,16,0,388, +2521,3503,16,0,475, 1,2559,1633,1,2597, -3480,16,0,388,1, -2561,3481,16,0,388, +3504,16,0,475,1, +2561,3505,16,0,475, 1,2459,882,1,2464, -899,1,2470,3482,16, -0,388,1,76,3483, -19,387,1,76,3484, +899,1,2470,3506,16, +0,475,1,74,3507, +19,474,1,74,3508, 5,9,1,2519,1618, 1,2557,1627,1,2521, -3485,16,0,385,1, -2559,1633,1,2597,3486, -16,0,385,1,2561, -3487,16,0,385,1, +3509,16,0,472,1, +2559,1633,1,2597,3510, +16,0,472,1,2561, +3511,16,0,472,1, 2459,882,1,2464,899, -1,2470,3488,16,0, -385,1,77,3489,19, -471,1,77,3490,5, +1,2470,3512,16,0, +472,1,75,3513,19, +390,1,75,3514,5, 9,1,2519,1618,1, -2557,1627,1,2521,3491, -16,0,469,1,2559, -1633,1,2597,3492,16, -0,469,1,2561,3493, -16,0,469,1,2459, +2557,1627,1,2521,3515, +16,0,388,1,2559, +1633,1,2597,3516,16, +0,388,1,2561,3517, +16,0,388,1,2459, 882,1,2464,899,1, -2470,3494,16,0,469, -1,78,3495,19,566, -1,78,3496,5,9, +2470,3518,16,0,388, +1,76,3519,19,387, +1,76,3520,5,9, 1,2519,1618,1,2557, -1627,1,2521,3497,16, -0,564,1,2559,1633, -1,2597,3498,16,0, -564,1,2561,3499,16, -0,564,1,2459,882, +1627,1,2521,3521,16, +0,385,1,2559,1633, +1,2597,3522,16,0, +385,1,2561,3523,16, +0,385,1,2459,882, 1,2464,899,1,2470, -3500,16,0,564,1, -79,3501,19,380,1, -79,3502,5,9,1, +3524,16,0,385,1, +77,3525,19,471,1, +77,3526,5,9,1, 2519,1618,1,2557,1627, -1,2521,3503,16,0, -378,1,2559,1633,1, -2597,3504,16,0,378, -1,2561,3505,16,0, -378,1,2459,882,1, -2464,899,1,2470,3506, -16,0,378,1,80, -3507,19,377,1,80, -3508,5,9,1,2519, +1,2521,3527,16,0, +469,1,2559,1633,1, +2597,3528,16,0,469, +1,2561,3529,16,0, +469,1,2459,882,1, +2464,899,1,2470,3530, +16,0,469,1,78, +3531,19,566,1,78, +3532,5,9,1,2519, 1618,1,2557,1627,1, -2521,3509,16,0,375, +2521,3533,16,0,564, 1,2559,1633,1,2597, -3510,16,0,375,1, -2561,3511,16,0,375, +3534,16,0,564,1, +2561,3535,16,0,564, 1,2459,882,1,2464, -899,1,2470,3512,16, -0,375,1,81,3513, -19,374,1,81,3514, +899,1,2470,3536,16, +0,564,1,79,3537, +19,380,1,79,3538, 5,9,1,2519,1618, 1,2557,1627,1,2521, -3515,16,0,372,1, -2559,1633,1,2597,3516, -16,0,372,1,2561, -3517,16,0,372,1, +3539,16,0,378,1, +2559,1633,1,2597,3540, +16,0,378,1,2561, +3541,16,0,378,1, 2459,882,1,2464,899, -1,2470,3518,16,0, -372,1,82,3519,19, -371,1,82,3520,5, +1,2470,3542,16,0, +378,1,80,3543,19, +377,1,80,3544,5, 9,1,2519,1618,1, -2557,1627,1,2521,3521, -16,0,369,1,2559, -1633,1,2597,3522,16, -0,369,1,2561,3523, -16,0,369,1,2459, +2557,1627,1,2521,3545, +16,0,375,1,2559, +1633,1,2597,3546,16, +0,375,1,2561,3547, +16,0,375,1,2459, 882,1,2464,899,1, -2470,3524,16,0,369, -1,83,3525,19,368, -1,83,3526,5,9, +2470,3548,16,0,375, +1,81,3549,19,374, +1,81,3550,5,9, 1,2519,1618,1,2557, -1627,1,2521,3527,16, -0,366,1,2559,1633, -1,2597,3528,16,0, -366,1,2561,3529,16, -0,366,1,2459,882, +1627,1,2521,3551,16, +0,372,1,2559,1633, +1,2597,3552,16,0, +372,1,2561,3553,16, +0,372,1,2459,882, 1,2464,899,1,2470, -3530,16,0,366,1, -84,3531,19,365,1, -84,3532,5,9,1, +3554,16,0,372,1, +82,3555,19,371,1, +82,3556,5,9,1, 2519,1618,1,2557,1627, -1,2521,3533,16,0, -363,1,2559,1633,1, -2597,3534,16,0,363, -1,2561,3535,16,0, -363,1,2459,882,1, -2464,899,1,2470,3536, -16,0,363,1,85, -3537,19,362,1,85, -3538,5,9,1,2519, +1,2521,3557,16,0, +369,1,2559,1633,1, +2597,3558,16,0,369, +1,2561,3559,16,0, +369,1,2459,882,1, +2464,899,1,2470,3560, +16,0,369,1,83, +3561,19,368,1,83, +3562,5,9,1,2519, 1618,1,2557,1627,1, -2521,3539,16,0,360, +2521,3563,16,0,366, 1,2559,1633,1,2597, -3540,16,0,360,1, -2561,3541,16,0,360, +3564,16,0,366,1, +2561,3565,16,0,366, 1,2459,882,1,2464, -899,1,2470,3542,16, -0,360,1,86,3543, -19,359,1,86,3544, +899,1,2470,3566,16, +0,366,1,84,3567, +19,365,1,84,3568, 5,9,1,2519,1618, 1,2557,1627,1,2521, -3545,16,0,357,1, -2559,1633,1,2597,3546, -16,0,357,1,2561, -3547,16,0,357,1, +3569,16,0,363,1, +2559,1633,1,2597,3570, +16,0,363,1,2561, +3571,16,0,363,1, 2459,882,1,2464,899, -1,2470,3548,16,0, -357,1,87,3549,19, -356,1,87,3550,5, +1,2470,3572,16,0, +363,1,85,3573,19, +362,1,85,3574,5, 9,1,2519,1618,1, -2557,1627,1,2521,3551, -16,0,354,1,2559, -1633,1,2597,3552,16, -0,354,1,2561,3553, -16,0,354,1,2459, +2557,1627,1,2521,3575, +16,0,360,1,2559, +1633,1,2597,3576,16, +0,360,1,2561,3577, +16,0,360,1,2459, 882,1,2464,899,1, -2470,3554,16,0,354, -1,88,3555,19,353, -1,88,3556,5,9, +2470,3578,16,0,360, +1,86,3579,19,359, +1,86,3580,5,9, 1,2519,1618,1,2557, -1627,1,2521,3557,16, -0,351,1,2559,1633, -1,2597,3558,16,0, -351,1,2561,3559,16, -0,351,1,2459,882, +1627,1,2521,3581,16, +0,357,1,2559,1633, +1,2597,3582,16,0, +357,1,2561,3583,16, +0,357,1,2459,882, 1,2464,899,1,2470, -3560,16,0,351,1, -89,3561,19,347,1, -89,3562,5,9,1, +3584,16,0,357,1, +87,3585,19,356,1, +87,3586,5,9,1, 2519,1618,1,2557,1627, -1,2521,3563,16,0, -345,1,2559,1633,1, -2597,3564,16,0,345, -1,2561,3565,16,0, -345,1,2459,882,1, -2464,899,1,2470,3566, -16,0,345,1,90, -3567,19,350,1,90, -3568,5,9,1,2519, +1,2521,3587,16,0, +354,1,2559,1633,1, +2597,3588,16,0,354, +1,2561,3589,16,0, +354,1,2459,882,1, +2464,899,1,2470,3590, +16,0,354,1,88, +3591,19,353,1,88, +3592,5,9,1,2519, 1618,1,2557,1627,1, -2521,3569,16,0,348, +2521,3593,16,0,351, 1,2559,1633,1,2597, -3570,16,0,348,1, -2561,3571,16,0,348, +3594,16,0,351,1, +2561,3595,16,0,351, 1,2459,882,1,2464, -899,1,2470,3572,16, -0,348,1,91,3573, -19,344,1,91,3574, +899,1,2470,3596,16, +0,351,1,89,3597, +19,347,1,89,3598, 5,9,1,2519,1618, 1,2557,1627,1,2521, -3575,16,0,342,1, -2559,1633,1,2597,3576, -16,0,342,1,2561, -3577,16,0,342,1, +3599,16,0,345,1, +2559,1633,1,2597,3600, +16,0,345,1,2561, +3601,16,0,345,1, 2459,882,1,2464,899, -1,2470,3578,16,0, -342,1,92,3579,19, -133,1,92,3580,5, -125,1,0,3581,16, -0,563,1,1,1951, -1,2,1957,1,3, -1962,1,4,1967,1, -5,1972,1,6,1977, -1,7,1982,1,8, -3582,16,0,131,1, -1515,3583,16,0,165, -1,2021,718,1,2022, -3584,16,0,497,1, -256,3585,16,0,173, -1,2025,3586,16,0, -501,1,18,3587,16, -0,138,1,2027,3588, -16,0,505,1,2695, -3589,16,0,563,1, -2029,725,1,2030,731, -1,2031,736,1,2032, -741,1,2033,746,1, -277,3590,16,0,173, -1,2035,752,1,2037, -757,1,2039,762,1, -32,3591,16,0,165, -1,2041,768,1,2293, -3592,16,0,173,1, -2043,774,1,2045,779, -1,2713,3170,1,2715, -3159,1,41,3593,16, -0,173,1,1297,3594, -16,0,165,1,43, -3595,16,0,173,1, -46,3596,16,0,178, -1,1804,3597,16,0, -165,1,299,3598,16, -0,173,1,52,3599, -16,0,165,1,509, -3600,16,0,173,1, -2318,3601,16,0,165, -1,62,3602,16,0, -195,1,65,3603,16, -0,197,1,2075,3604, -16,0,165,1,1574, -799,1,71,3605,16, -0,173,1,1775,3606, -16,0,165,1,76, -3607,16,0,173,1, -1834,3608,16,0,165, -1,2337,3609,16,0, -165,1,79,3610,16, -0,173,1,1335,3611, -16,0,165,1,322, -3612,16,0,173,1, -85,3613,16,0,173, -1,1261,3614,16,0, -165,1,89,3615,16, -0,173,1,346,3616, -16,0,173,1,97, -3617,16,0,173,1, -2106,3618,16,0,165, -1,102,3619,16,0, -173,1,1860,821,1, -1803,787,1,2364,827, -1,1113,3620,16,0, -158,1,112,3621,16, -0,173,1,1117,3622, -16,0,165,1,1873, -835,1,1876,3623,16, -0,165,1,372,3624, -16,0,535,1,374, -3625,16,0,537,1, -124,3626,16,0,173, -1,376,3627,16,0, -539,1,378,3628,16, -0,541,1,2136,842, -1,381,3629,16,0, -173,1,525,3630,16, -0,173,1,137,3631, -16,0,173,1,1901, -3632,16,0,165,1, -2655,3175,1,2658,3633, -16,0,173,1,1153, -3634,16,0,165,1, -151,3635,16,0,173, -1,1407,3636,16,0, -165,1,1659,3637,16, -0,165,1,2413,3638, -16,0,165,1,406, -3639,16,0,173,1, -1371,3640,16,0,165, -1,2105,814,1,1657, -894,1,166,3641,16, -0,173,1,1622,3642, -16,0,173,1,2683, -3187,1,1931,861,1, -1933,3643,16,0,165, -1,431,3644,16,0, -173,1,1585,3645,16, -0,173,1,182,3646, -16,0,173,1,2694, -3180,1,1189,3647,16, -0,165,1,1443,3648, -16,0,165,1,1695, -3649,16,0,165,1, -2198,3650,16,0,165, -1,447,3651,16,0, -173,1,2458,876,1, -2459,882,1,1958,3652, -16,0,165,1,2462, -889,1,2714,3147,1, -2464,899,1,2716,3153, -1,2466,3164,1,459, -3653,16,0,173,1, -2468,3654,16,0,340, -1,462,3655,16,0, -173,1,199,3656,16, -0,173,1,217,3657, -16,0,173,1,2227, -908,1,1225,3658,16, -0,165,1,1479,3659, -16,0,165,1,1731, -3660,16,0,173,1, -1989,916,1,1990,3661, -16,0,165,1,236, -3662,16,0,173,1, -1756,3663,16,0,165, -1,93,3664,19,626, -1,93,3665,5,95, -1,256,3666,16,0, -624,1,1261,3667,16, -0,624,1,509,3668, -16,0,624,1,1515, -3669,16,0,624,1, -2021,718,1,1775,3670, -16,0,624,1,2029, -725,1,2030,731,1, -2031,736,1,2032,741, -1,2033,746,1,277, -3671,16,0,624,1, -2035,752,1,2037,757, -1,2039,762,1,32, -3672,16,0,624,1, -2041,768,1,2293,3673, -16,0,624,1,2043, -774,1,2045,779,1, -41,3674,16,0,624, -1,1297,3675,16,0, -624,1,43,3676,16, -0,624,1,1803,787, -1,1804,3677,16,0, -624,1,299,3678,16, -0,624,1,52,3679, -16,0,624,1,2318, -3680,16,0,624,1, -62,3681,16,0,624, -1,2075,3682,16,0, -624,1,1574,799,1, -71,3683,16,0,624, -1,76,3684,16,0, -624,1,1834,3685,16, -0,624,1,2337,3686, -16,0,624,1,79, -3687,16,0,624,1, -1335,3688,16,0,624, -1,322,3689,16,0, -624,1,85,3690,16, -0,624,1,89,3691, -16,0,624,1,346, -3692,16,0,624,1, -2105,814,1,2106,3693, -16,0,624,1,97, -3694,16,0,624,1, -1860,821,1,2364,827, -1,102,3695,16,0, -624,1,112,3696,16, -0,624,1,1117,3697, -16,0,624,1,1873, -835,1,1876,3698,16, -0,624,1,124,3699, -16,0,624,1,2136, -842,1,381,3700,16, -0,624,1,525,3701, -16,0,624,1,137, -3702,16,0,624,1, -1901,3703,16,0,624, -1,2658,3704,16,0, -624,1,1153,3705,16, -0,624,1,151,3706, -16,0,624,1,1407, -3707,16,0,624,1, -1659,3708,16,0,624, -1,2413,3709,16,0, -624,1,406,3710,16, -0,624,1,1371,3711, -16,0,624,1,166, -3712,16,0,624,1, -1622,3713,16,0,624, -1,1931,861,1,1933, -3714,16,0,624,1, -431,3715,16,0,624, -1,1585,3716,16,0, -624,1,182,3717,16, -0,624,1,1189,3718, -16,0,624,1,1443, -3719,16,0,624,1, -1695,3720,16,0,624, -1,2198,3721,16,0, -624,1,447,3722,16, -0,624,1,2458,876, -1,2459,882,1,1958, -3723,16,0,624,1, -2462,889,1,1657,894, -1,2464,899,1,199, -3724,16,0,624,1, -459,3725,16,0,624, -1,462,3726,16,0, -624,1,217,3727,16, -0,624,1,2227,908, -1,1225,3728,16,0, -624,1,1479,3729,16, -0,624,1,1731,3730, -16,0,624,1,1989, -916,1,1990,3731,16, -0,624,1,236,3732, -16,0,624,1,1756, -3733,16,0,624,1, -94,3734,19,623,1, -94,3735,5,95,1, -256,3736,16,0,621, -1,1261,3737,16,0, -621,1,509,3738,16, -0,621,1,1515,3739, -16,0,621,1,2021, -718,1,1775,3740,16, -0,621,1,2029,725, +1,2470,3602,16,0, +345,1,90,3603,19, +350,1,90,3604,5, +9,1,2519,1618,1, +2557,1627,1,2521,3605, +16,0,348,1,2559, +1633,1,2597,3606,16, +0,348,1,2561,3607, +16,0,348,1,2459, +882,1,2464,899,1, +2470,3608,16,0,348, +1,91,3609,19,344, +1,91,3610,5,9, +1,2519,1618,1,2557, +1627,1,2521,3611,16, +0,342,1,2559,1633, +1,2597,3612,16,0, +342,1,2561,3613,16, +0,342,1,2459,882, +1,2464,899,1,2470, +3614,16,0,342,1, +92,3615,19,133,1, +92,3616,5,125,1, +0,3617,16,0,563, +1,1,1951,1,2, +1957,1,3,1962,1, +4,1967,1,5,1972, +1,6,1977,1,7, +1982,1,8,3618,16, +0,131,1,1515,3619, +16,0,165,1,2021, +718,1,2022,3620,16, +0,497,1,256,3621, +16,0,173,1,2025, +3622,16,0,501,1, +18,3623,16,0,138, +1,2027,3624,16,0, +505,1,2695,3625,16, +0,563,1,2029,725, 1,2030,731,1,2031, 736,1,2032,741,1, -2033,746,1,277,3741, -16,0,621,1,2035, +2033,746,1,277,3626, +16,0,173,1,2035, 752,1,2037,757,1, -2039,762,1,32,3742, -16,0,621,1,2041, -768,1,2293,3743,16, -0,621,1,2043,774, -1,2045,779,1,41, -3744,16,0,621,1, -1297,3745,16,0,621, -1,43,3746,16,0, -621,1,1803,787,1, -1804,3747,16,0,621, -1,299,3748,16,0, -621,1,52,3749,16, -0,621,1,2318,3750, -16,0,621,1,62, -3751,16,0,621,1, -2075,3752,16,0,621, -1,1574,799,1,71, -3753,16,0,621,1, -76,3754,16,0,621, -1,1834,3755,16,0, -621,1,2337,3756,16, -0,621,1,79,3757, -16,0,621,1,1335, -3758,16,0,621,1, -322,3759,16,0,621, -1,85,3760,16,0, -621,1,89,3761,16, -0,621,1,346,3762, -16,0,621,1,2105, -814,1,2106,3763,16, -0,621,1,97,3764, -16,0,621,1,1860, -821,1,2364,827,1, -102,3765,16,0,621, -1,112,3766,16,0, -621,1,1117,3767,16, -0,621,1,1873,835, -1,1876,3768,16,0, -621,1,124,3769,16, -0,621,1,2136,842, -1,381,3770,16,0, -621,1,525,3771,16, -0,621,1,137,3772, -16,0,621,1,1901, -3773,16,0,621,1, -2658,3774,16,0,621, -1,1153,3775,16,0, -621,1,151,3776,16, -0,621,1,1407,3777, -16,0,621,1,1659, -3778,16,0,621,1, -2413,3779,16,0,621, -1,406,3780,16,0, -621,1,1371,3781,16, -0,621,1,166,3782, -16,0,621,1,1622, -3783,16,0,621,1, -1931,861,1,1933,3784, -16,0,621,1,431, -3785,16,0,621,1, -1585,3786,16,0,621, -1,182,3787,16,0, -621,1,1189,3788,16, -0,621,1,1443,3789, -16,0,621,1,1695, -3790,16,0,621,1, -2198,3791,16,0,621, -1,447,3792,16,0, -621,1,2458,876,1, -2459,882,1,1958,3793, -16,0,621,1,2462, -889,1,1657,894,1, -2464,899,1,199,3794, -16,0,621,1,459, -3795,16,0,621,1, -462,3796,16,0,621, -1,217,3797,16,0, -621,1,2227,908,1, -1225,3798,16,0,621, -1,1479,3799,16,0, -621,1,1731,3800,16, -0,621,1,1989,916, -1,1990,3801,16,0, -621,1,236,3802,16, -0,621,1,1756,3803, -16,0,621,1,95, -3804,19,620,1,95, -3805,5,95,1,256, -3806,16,0,618,1, -1261,3807,16,0,618, -1,509,3808,16,0, -618,1,1515,3809,16, -0,618,1,2021,718, -1,1775,3810,16,0, -618,1,2029,725,1, +2039,762,1,32,3627, +16,0,165,1,2041, +768,1,2293,3628,16, +0,173,1,2043,774, +1,2045,779,1,2713, +3206,1,2715,3195,1, +41,3629,16,0,173, +1,1297,3630,16,0, +165,1,43,3631,16, +0,173,1,46,3632, +16,0,178,1,1804, +3633,16,0,165,1, +299,3634,16,0,173, +1,52,3635,16,0, +165,1,509,3636,16, +0,173,1,2318,3637, +16,0,165,1,62, +3638,16,0,195,1, +65,3639,16,0,197, +1,2075,3640,16,0, +165,1,1574,799,1, +71,3641,16,0,173, +1,1775,3642,16,0, +165,1,76,3643,16, +0,173,1,1834,3644, +16,0,165,1,2337, +3645,16,0,165,1, +79,3646,16,0,173, +1,1335,3647,16,0, +165,1,322,3648,16, +0,173,1,85,3649, +16,0,173,1,1261, +3650,16,0,165,1, +89,3651,16,0,173, +1,346,3652,16,0, +173,1,97,3653,16, +0,173,1,2106,3654, +16,0,165,1,102, +3655,16,0,173,1, +1860,821,1,1803,787, +1,2364,827,1,1113, +3656,16,0,158,1, +112,3657,16,0,173, +1,1117,3658,16,0, +165,1,1873,835,1, +1876,3659,16,0,165, +1,372,3660,16,0, +535,1,374,3661,16, +0,537,1,124,3662, +16,0,173,1,376, +3663,16,0,539,1, +378,3664,16,0,541, +1,2136,842,1,381, +3665,16,0,173,1, +525,3666,16,0,173, +1,137,3667,16,0, +173,1,1901,3668,16, +0,165,1,2655,3211, +1,2658,3669,16,0, +173,1,1153,3670,16, +0,165,1,151,3671, +16,0,173,1,1407, +3672,16,0,165,1, +1659,3673,16,0,165, +1,2413,3674,16,0, +165,1,406,3675,16, +0,173,1,1371,3676, +16,0,165,1,2105, +814,1,1657,894,1, +166,3677,16,0,173, +1,1622,3678,16,0, +173,1,2683,3223,1, +1931,861,1,1933,3679, +16,0,165,1,431, +3680,16,0,173,1, +1585,3681,16,0,173, +1,182,3682,16,0, +173,1,2694,3216,1, +1189,3683,16,0,165, +1,1443,3684,16,0, +165,1,1695,3685,16, +0,165,1,2198,3686, +16,0,165,1,447, +3687,16,0,173,1, +2458,876,1,2459,882, +1,1958,3688,16,0, +165,1,2462,889,1, +2714,3183,1,2464,899, +1,2716,3189,1,2466, +3200,1,459,3689,16, +0,173,1,2468,3690, +16,0,340,1,462, +3691,16,0,173,1, +199,3692,16,0,173, +1,217,3693,16,0, +173,1,2227,908,1, +1225,3694,16,0,165, +1,1479,3695,16,0, +165,1,1731,3696,16, +0,173,1,1989,916, +1,1990,3697,16,0, +165,1,236,3698,16, +0,173,1,1756,3699, +16,0,165,1,93, +3700,19,626,1,93, +3701,5,95,1,256, +3702,16,0,624,1, +1261,3703,16,0,624, +1,509,3704,16,0, +624,1,1515,3705,16, +0,624,1,2021,718, +1,1775,3706,16,0, +624,1,2029,725,1, 2030,731,1,2031,736, 1,2032,741,1,2033, -746,1,277,3811,16, -0,618,1,2035,752, +746,1,277,3707,16, +0,624,1,2035,752, 1,2037,757,1,2039, -762,1,32,3812,16, -0,618,1,2041,768, -1,2293,3813,16,0, -618,1,2043,774,1, -2045,779,1,41,3814, -16,0,618,1,1297, -3815,16,0,618,1, -43,3816,16,0,618, +762,1,32,3708,16, +0,624,1,2041,768, +1,2293,3709,16,0, +624,1,2043,774,1, +2045,779,1,41,3710, +16,0,624,1,1297, +3711,16,0,624,1, +43,3712,16,0,624, 1,1803,787,1,1804, -3817,16,0,618,1, -299,3818,16,0,618, -1,52,3819,16,0, -618,1,2318,3820,16, -0,618,1,62,3821, -16,0,618,1,2075, -3822,16,0,618,1, -1574,799,1,71,3823, -16,0,618,1,76, -3824,16,0,618,1, -1834,3825,16,0,618, -1,2337,3826,16,0, -618,1,79,3827,16, -0,618,1,1335,3828, -16,0,618,1,322, -3829,16,0,618,1, -85,3830,16,0,618, -1,89,3831,16,0, -618,1,346,3832,16, -0,618,1,2105,814, -1,2106,3833,16,0, -618,1,97,3834,16, -0,618,1,1860,821, +3713,16,0,624,1, +299,3714,16,0,624, +1,52,3715,16,0, +624,1,2318,3716,16, +0,624,1,62,3717, +16,0,624,1,2075, +3718,16,0,624,1, +1574,799,1,71,3719, +16,0,624,1,76, +3720,16,0,624,1, +1834,3721,16,0,624, +1,2337,3722,16,0, +624,1,79,3723,16, +0,624,1,1335,3724, +16,0,624,1,322, +3725,16,0,624,1, +85,3726,16,0,624, +1,89,3727,16,0, +624,1,346,3728,16, +0,624,1,2105,814, +1,2106,3729,16,0, +624,1,97,3730,16, +0,624,1,1860,821, 1,2364,827,1,102, -3835,16,0,618,1, -112,3836,16,0,618, -1,1117,3837,16,0, -618,1,1873,835,1, -1876,3838,16,0,618, -1,124,3839,16,0, -618,1,2136,842,1, -381,3840,16,0,618, -1,525,3841,16,0, -618,1,137,3842,16, -0,618,1,1901,3843, -16,0,618,1,2658, -3844,16,0,618,1, -1153,3845,16,0,618, -1,151,3846,16,0, -618,1,1407,3847,16, -0,618,1,1659,3848, -16,0,618,1,2413, -3849,16,0,618,1, -406,3850,16,0,618, -1,1371,3851,16,0, -618,1,166,3852,16, -0,618,1,1622,3853, -16,0,618,1,1931, -861,1,1933,3854,16, -0,618,1,431,3855, -16,0,618,1,1585, -3856,16,0,618,1, -182,3857,16,0,618, -1,1189,3858,16,0, -618,1,1443,3859,16, -0,618,1,1695,3860, -16,0,618,1,2198, -3861,16,0,618,1, -447,3862,16,0,618, +3731,16,0,624,1, +112,3732,16,0,624, +1,1117,3733,16,0, +624,1,1873,835,1, +1876,3734,16,0,624, +1,124,3735,16,0, +624,1,2136,842,1, +381,3736,16,0,624, +1,525,3737,16,0, +624,1,137,3738,16, +0,624,1,1901,3739, +16,0,624,1,2658, +3740,16,0,624,1, +1153,3741,16,0,624, +1,151,3742,16,0, +624,1,1407,3743,16, +0,624,1,1659,3744, +16,0,624,1,2413, +3745,16,0,624,1, +406,3746,16,0,624, +1,1371,3747,16,0, +624,1,166,3748,16, +0,624,1,1622,3749, +16,0,624,1,1931, +861,1,1933,3750,16, +0,624,1,431,3751, +16,0,624,1,1585, +3752,16,0,624,1, +182,3753,16,0,624, +1,1189,3754,16,0, +624,1,1443,3755,16, +0,624,1,1695,3756, +16,0,624,1,2198, +3757,16,0,624,1, +447,3758,16,0,624, 1,2458,876,1,2459, -882,1,1958,3863,16, -0,618,1,2462,889, +882,1,1958,3759,16, +0,624,1,2462,889, 1,1657,894,1,2464, -899,1,199,3864,16, -0,618,1,459,3865, -16,0,618,1,462, -3866,16,0,618,1, -217,3867,16,0,618, +899,1,199,3760,16, +0,624,1,459,3761, +16,0,624,1,462, +3762,16,0,624,1, +217,3763,16,0,624, 1,2227,908,1,1225, -3868,16,0,618,1, -1479,3869,16,0,618, -1,1731,3870,16,0, -618,1,1989,916,1, -1990,3871,16,0,618, -1,236,3872,16,0, -618,1,1756,3873,16, -0,618,1,96,3874, -19,103,1,96,3875, -5,1,1,0,3876, -16,0,104,1,97, -3877,19,611,1,97, -3878,5,1,1,0, -3879,16,0,609,1, -98,3880,19,636,1, -98,3881,5,2,1, -0,3882,16,0,638, -1,2695,3883,16,0, -634,1,99,3884,19, -633,1,99,3885,5, -2,1,0,3886,16, -0,637,1,2695,3887, -16,0,631,1,100, -3888,19,296,1,100, -3889,5,2,1,0, -3890,16,0,557,1, -2695,3891,16,0,294, -1,101,3892,19,561, -1,101,3893,5,4, -1,0,3894,16,0, -641,1,2695,3895,16, -0,641,1,2706,3896, -16,0,559,1,2636, -3897,16,0,559,1, -102,3898,19,591,1, -102,3899,5,2,1, -2470,3900,16,0,664, -1,2561,3901,16,0, -589,1,103,3902,19, -463,1,103,3903,5, -4,1,2597,3904,16, -0,558,1,2521,3905, -16,0,558,1,2470, -3906,16,0,461,1, -2561,3907,16,0,461, -1,104,3908,19,141, -1,104,3909,5,3, -1,2642,3910,16,0, -569,1,2506,3911,16, -0,317,1,10,3912, -16,0,139,1,105, -3913,19,151,1,105, -3914,5,17,1,0, -3915,16,0,254,1, -2075,3916,16,0,648, -1,2337,3917,16,0, -648,1,2413,3918,16, -0,648,1,10,3919, -16,0,336,1,2198, -3920,16,0,648,1, -1901,3921,16,0,648, -1,2642,3922,16,0, -336,1,21,3923,16, -0,149,1,2106,3924, -16,0,648,1,2506, -3925,16,0,336,1, -1804,3926,16,0,648, -1,1990,3927,16,0, -648,1,2695,3928,16, -0,254,1,32,3929, -16,0,648,1,1958, -3930,16,0,648,1, -1775,3931,16,0,648, -1,106,3932,19,130, -1,106,3933,5,18, -1,0,3934,16,0, -128,1,2642,3935,16, -0,137,1,2075,3936, -16,0,137,1,2337, -3937,16,0,137,1, -2413,3938,16,0,137, -1,10,3939,16,0, -137,1,2198,3940,16, -0,137,1,1901,3941, -16,0,137,1,52, -3942,16,0,193,1, -21,3943,16,0,137, -1,2106,3944,16,0, -137,1,2506,3945,16, -0,137,1,1804,3946, -16,0,137,1,1990, -3947,16,0,137,1, -2695,3948,16,0,128, -1,32,3949,16,0, -137,1,1958,3950,16, -0,137,1,1775,3951, -16,0,137,1,107, -3952,19,658,1,107, -3953,5,4,1,2597, -3954,16,0,656,1, -2521,3955,16,0,656, -1,2470,3956,16,0, -656,1,2561,3957,16, -0,656,1,108,3958, -19,335,1,108,3959, -5,14,1,2517,3960, -16,0,437,1,2075, -3961,16,0,506,1, -2337,3962,16,0,506, -1,2413,3963,16,0, -506,1,1901,3964,16, -0,506,1,2198,3965, -16,0,506,1,2106, -3966,16,0,506,1, -2653,3967,16,0,571, -1,1804,3968,16,0, -506,1,1990,3969,16, -0,506,1,31,3970, -16,0,333,1,32, -3971,16,0,506,1, -1958,3972,16,0,506, -1,1775,3973,16,0, -506,1,109,3974,19, -302,1,109,3975,5, -1,1,32,3976,16, -0,300,1,110,3977, -19,261,1,110,3978, -5,11,1,2075,3979, -16,0,577,1,2337, -3980,16,0,265,1, -2413,3981,16,0,445, -1,1901,3982,16,0, -391,1,2198,3983,16, -0,319,1,2106,3984, -16,0,607,1,1804, -3985,16,0,284,1, -1990,3986,16,0,494, -1,32,3987,16,0, -329,1,1958,3988,16, -0,450,1,1775,3989, -16,0,259,1,111, -3990,19,583,1,111, -3991,5,11,1,2075, -3992,16,0,581,1, -2337,3993,16,0,581, -1,2413,3994,16,0, -581,1,1901,3995,16, -0,581,1,2198,3996, -16,0,581,1,2106, -3997,16,0,581,1, -1804,3998,16,0,581, -1,1990,3999,16,0, -581,1,32,4000,16, -0,581,1,1958,4001, -16,0,581,1,1775, -4002,16,0,581,1, -112,4003,19,645,1, -112,4004,5,11,1, -2075,4005,16,0,643, -1,2337,4006,16,0, -643,1,2413,4007,16, -0,643,1,1901,4008, -16,0,643,1,2198, -4009,16,0,643,1, -2106,4010,16,0,643, -1,1804,4011,16,0, -643,1,1990,4012,16, -0,643,1,32,4013, -16,0,643,1,1958, -4014,16,0,643,1, -1775,4015,16,0,643, -1,113,4016,19,161, -1,113,4017,5,31, -1,1901,4018,16,0, -647,1,1479,4019,16, -0,551,1,2075,4020, -16,0,647,1,1695, -4021,16,0,189,1, -1756,4022,16,0,188, -1,2413,4023,16,0, -647,1,2198,4024,16, -0,647,1,1876,4025, -16,0,661,1,1659, -4026,16,0,188,1, -1443,4027,16,0,522, -1,1117,4028,16,0, -159,1,1990,4029,16, -0,647,1,1189,4030, -16,0,240,1,1775, -4031,16,0,647,1, -32,4032,16,0,647, -1,2106,4033,16,0, -647,1,1515,4034,16, -0,579,1,2337,4035, -16,0,647,1,52, -4036,16,0,592,1, -1804,4037,16,0,647, -1,1261,4038,16,0, -298,1,1153,4039,16, -0,247,1,1225,4040, -16,0,274,1,1335, -4041,16,0,443,1, -1933,4042,16,0,553, -1,1834,4043,16,0, -312,1,1297,4044,16, -0,323,1,1407,4045, -16,0,568,1,2318, -4046,16,0,188,1, -1958,4047,16,0,647, -1,1371,4048,16,0, -438,1,114,4049,19, -531,1,114,4050,5, -11,1,2075,4051,16, -0,529,1,2337,4052, -16,0,529,1,2413, -4053,16,0,529,1, -1901,4054,16,0,529, -1,2198,4055,16,0, -529,1,2106,4056,16, -0,529,1,1804,4057, -16,0,529,1,1990, -4058,16,0,529,1, -32,4059,16,0,529, -1,1958,4060,16,0, -529,1,1775,4061,16, -0,529,1,115,4062, -19,527,1,115,4063, -5,11,1,2075,4064, -16,0,525,1,2337, -4065,16,0,525,1, -2413,4066,16,0,525, -1,1901,4067,16,0, -525,1,2198,4068,16, -0,525,1,2106,4069, -16,0,525,1,1804, -4070,16,0,525,1, -1990,4071,16,0,525, -1,32,4072,16,0, -525,1,1958,4073,16, -0,525,1,1775,4074, -16,0,525,1,116, -4075,19,575,1,116, -4076,5,11,1,2075, -4077,16,0,573,1, -2337,4078,16,0,573, -1,2413,4079,16,0, -573,1,1901,4080,16, -0,573,1,2198,4081, -16,0,573,1,2106, -4082,16,0,573,1, -1804,4083,16,0,573, -1,1990,4084,16,0, -573,1,32,4085,16, -0,573,1,1958,4086, -16,0,573,1,1775, -4087,16,0,573,1, -117,4088,19,521,1, -117,4089,5,11,1, -2075,4090,16,0,519, -1,2337,4091,16,0, -519,1,2413,4092,16, -0,519,1,1901,4093, -16,0,519,1,2198, -4094,16,0,519,1, -2106,4095,16,0,519, -1,1804,4096,16,0, -519,1,1990,4097,16, -0,519,1,32,4098, -16,0,519,1,1958, -4099,16,0,519,1, -1775,4100,16,0,519, -1,118,4101,19,518, -1,118,4102,5,11, -1,2075,4103,16,0, -516,1,2337,4104,16, -0,516,1,2413,4105, -16,0,516,1,1901, -4106,16,0,516,1, -2198,4107,16,0,516, -1,2106,4108,16,0, -516,1,1804,4109,16, -0,516,1,1990,4110, -16,0,516,1,32, -4111,16,0,516,1, -1958,4112,16,0,516, -1,1775,4113,16,0, -516,1,119,4114,19, -515,1,119,4115,5, -11,1,2075,4116,16, -0,513,1,2337,4117, -16,0,513,1,2413, -4118,16,0,513,1, -1901,4119,16,0,513, -1,2198,4120,16,0, -513,1,2106,4121,16, -0,513,1,1804,4122, -16,0,513,1,1990, -4123,16,0,513,1, -32,4124,16,0,513, -1,1958,4125,16,0, -513,1,1775,4126,16, -0,513,1,120,4127, -19,512,1,120,4128, -5,11,1,2075,4129, -16,0,510,1,2337, -4130,16,0,510,1, -2413,4131,16,0,510, -1,1901,4132,16,0, -510,1,2198,4133,16, -0,510,1,2106,4134, -16,0,510,1,1804, -4135,16,0,510,1, -1990,4136,16,0,510, -1,32,4137,16,0, -510,1,1958,4138,16, -0,510,1,1775,4139, -16,0,510,1,121, -4140,19,509,1,121, -4141,5,11,1,2075, -4142,16,0,507,1, -2337,4143,16,0,507, -1,2413,4144,16,0, -507,1,1901,4145,16, -0,507,1,2198,4146, -16,0,507,1,2106, -4147,16,0,507,1, -1804,4148,16,0,507, -1,1990,4149,16,0, -507,1,32,4150,16, -0,507,1,1958,4151, -16,0,507,1,1775, -4152,16,0,507,1, -122,4153,19,147,1, -122,4154,5,3,1, -1756,4155,16,0,283, -1,2318,4156,16,0, -297,1,1659,4157,16, -0,145,1,123,4158, -19,548,1,123,4159, -5,68,1,1901,4160, -16,0,546,1,1479, -4161,16,0,546,1, -112,4162,16,0,546, -1,2293,4163,16,0, -546,1,1804,4164,16, -0,546,1,431,4165, -16,0,546,1,1443, -4166,16,0,546,1, -1756,4167,16,0,546, -1,124,4168,16,0, -546,1,525,4169,16, -0,546,1,236,4170, -16,0,546,1,346, -4171,16,0,546,1, -1876,4172,16,0,546, -1,1659,4173,16,0, -546,1,1225,4174,16, -0,546,1,1117,4175, -16,0,546,1,137, -4176,16,0,546,1, -2318,4177,16,0,546, -1,1775,4178,16,0, -546,1,32,4179,16, -0,546,1,1407,4180, -16,0,546,1,256, -4181,16,0,546,1, -459,4182,16,0,546, -1,406,4183,16,0, -546,1,41,4184,16, -0,546,1,2658,4185, -16,0,546,1,43, -4186,16,0,546,1, -1585,4187,16,0,546, -1,1990,4188,16,0, -546,1,2337,4189,16, -0,546,1,509,4190, -16,0,546,1,52, -4191,16,0,546,1, -151,4192,16,0,546, -1,447,4193,16,0, -546,1,166,4194,16, -0,546,1,462,4195, -16,0,546,1,277, -4196,16,0,546,1, -1695,4197,16,0,546, -1,62,4198,16,0, -586,1,1153,4199,16, -0,546,1,381,4200, -16,0,546,1,2106, -4201,16,0,546,1, -1335,4202,16,0,546, -1,71,4203,16,0, -546,1,182,4204,16, -0,546,1,76,4205, -16,0,546,1,79, -4206,16,0,546,1, -1933,4207,16,0,546, -1,299,4208,16,0, -546,1,85,4209,16, -0,546,1,1515,4210, -16,0,546,1,2198, -4211,16,0,546,1, -89,4212,16,0,546, -1,1834,4213,16,0, -546,1,1622,4214,16, -0,546,1,2413,4215, -16,0,546,1,2075, -4216,16,0,546,1, -1731,4217,16,0,546, -1,97,4218,16,0, -546,1,1297,4219,16, -0,546,1,1189,4220, -16,0,546,1,102, -4221,16,0,546,1, -1261,4222,16,0,546, -1,322,4223,16,0, -546,1,1958,4224,16, -0,546,1,199,4225, -16,0,546,1,1371, -4226,16,0,546,1, -217,4227,16,0,546, -1,124,4228,19,602, -1,124,4229,5,2, -1,459,4230,16,0, -600,1,41,4231,16, -0,665,1,125,4232, -19,606,1,125,4233, -5,3,1,462,4234, -16,0,604,1,459, -4235,16,0,630,1, -41,4236,16,0,630, -1,126,4237,19,4238, -4,36,69,0,120, -0,112,0,114,0, -101,0,115,0,115, -0,105,0,111,0, -110,0,65,0,114, -0,103,0,117,0, -109,0,101,0,110, -0,116,0,1,126, -4233,1,127,4239,19, -544,1,127,4240,5, -68,1,1901,4241,16, -0,542,1,1479,4242, -16,0,542,1,112, -4243,16,0,542,1, -2293,4244,16,0,542, -1,1804,4245,16,0, -542,1,431,4246,16, -0,542,1,1443,4247, -16,0,542,1,1756, -4248,16,0,542,1, -124,4249,16,0,542, -1,525,4250,16,0, -542,1,236,4251,16, -0,542,1,346,4252, -16,0,542,1,1876, -4253,16,0,542,1, -1659,4254,16,0,542, -1,1225,4255,16,0, -542,1,1117,4256,16, -0,542,1,137,4257, -16,0,542,1,2318, -4258,16,0,542,1, -1775,4259,16,0,542, -1,32,4260,16,0, -542,1,1407,4261,16, -0,542,1,256,4262, -16,0,542,1,459, -4263,16,0,542,1, -406,4264,16,0,542, -1,41,4265,16,0, -542,1,2658,4266,16, -0,542,1,43,4267, -16,0,542,1,1585, -4268,16,0,542,1, -1990,4269,16,0,542, -1,2337,4270,16,0, -542,1,509,4271,16, -0,542,1,52,4272, -16,0,542,1,151, -4273,16,0,542,1, -447,4274,16,0,542, -1,166,4275,16,0, -542,1,462,4276,16, -0,542,1,277,4277, -16,0,542,1,1695, -4278,16,0,542,1, -62,4279,16,0,587, -1,1153,4280,16,0, -542,1,381,4281,16, -0,542,1,2106,4282, -16,0,542,1,1335, -4283,16,0,542,1, -71,4284,16,0,542, -1,182,4285,16,0, -542,1,76,4286,16, -0,542,1,79,4287, -16,0,542,1,1933, -4288,16,0,542,1, -299,4289,16,0,542, -1,85,4290,16,0, -542,1,1515,4291,16, -0,542,1,2198,4292, -16,0,542,1,89, -4293,16,0,542,1, -1834,4294,16,0,542, -1,1622,4295,16,0, -542,1,2413,4296,16, -0,542,1,2075,4297, -16,0,542,1,1731, -4298,16,0,542,1, -97,4299,16,0,542, -1,1297,4300,16,0, -542,1,1189,4301,16, -0,542,1,102,4302, -16,0,542,1,1261, -4303,16,0,542,1, -322,4304,16,0,542, -1,1958,4305,16,0, -542,1,199,4306,16, -0,542,1,1371,4307, -16,0,542,1,217, -4308,16,0,542,1, -128,4309,19,4310,4, -28,86,0,101,0, -99,0,116,0,111, -0,114,0,67,0, +3764,16,0,624,1, +1479,3765,16,0,624, +1,1731,3766,16,0, +624,1,1989,916,1, +1990,3767,16,0,624, +1,236,3768,16,0, +624,1,1756,3769,16, +0,624,1,94,3770, +19,623,1,94,3771, +5,95,1,256,3772, +16,0,621,1,1261, +3773,16,0,621,1, +509,3774,16,0,621, +1,1515,3775,16,0, +621,1,2021,718,1, +1775,3776,16,0,621, +1,2029,725,1,2030, +731,1,2031,736,1, +2032,741,1,2033,746, +1,277,3777,16,0, +621,1,2035,752,1, +2037,757,1,2039,762, +1,32,3778,16,0, +621,1,2041,768,1, +2293,3779,16,0,621, +1,2043,774,1,2045, +779,1,41,3780,16, +0,621,1,1297,3781, +16,0,621,1,43, +3782,16,0,621,1, +1803,787,1,1804,3783, +16,0,621,1,299, +3784,16,0,621,1, +52,3785,16,0,621, +1,2318,3786,16,0, +621,1,62,3787,16, +0,621,1,2075,3788, +16,0,621,1,1574, +799,1,71,3789,16, +0,621,1,76,3790, +16,0,621,1,1834, +3791,16,0,621,1, +2337,3792,16,0,621, +1,79,3793,16,0, +621,1,1335,3794,16, +0,621,1,322,3795, +16,0,621,1,85, +3796,16,0,621,1, +89,3797,16,0,621, +1,346,3798,16,0, +621,1,2105,814,1, +2106,3799,16,0,621, +1,97,3800,16,0, +621,1,1860,821,1, +2364,827,1,102,3801, +16,0,621,1,112, +3802,16,0,621,1, +1117,3803,16,0,621, +1,1873,835,1,1876, +3804,16,0,621,1, +124,3805,16,0,621, +1,2136,842,1,381, +3806,16,0,621,1, +525,3807,16,0,621, +1,137,3808,16,0, +621,1,1901,3809,16, +0,621,1,2658,3810, +16,0,621,1,1153, +3811,16,0,621,1, +151,3812,16,0,621, +1,1407,3813,16,0, +621,1,1659,3814,16, +0,621,1,2413,3815, +16,0,621,1,406, +3816,16,0,621,1, +1371,3817,16,0,621, +1,166,3818,16,0, +621,1,1622,3819,16, +0,621,1,1931,861, +1,1933,3820,16,0, +621,1,431,3821,16, +0,621,1,1585,3822, +16,0,621,1,182, +3823,16,0,621,1, +1189,3824,16,0,621, +1,1443,3825,16,0, +621,1,1695,3826,16, +0,621,1,2198,3827, +16,0,621,1,447, +3828,16,0,621,1, +2458,876,1,2459,882, +1,1958,3829,16,0, +621,1,2462,889,1, +1657,894,1,2464,899, +1,199,3830,16,0, +621,1,459,3831,16, +0,621,1,462,3832, +16,0,621,1,217, +3833,16,0,621,1, +2227,908,1,1225,3834, +16,0,621,1,1479, +3835,16,0,621,1, +1731,3836,16,0,621, +1,1989,916,1,1990, +3837,16,0,621,1, +236,3838,16,0,621, +1,1756,3839,16,0, +621,1,95,3840,19, +620,1,95,3841,5, +95,1,256,3842,16, +0,618,1,1261,3843, +16,0,618,1,509, +3844,16,0,618,1, +1515,3845,16,0,618, +1,2021,718,1,1775, +3846,16,0,618,1, +2029,725,1,2030,731, +1,2031,736,1,2032, +741,1,2033,746,1, +277,3847,16,0,618, +1,2035,752,1,2037, +757,1,2039,762,1, +32,3848,16,0,618, +1,2041,768,1,2293, +3849,16,0,618,1, +2043,774,1,2045,779, +1,41,3850,16,0, +618,1,1297,3851,16, +0,618,1,43,3852, +16,0,618,1,1803, +787,1,1804,3853,16, +0,618,1,299,3854, +16,0,618,1,52, +3855,16,0,618,1, +2318,3856,16,0,618, +1,62,3857,16,0, +618,1,2075,3858,16, +0,618,1,1574,799, +1,71,3859,16,0, +618,1,76,3860,16, +0,618,1,1834,3861, +16,0,618,1,2337, +3862,16,0,618,1, +79,3863,16,0,618, +1,1335,3864,16,0, +618,1,322,3865,16, +0,618,1,85,3866, +16,0,618,1,89, +3867,16,0,618,1, +346,3868,16,0,618, +1,2105,814,1,2106, +3869,16,0,618,1, +97,3870,16,0,618, +1,1860,821,1,2364, +827,1,102,3871,16, +0,618,1,112,3872, +16,0,618,1,1117, +3873,16,0,618,1, +1873,835,1,1876,3874, +16,0,618,1,124, +3875,16,0,618,1, +2136,842,1,381,3876, +16,0,618,1,525, +3877,16,0,618,1, +137,3878,16,0,618, +1,1901,3879,16,0, +618,1,2658,3880,16, +0,618,1,1153,3881, +16,0,618,1,151, +3882,16,0,618,1, +1407,3883,16,0,618, +1,1659,3884,16,0, +618,1,2413,3885,16, +0,618,1,406,3886, +16,0,618,1,1371, +3887,16,0,618,1, +166,3888,16,0,618, +1,1622,3889,16,0, +618,1,1931,861,1, +1933,3890,16,0,618, +1,431,3891,16,0, +618,1,1585,3892,16, +0,618,1,182,3893, +16,0,618,1,1189, +3894,16,0,618,1, +1443,3895,16,0,618, +1,1695,3896,16,0, +618,1,2198,3897,16, +0,618,1,447,3898, +16,0,618,1,2458, +876,1,2459,882,1, +1958,3899,16,0,618, +1,2462,889,1,1657, +894,1,2464,899,1, +199,3900,16,0,618, +1,459,3901,16,0, +618,1,462,3902,16, +0,618,1,217,3903, +16,0,618,1,2227, +908,1,1225,3904,16, +0,618,1,1479,3905, +16,0,618,1,1731, +3906,16,0,618,1, +1989,916,1,1990,3907, +16,0,618,1,236, +3908,16,0,618,1, +1756,3909,16,0,618, +1,96,3910,19,103, +1,96,3911,5,1, +1,0,3912,16,0, +104,1,97,3913,19, +611,1,97,3914,5, +1,1,0,3915,16, +0,609,1,98,3916, +19,636,1,98,3917, +5,2,1,0,3918, +16,0,638,1,2695, +3919,16,0,634,1, +99,3920,19,633,1, +99,3921,5,2,1, +0,3922,16,0,637, +1,2695,3923,16,0, +631,1,100,3924,19, +296,1,100,3925,5, +2,1,0,3926,16, +0,557,1,2695,3927, +16,0,294,1,101, +3928,19,561,1,101, +3929,5,4,1,0, +3930,16,0,641,1, +2695,3931,16,0,641, +1,2706,3932,16,0, +559,1,2636,3933,16, +0,559,1,102,3934, +19,591,1,102,3935, +5,2,1,2470,3936, +16,0,664,1,2561, +3937,16,0,589,1, +103,3938,19,463,1, +103,3939,5,4,1, +2597,3940,16,0,558, +1,2521,3941,16,0, +558,1,2470,3942,16, +0,461,1,2561,3943, +16,0,461,1,104, +3944,19,141,1,104, +3945,5,3,1,2642, +3946,16,0,569,1, +2506,3947,16,0,317, +1,10,3948,16,0, +139,1,105,3949,19, +151,1,105,3950,5, +17,1,0,3951,16, +0,254,1,2075,3952, +16,0,648,1,2337, +3953,16,0,648,1, +2413,3954,16,0,648, +1,10,3955,16,0, +336,1,2198,3956,16, +0,648,1,1901,3957, +16,0,648,1,2642, +3958,16,0,336,1, +21,3959,16,0,149, +1,2106,3960,16,0, +648,1,2506,3961,16, +0,336,1,1804,3962, +16,0,648,1,1990, +3963,16,0,648,1, +2695,3964,16,0,254, +1,32,3965,16,0, +648,1,1958,3966,16, +0,648,1,1775,3967, +16,0,648,1,106, +3968,19,130,1,106, +3969,5,18,1,0, +3970,16,0,128,1, +2642,3971,16,0,137, +1,2075,3972,16,0, +137,1,2337,3973,16, +0,137,1,2413,3974, +16,0,137,1,10, +3975,16,0,137,1, +2198,3976,16,0,137, +1,1901,3977,16,0, +137,1,52,3978,16, +0,193,1,21,3979, +16,0,137,1,2106, +3980,16,0,137,1, +2506,3981,16,0,137, +1,1804,3982,16,0, +137,1,1990,3983,16, +0,137,1,2695,3984, +16,0,128,1,32, +3985,16,0,137,1, +1958,3986,16,0,137, +1,1775,3987,16,0, +137,1,107,3988,19, +658,1,107,3989,5, +4,1,2597,3990,16, +0,656,1,2521,3991, +16,0,656,1,2470, +3992,16,0,656,1, +2561,3993,16,0,656, +1,108,3994,19,335, +1,108,3995,5,14, +1,2517,3996,16,0, +437,1,2075,3997,16, +0,506,1,2337,3998, +16,0,506,1,2413, +3999,16,0,506,1, +1901,4000,16,0,506, +1,2198,4001,16,0, +506,1,2106,4002,16, +0,506,1,2653,4003, +16,0,571,1,1804, +4004,16,0,506,1, +1990,4005,16,0,506, +1,31,4006,16,0, +333,1,32,4007,16, +0,506,1,1958,4008, +16,0,506,1,1775, +4009,16,0,506,1, +109,4010,19,302,1, +109,4011,5,1,1, +32,4012,16,0,300, +1,110,4013,19,261, +1,110,4014,5,11, +1,2075,4015,16,0, +577,1,2337,4016,16, +0,265,1,2413,4017, +16,0,445,1,1901, +4018,16,0,391,1, +2198,4019,16,0,319, +1,2106,4020,16,0, +607,1,1804,4021,16, +0,284,1,1990,4022, +16,0,494,1,32, +4023,16,0,329,1, +1958,4024,16,0,450, +1,1775,4025,16,0, +259,1,111,4026,19, +583,1,111,4027,5, +11,1,2075,4028,16, +0,581,1,2337,4029, +16,0,581,1,2413, +4030,16,0,581,1, +1901,4031,16,0,581, +1,2198,4032,16,0, +581,1,2106,4033,16, +0,581,1,1804,4034, +16,0,581,1,1990, +4035,16,0,581,1, +32,4036,16,0,581, +1,1958,4037,16,0, +581,1,1775,4038,16, +0,581,1,112,4039, +19,645,1,112,4040, +5,11,1,2075,4041, +16,0,643,1,2337, +4042,16,0,643,1, +2413,4043,16,0,643, +1,1901,4044,16,0, +643,1,2198,4045,16, +0,643,1,2106,4046, +16,0,643,1,1804, +4047,16,0,643,1, +1990,4048,16,0,643, +1,32,4049,16,0, +643,1,1958,4050,16, +0,643,1,1775,4051, +16,0,643,1,113, +4052,19,161,1,113, +4053,5,31,1,1901, +4054,16,0,647,1, +1479,4055,16,0,551, +1,2075,4056,16,0, +647,1,1695,4057,16, +0,189,1,1756,4058, +16,0,188,1,2413, +4059,16,0,647,1, +2198,4060,16,0,647, +1,1876,4061,16,0, +661,1,1659,4062,16, +0,188,1,1443,4063, +16,0,522,1,1117, +4064,16,0,159,1, +1990,4065,16,0,647, +1,1189,4066,16,0, +240,1,1775,4067,16, +0,647,1,32,4068, +16,0,647,1,2106, +4069,16,0,647,1, +1515,4070,16,0,579, +1,2337,4071,16,0, +647,1,52,4072,16, +0,592,1,1804,4073, +16,0,647,1,1261, +4074,16,0,298,1, +1153,4075,16,0,247, +1,1225,4076,16,0, +274,1,1335,4077,16, +0,443,1,1933,4078, +16,0,553,1,1834, +4079,16,0,312,1, +1297,4080,16,0,323, +1,1407,4081,16,0, +568,1,2318,4082,16, +0,188,1,1958,4083, +16,0,647,1,1371, +4084,16,0,438,1, +114,4085,19,531,1, +114,4086,5,11,1, +2075,4087,16,0,529, +1,2337,4088,16,0, +529,1,2413,4089,16, +0,529,1,1901,4090, +16,0,529,1,2198, +4091,16,0,529,1, +2106,4092,16,0,529, +1,1804,4093,16,0, +529,1,1990,4094,16, +0,529,1,32,4095, +16,0,529,1,1958, +4096,16,0,529,1, +1775,4097,16,0,529, +1,115,4098,19,527, +1,115,4099,5,11, +1,2075,4100,16,0, +525,1,2337,4101,16, +0,525,1,2413,4102, +16,0,525,1,1901, +4103,16,0,525,1, +2198,4104,16,0,525, +1,2106,4105,16,0, +525,1,1804,4106,16, +0,525,1,1990,4107, +16,0,525,1,32, +4108,16,0,525,1, +1958,4109,16,0,525, +1,1775,4110,16,0, +525,1,116,4111,19, +575,1,116,4112,5, +11,1,2075,4113,16, +0,573,1,2337,4114, +16,0,573,1,2413, +4115,16,0,573,1, +1901,4116,16,0,573, +1,2198,4117,16,0, +573,1,2106,4118,16, +0,573,1,1804,4119, +16,0,573,1,1990, +4120,16,0,573,1, +32,4121,16,0,573, +1,1958,4122,16,0, +573,1,1775,4123,16, +0,573,1,117,4124, +19,521,1,117,4125, +5,11,1,2075,4126, +16,0,519,1,2337, +4127,16,0,519,1, +2413,4128,16,0,519, +1,1901,4129,16,0, +519,1,2198,4130,16, +0,519,1,2106,4131, +16,0,519,1,1804, +4132,16,0,519,1, +1990,4133,16,0,519, +1,32,4134,16,0, +519,1,1958,4135,16, +0,519,1,1775,4136, +16,0,519,1,118, +4137,19,518,1,118, +4138,5,11,1,2075, +4139,16,0,516,1, +2337,4140,16,0,516, +1,2413,4141,16,0, +516,1,1901,4142,16, +0,516,1,2198,4143, +16,0,516,1,2106, +4144,16,0,516,1, +1804,4145,16,0,516, +1,1990,4146,16,0, +516,1,32,4147,16, +0,516,1,1958,4148, +16,0,516,1,1775, +4149,16,0,516,1, +119,4150,19,515,1, +119,4151,5,11,1, +2075,4152,16,0,513, +1,2337,4153,16,0, +513,1,2413,4154,16, +0,513,1,1901,4155, +16,0,513,1,2198, +4156,16,0,513,1, +2106,4157,16,0,513, +1,1804,4158,16,0, +513,1,1990,4159,16, +0,513,1,32,4160, +16,0,513,1,1958, +4161,16,0,513,1, +1775,4162,16,0,513, +1,120,4163,19,512, +1,120,4164,5,11, +1,2075,4165,16,0, +510,1,2337,4166,16, +0,510,1,2413,4167, +16,0,510,1,1901, +4168,16,0,510,1, +2198,4169,16,0,510, +1,2106,4170,16,0, +510,1,1804,4171,16, +0,510,1,1990,4172, +16,0,510,1,32, +4173,16,0,510,1, +1958,4174,16,0,510, +1,1775,4175,16,0, +510,1,121,4176,19, +509,1,121,4177,5, +11,1,2075,4178,16, +0,507,1,2337,4179, +16,0,507,1,2413, +4180,16,0,507,1, +1901,4181,16,0,507, +1,2198,4182,16,0, +507,1,2106,4183,16, +0,507,1,1804,4184, +16,0,507,1,1990, +4185,16,0,507,1, +32,4186,16,0,507, +1,1958,4187,16,0, +507,1,1775,4188,16, +0,507,1,122,4189, +19,147,1,122,4190, +5,3,1,1756,4191, +16,0,283,1,2318, +4192,16,0,297,1, +1659,4193,16,0,145, +1,123,4194,19,548, +1,123,4195,5,68, +1,1901,4196,16,0, +546,1,1479,4197,16, +0,546,1,112,4198, +16,0,546,1,2293, +4199,16,0,546,1, +1804,4200,16,0,546, +1,431,4201,16,0, +546,1,1443,4202,16, +0,546,1,1756,4203, +16,0,546,1,124, +4204,16,0,546,1, +525,4205,16,0,546, +1,236,4206,16,0, +546,1,346,4207,16, +0,546,1,1876,4208, +16,0,546,1,1659, +4209,16,0,546,1, +1225,4210,16,0,546, +1,1117,4211,16,0, +546,1,137,4212,16, +0,546,1,2318,4213, +16,0,546,1,1775, +4214,16,0,546,1, +32,4215,16,0,546, +1,1407,4216,16,0, +546,1,256,4217,16, +0,546,1,459,4218, +16,0,546,1,406, +4219,16,0,546,1, +41,4220,16,0,546, +1,2658,4221,16,0, +546,1,43,4222,16, +0,546,1,1585,4223, +16,0,546,1,1990, +4224,16,0,546,1, +2337,4225,16,0,546, +1,509,4226,16,0, +546,1,52,4227,16, +0,546,1,151,4228, +16,0,546,1,447, +4229,16,0,546,1, +166,4230,16,0,546, +1,462,4231,16,0, +546,1,277,4232,16, +0,546,1,1695,4233, +16,0,546,1,62, +4234,16,0,586,1, +1153,4235,16,0,546, +1,381,4236,16,0, +546,1,2106,4237,16, +0,546,1,1335,4238, +16,0,546,1,71, +4239,16,0,546,1, +182,4240,16,0,546, +1,76,4241,16,0, +546,1,79,4242,16, +0,546,1,1933,4243, +16,0,546,1,299, +4244,16,0,546,1, +85,4245,16,0,546, +1,1515,4246,16,0, +546,1,2198,4247,16, +0,546,1,89,4248, +16,0,546,1,1834, +4249,16,0,546,1, +1622,4250,16,0,546, +1,2413,4251,16,0, +546,1,2075,4252,16, +0,546,1,1731,4253, +16,0,546,1,97, +4254,16,0,546,1, +1297,4255,16,0,546, +1,1189,4256,16,0, +546,1,102,4257,16, +0,546,1,1261,4258, +16,0,546,1,322, +4259,16,0,546,1, +1958,4260,16,0,546, +1,199,4261,16,0, +546,1,1371,4262,16, +0,546,1,217,4263, +16,0,546,1,124, +4264,19,602,1,124, +4265,5,2,1,459, +4266,16,0,600,1, +41,4267,16,0,665, +1,125,4268,19,606, +1,125,4269,5,3, +1,462,4270,16,0, +604,1,459,4271,16, +0,630,1,41,4272, +16,0,630,1,126, +4273,19,4274,4,36, +69,0,120,0,112, +0,114,0,101,0, +115,0,115,0,105, +0,111,0,110,0, +65,0,114,0,103, +0,117,0,109,0, +101,0,110,0,116, +0,1,126,4269,1, +127,4275,19,544,1, +127,4276,5,68,1, +1901,4277,16,0,542, +1,1479,4278,16,0, +542,1,112,4279,16, +0,542,1,2293,4280, +16,0,542,1,1804, +4281,16,0,542,1, +431,4282,16,0,542, +1,1443,4283,16,0, +542,1,1756,4284,16, +0,542,1,124,4285, +16,0,542,1,525, +4286,16,0,542,1, +236,4287,16,0,542, +1,346,4288,16,0, +542,1,1876,4289,16, +0,542,1,1659,4290, +16,0,542,1,1225, +4291,16,0,542,1, +1117,4292,16,0,542, +1,137,4293,16,0, +542,1,2318,4294,16, +0,542,1,1775,4295, +16,0,542,1,32, +4296,16,0,542,1, +1407,4297,16,0,542, +1,256,4298,16,0, +542,1,459,4299,16, +0,542,1,406,4300, +16,0,542,1,41, +4301,16,0,542,1, +2658,4302,16,0,542, +1,43,4303,16,0, +542,1,1585,4304,16, +0,542,1,1990,4305, +16,0,542,1,2337, +4306,16,0,542,1, +509,4307,16,0,542, +1,52,4308,16,0, +542,1,151,4309,16, +0,542,1,447,4310, +16,0,542,1,166, +4311,16,0,542,1, +462,4312,16,0,542, +1,277,4313,16,0, +542,1,1695,4314,16, +0,542,1,62,4315, +16,0,587,1,1153, +4316,16,0,542,1, +381,4317,16,0,542, +1,2106,4318,16,0, +542,1,1335,4319,16, +0,542,1,71,4320, +16,0,542,1,182, +4321,16,0,542,1, +76,4322,16,0,542, +1,79,4323,16,0, +542,1,1933,4324,16, +0,542,1,299,4325, +16,0,542,1,85, +4326,16,0,542,1, +1515,4327,16,0,542, +1,2198,4328,16,0, +542,1,89,4329,16, +0,542,1,1834,4330, +16,0,542,1,1622, +4331,16,0,542,1, +2413,4332,16,0,542, +1,2075,4333,16,0, +542,1,1731,4334,16, +0,542,1,97,4335, +16,0,542,1,1297, +4336,16,0,542,1, +1189,4337,16,0,542, +1,102,4338,16,0, +542,1,1261,4339,16, +0,542,1,322,4340, +16,0,542,1,1958, +4341,16,0,542,1, +199,4342,16,0,542, +1,1371,4343,16,0, +542,1,217,4344,16, +0,542,1,128,4345, +19,4346,4,28,86, +0,101,0,99,0, +116,0,111,0,114, +0,67,0,111,0, +110,0,115,0,116, +0,97,0,110,0, +116,0,1,128,4276, +1,129,4347,19,4348, +4,32,82,0,111, +0,116,0,97,0, +116,0,105,0,111, +0,110,0,67,0, 111,0,110,0,115, 0,116,0,97,0, 110,0,116,0,1, -128,4240,1,129,4311, -19,4312,4,32,82, -0,111,0,116,0, -97,0,116,0,105, -0,111,0,110,0, +129,4276,1,130,4349, +19,4350,4,24,76, +0,105,0,115,0, +116,0,67,0,111, +0,110,0,115,0, +116,0,97,0,110, +0,116,0,1,130, +4276,1,131,4351,19, +169,1,131,4352,5, +67,1,1901,4353,16, +0,585,1,1479,4354, +16,0,533,1,112, +4355,16,0,249,1, +2293,4356,16,0,273, +1,1804,4357,16,0, +585,1,431,4358,16, +0,580,1,1443,4359, +16,0,468,1,1756, +4360,16,0,673,1, +124,4361,16,0,258, +1,525,4362,16,0, +305,1,236,4363,16, +0,341,1,346,4364, +16,0,496,1,1876, +4365,16,0,318,1, +1659,4366,16,0,673, +1,1225,4367,16,0, +248,1,1117,4368,16, +0,219,1,137,4369, +16,0,272,1,2318, +4370,16,0,673,1, +1775,4371,16,0,585, +1,32,4372,16,0, +585,1,1407,4373,16, +0,487,1,256,4374, +16,0,395,1,459, +4375,16,0,167,1, +406,4376,16,0,562, +1,41,4377,16,0, +167,1,2658,4378,16, +0,659,1,43,4379, +16,0,640,1,1990, +4380,16,0,585,1, +2337,4381,16,0,585, +1,509,4382,16,0, +655,1,52,4383,16, +0,594,1,151,4384, +16,0,282,1,447, +4385,16,0,305,1, +166,4386,16,0,293, +1,462,4387,16,0, +167,1,277,4388,16, +0,434,1,1695,4389, +16,0,270,1,1261, +4390,16,0,281,1, +1153,4391,16,0,174, +1,381,4392,16,0, +550,1,2106,4393,16, +0,585,1,1335,4394, +16,0,326,1,71, +4395,16,0,203,1, +182,4396,16,0,305, +1,76,4397,16,0, +549,1,79,4398,16, +0,218,1,1933,4399, +16,0,407,1,299, +4400,16,0,444,1, +85,4401,16,0,457, +1,1515,4402,16,0, +556,1,2198,4403,16, +0,585,1,89,4404, +16,0,227,1,1834, +4405,16,0,292,1, +1622,4406,16,0,654, +1,2413,4407,16,0, +585,1,2075,4408,16, +0,585,1,1731,4409, +16,0,250,1,97, +4410,16,0,411,1, +1297,4411,16,0,328, +1,1189,4412,16,0, +217,1,102,4413,16, +0,238,1,1585,4414, +16,0,663,1,322, +4415,16,0,458,1, +1958,4416,16,0,585, +1,199,4417,16,0, +316,1,1371,4418,16, +0,396,1,217,4419, +16,0,325,1,132, +4420,19,4421,4,36, 67,0,111,0,110, 0,115,0,116,0, 97,0,110,0,116, -0,1,129,4240,1, -130,4313,19,4314,4, -24,76,0,105,0, -115,0,116,0,67, -0,111,0,110,0, -115,0,116,0,97, -0,110,0,116,0, -1,130,4240,1,131, -4315,19,169,1,131, -4316,5,67,1,1901, -4317,16,0,585,1, -1479,4318,16,0,533, -1,112,4319,16,0, -249,1,2293,4320,16, -0,273,1,1804,4321, -16,0,585,1,431, -4322,16,0,580,1, -1443,4323,16,0,468, -1,1756,4324,16,0, -673,1,124,4325,16, -0,258,1,525,4326, -16,0,305,1,236, -4327,16,0,341,1, -346,4328,16,0,496, -1,1876,4329,16,0, -318,1,1659,4330,16, -0,673,1,1225,4331, -16,0,248,1,1117, -4332,16,0,219,1, -137,4333,16,0,272, -1,2318,4334,16,0, -673,1,1775,4335,16, -0,585,1,32,4336, -16,0,585,1,1407, -4337,16,0,487,1, -256,4338,16,0,395, -1,459,4339,16,0, -167,1,406,4340,16, -0,562,1,41,4341, -16,0,167,1,2658, -4342,16,0,659,1, -43,4343,16,0,640, -1,1990,4344,16,0, -585,1,2337,4345,16, -0,585,1,509,4346, -16,0,655,1,52, -4347,16,0,594,1, -151,4348,16,0,282, -1,447,4349,16,0, -305,1,166,4350,16, -0,293,1,462,4351, -16,0,167,1,277, -4352,16,0,434,1, -1695,4353,16,0,270, -1,1261,4354,16,0, -281,1,1153,4355,16, -0,174,1,381,4356, -16,0,550,1,2106, -4357,16,0,585,1, -1335,4358,16,0,326, -1,71,4359,16,0, -203,1,182,4360,16, -0,305,1,76,4361, -16,0,549,1,79, -4362,16,0,218,1, -1933,4363,16,0,407, -1,299,4364,16,0, -444,1,85,4365,16, -0,457,1,1515,4366, -16,0,556,1,2198, -4367,16,0,585,1, -89,4368,16,0,227, -1,1834,4369,16,0, -292,1,1622,4370,16, -0,654,1,2413,4371, -16,0,585,1,2075, -4372,16,0,585,1, -1731,4373,16,0,250, -1,97,4374,16,0, -411,1,1297,4375,16, -0,328,1,1189,4376, -16,0,217,1,102, -4377,16,0,238,1, -1585,4378,16,0,663, -1,322,4379,16,0, -458,1,1958,4380,16, -0,585,1,199,4381, -16,0,316,1,1371, -4382,16,0,396,1, -217,4383,16,0,325, -1,132,4384,19,4385, -4,36,67,0,111, -0,110,0,115,0, -116,0,97,0,110, -0,116,0,69,0, +0,69,0,120,0, +112,0,114,0,101, +0,115,0,115,0, +105,0,111,0,110, +0,1,132,4352,1, +133,4422,19,4423,4, +30,73,0,100,0, +101,0,110,0,116, +0,69,0,120,0, +112,0,114,0,101, +0,115,0,115,0, +105,0,111,0,110, +0,1,133,4352,1, +134,4424,19,4425,4, +36,73,0,100,0, +101,0,110,0,116, +0,68,0,111,0, +116,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,1,134,4352, +1,135,4426,19,4427, +4,44,70,0,117, +0,110,0,99,0, +116,0,105,0,111, +0,110,0,67,0, +97,0,108,0,108, +0,69,0,120,0, +112,0,114,0,101, +0,115,0,115,0, +105,0,111,0,110, +0,1,135,4352,1, +136,4428,19,4429,4, +32,66,0,105,0, +110,0,97,0,114, +0,121,0,69,0, 120,0,112,0,114, 0,101,0,115,0, 115,0,105,0,111, -0,110,0,1,132, -4316,1,133,4386,19, -4387,4,30,73,0, -100,0,101,0,110, -0,116,0,69,0, +0,110,0,1,136, +4352,1,137,4430,19, +4431,4,30,85,0, +110,0,97,0,114, +0,121,0,69,0, 120,0,112,0,114, 0,101,0,115,0, 115,0,105,0,111, -0,110,0,1,133, -4316,1,134,4388,19, -4389,4,36,73,0, -100,0,101,0,110, -0,116,0,68,0, -111,0,116,0,69, +0,110,0,1,137, +4352,1,138,4432,19, +4433,4,36,84,0, +121,0,112,0,101, +0,99,0,97,0, +115,0,116,0,69, 0,120,0,112,0, 114,0,101,0,115, 0,115,0,105,0, 111,0,110,0,1, -134,4316,1,135,4390, -19,4391,4,44,70, -0,117,0,110,0, -99,0,116,0,105, -0,111,0,110,0, -67,0,97,0,108, -0,108,0,69,0, -120,0,112,0,114, -0,101,0,115,0, -115,0,105,0,111, -0,110,0,1,135, -4316,1,136,4392,19, -4393,4,32,66,0, -105,0,110,0,97, -0,114,0,121,0, -69,0,120,0,112, -0,114,0,101,0, -115,0,115,0,105, -0,111,0,110,0, -1,136,4316,1,137, -4394,19,4395,4,30, -85,0,110,0,97, -0,114,0,121,0, -69,0,120,0,112, -0,114,0,101,0, -115,0,115,0,105, -0,111,0,110,0, -1,137,4316,1,138, -4396,19,4397,4,36, -84,0,121,0,112, -0,101,0,99,0, -97,0,115,0,116, +138,4352,1,139,4434, +19,4435,4,42,80, +0,97,0,114,0, +101,0,110,0,116, +0,104,0,101,0, +115,0,105,0,115, 0,69,0,120,0, 112,0,114,0,101, 0,115,0,115,0, 105,0,111,0,110, -0,1,138,4316,1, -139,4398,19,4399,4, -42,80,0,97,0, -114,0,101,0,110, -0,116,0,104,0, -101,0,115,0,105, -0,115,0,69,0, -120,0,112,0,114, -0,101,0,115,0, -115,0,105,0,111, -0,110,0,1,139, -4316,1,140,4400,19, -4401,4,56,73,0, -110,0,99,0,114, -0,101,0,109,0, -101,0,110,0,116, -0,68,0,101,0, +0,1,139,4352,1, +140,4436,19,4437,4, +56,73,0,110,0, 99,0,114,0,101, 0,109,0,101,0, -110,0,116,0,69, -0,120,0,112,0, -114,0,101,0,115, -0,115,0,105,0, -111,0,110,0,1, -140,4316,1,142,4402, -19,683,1,142,3875, -1,143,4403,19,705, -1,143,3875,1,144, -4404,19,3156,1,144, -3878,1,145,4405,19, -3151,1,145,3878,1, -146,4406,19,3162,1, -146,3878,1,147,4407, -19,3173,1,147,3878, -1,148,4408,19,3184, -1,148,3881,1,149, -4409,19,3190,1,149, -3881,1,150,4410,19, -3178,1,150,3885,1, -151,4411,19,3168,1, -151,3885,1,152,4412, -19,689,1,152,3889, -1,153,4413,19,710, -1,153,3889,1,154, -4414,19,695,1,154, -3893,1,155,4415,19, -700,1,155,3893,1, -156,4416,19,1636,1, -156,3899,1,157,4417, -19,1631,1,157,3899, -1,158,4418,19,1622, -1,158,3903,1,159, -4419,19,1680,1,159, -3909,1,160,4420,19, -1657,1,160,3909,1, -161,4421,19,1117,1, -161,3914,1,162,4422, -19,902,1,162,3959, -1,163,4423,19,886, -1,163,3959,1,164, -4424,19,892,1,164, -3975,1,165,4425,19, -880,1,165,3975,1, -166,4426,19,1145,1, -166,3991,1,167,4427, -19,782,1,167,3978, -1,168,4428,19,897, -1,168,3978,1,169, -4429,19,777,1,169, -3978,1,170,4430,19, -802,1,170,3978,1, -171,4431,19,771,1, -171,3978,1,172,4432, -19,765,1,172,3978, -1,173,4433,19,760, -1,173,3978,1,174, -4434,19,755,1,174, -3978,1,175,4435,19, -749,1,175,3978,1, -176,4436,19,744,1, -176,3978,1,177,4437, -19,739,1,177,3978, -1,178,4438,19,734, -1,178,3978,1,179, -4439,19,729,1,179, -3978,1,180,4440,19, -1152,1,180,4063,1, -181,4441,19,1290,1, -181,4076,1,182,4442, -19,1139,1,182,4089, -1,183,4443,19,1278, -1,183,4089,1,184, -4444,19,919,1,184, -4102,1,185,4445,19, -722,1,185,4102,1, -186,4446,19,817,1, -186,4102,1,187,4447, -19,845,1,187,4102, -1,188,4448,19,865, -1,188,4115,1,189, -4449,19,911,1,189, -4115,1,190,4450,19, -825,1,190,4128,1, -191,4451,19,838,1, -191,4128,1,192,4452, -19,791,1,192,4141, -1,193,4453,19,830, -1,193,4141,1,194, -4454,19,1477,1,194, -4154,1,195,4455,19, -1158,1,195,4154,1, -196,4456,19,1509,1, -196,4154,1,197,4457, -19,1541,1,197,4154, -1,198,4458,19,1406, -1,198,4004,1,199, -4459,19,1466,1,199, -4004,1,200,4460,19, -1133,1,200,4017,1, -201,4461,19,1573,1, -201,4017,1,202,4462, -19,1504,1,202,4017, -1,203,4463,19,1451, -1,203,4017,1,204, -4464,19,1374,1,204, -4017,1,205,4465,19, -1300,1,205,4017,1, -206,4466,19,1310,1, -206,4017,1,207,4467, -19,1128,1,207,4017, -1,208,4468,19,1557, -1,208,4017,1,209, -4469,19,1499,1,209, -4017,1,210,4470,19, -1441,1,210,4017,1, -211,4471,19,1363,1, -211,4017,1,212,4472, -19,1326,1,212,4017, -1,213,4473,19,1111, -1,213,4017,1,214, -4474,19,1461,1,214, -4017,1,215,4475,19, -1487,1,215,4017,1, -216,4476,19,1434,1, -216,4017,1,217,4477, -19,1456,1,217,4017, -1,218,4478,19,1266, -1,218,4017,1,219, -4479,19,1170,1,219, -4017,1,220,4480,19, -1100,1,220,4017,1, -221,4481,19,1531,1, -221,4017,1,222,4482, -19,1482,1,222,4017, -1,223,4483,19,1429, -1,223,4017,1,224, -4484,19,1295,1,224, -4050,1,225,4485,19, -1273,1,225,4050,1, -226,4486,19,1562,1, -226,4240,1,227,4487, -19,1586,1,227,4240, -1,228,4488,19,1552, -1,228,4240,1,229, -4489,19,1547,1,229, -4240,1,230,4490,19, -1568,1,230,4240,1, -231,4491,19,1515,1, -231,4240,1,232,4492, -19,1220,1,232,4240, -1,233,4493,19,1395, -1,233,4316,1,234, -4494,19,1181,1,234, -4316,1,235,4495,19, -1188,1,235,4316,1, -236,4496,19,1209,1, -236,4316,1,237,4497, -19,1204,1,237,4316, -1,238,4498,19,1199, -1,238,4316,1,239, -4499,19,1194,1,239, -4316,1,240,4500,19, -1384,1,240,4316,1, -241,4501,19,1412,1, -241,4316,1,242,4502, -19,1389,1,242,4316, -1,243,4503,19,1379, -1,243,4316,1,244, -4504,19,1369,1,244, -4316,1,245,4505,19, -1352,1,245,4316,1, -246,4506,19,1305,1, -246,4316,1,247,4507, -19,1214,1,247,4316, -1,248,4508,19,1175, -1,248,4316,1,249, -4509,19,1123,1,249, -4316,1,250,4510,19, -1581,1,250,4316,1, -251,4511,19,1536,1, -251,4316,1,252,4512, -19,1526,1,252,4316, -1,253,4513,19,1521, -1,253,4316,1,254, -4514,19,1472,1,254, -4316,1,255,4515,19, -1446,1,255,4316,1, -256,4516,19,1422,1, -256,4316,1,257,4517, -19,1417,1,257,4316, -1,258,4518,19,1358, -1,258,4316,1,259, -4519,19,1334,1,259, -4316,1,260,4520,19, -1400,1,260,4316,1, -261,4521,19,1493,1, -261,4316,1,262,4522, -19,1347,1,262,4316, -1,263,4523,19,1341, -1,263,4316,1,264, -4524,19,1321,1,264, -4316,1,265,4525,19, -1284,1,265,4316,1, -266,4526,19,1261,1, -266,4316,1,267,4527, -19,1106,1,267,4316, -1,268,4528,19,1596, -1,268,4316,1,269, -4529,19,1226,1,269, -4316,1,270,4530,19, -1231,1,270,4316,1, -271,4531,19,1251,1, -271,4316,1,272,4532, -19,1241,1,272,4316, -1,273,4533,19,1246, -1,273,4316,1,274, -4534,19,1236,1,274, -4316,1,275,4535,19, -1591,1,275,4316,1, -276,4536,19,1256,1, -276,4316,1,277,4537, -19,1316,1,277,4159, -1,278,4538,19,1650, -1,278,4229,1,279, -4539,19,1686,1,279, -4229,1,280,4540,19, -1666,1,280,4233,1, -281,4541,19,1985,1, -281,3933,1,282,4542, -19,1980,1,282,3933, -1,283,4543,19,1975, -1,283,3933,1,284, -4544,19,1970,1,284, -3933,1,285,4545,19, -1965,1,285,3933,1, -286,4546,19,1960,1, -286,3933,1,287,4547, -19,1955,1,287,3933, -1,288,4548,19,1944, -1,288,3953,1,289, -4549,19,1939,1,289, -3953,1,290,4550,19, -1934,1,290,3953,1, -291,4551,19,1929,1, -291,3953,1,292,4552, -19,1924,1,292,3953, -1,293,4553,19,1919, -1,293,3953,1,294, -4554,19,1914,1,294, -3953,1,295,4555,19, -1909,1,295,3953,1, -296,4556,19,1904,1, -296,3953,1,297,4557, -19,1739,1,297,3953, -1,298,4558,19,1898, -1,298,3953,1,299, -4559,19,1893,1,299, -3953,1,300,4560,19, -1888,1,300,3953,1, -301,4561,19,1732,1, -301,3953,1,302,4562, -19,1883,1,302,3953, -1,303,4563,19,1878, -1,303,3953,1,304, -4564,19,1873,1,304, -3953,1,305,4565,19, -1868,1,305,3953,1, -306,4566,19,1863,1, -306,3953,1,307,4567, -19,1858,1,307,3953, -1,308,4568,19,1725, -1,308,3953,1,309, -4569,19,1852,1,309, -3953,1,310,4570,19, -1847,1,310,3953,1, -311,4571,19,1842,1, -311,3953,1,312,4572, -19,1719,1,312,3953, -1,313,4573,19,1836, -1,313,3953,1,314, -4574,19,1767,1,314, -3953,1,315,4575,19, -1831,1,315,3953,1, -316,4576,19,1826,1, -316,3953,1,317,4577, -19,1821,1,317,3953, -1,318,4578,19,1816, -1,318,3953,1,319, -4579,19,1811,1,319, -3953,1,320,4580,19, -1806,1,320,3953,1, -321,4581,19,1801,1, -321,3953,1,322,4582, -19,4583,4,50,65, -0,114,0,103,0, -117,0,109,0,101, -0,110,0,116,0, -68,0,101,0,99, -0,108,0,97,0, -114,0,97,0,116, +110,0,116,0,68, +0,101,0,99,0, +114,0,101,0,109, +0,101,0,110,0, +116,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, 0,105,0,111,0, -110,0,76,0,105, -0,115,0,116,0, -95,0,51,0,1, -322,3909,1,323,4584, -19,4585,4,28,65, -0,114,0,103,0, -117,0,109,0,101, -0,110,0,116,0, -76,0,105,0,115, -0,116,0,95,0, -51,0,1,323,4229, -1,324,4586,19,4587, +110,0,1,140,4352, +1,142,4438,19,683, +1,142,3911,1,143, +4439,19,705,1,143, +3911,1,144,4440,19, +3192,1,144,3914,1, +145,4441,19,3187,1, +145,3914,1,146,4442, +19,3198,1,146,3914, +1,147,4443,19,3209, +1,147,3914,1,148, +4444,19,3220,1,148, +3917,1,149,4445,19, +3226,1,149,3917,1, +150,4446,19,3214,1, +150,3921,1,151,4447, +19,3204,1,151,3921, +1,152,4448,19,689, +1,152,3925,1,153, +4449,19,710,1,153, +3925,1,154,4450,19, +695,1,154,3929,1, +155,4451,19,700,1, +155,3929,1,156,4452, +19,1636,1,156,3935, +1,157,4453,19,1631, +1,157,3935,1,158, +4454,19,1622,1,158, +3939,1,159,4455,19, +1680,1,159,3945,1, +160,4456,19,1657,1, +160,3945,1,161,4457, +19,1117,1,161,3950, +1,162,4458,19,902, +1,162,3995,1,163, +4459,19,886,1,163, +3995,1,164,4460,19, +892,1,164,4011,1, +165,4461,19,880,1, +165,4011,1,166,4462, +19,1145,1,166,4027, +1,167,4463,19,782, +1,167,4014,1,168, +4464,19,897,1,168, +4014,1,169,4465,19, +777,1,169,4014,1, +170,4466,19,802,1, +170,4014,1,171,4467, +19,771,1,171,4014, +1,172,4468,19,765, +1,172,4014,1,173, +4469,19,760,1,173, +4014,1,174,4470,19, +755,1,174,4014,1, +175,4471,19,749,1, +175,4014,1,176,4472, +19,744,1,176,4014, +1,177,4473,19,739, +1,177,4014,1,178, +4474,19,734,1,178, +4014,1,179,4475,19, +729,1,179,4014,1, +180,4476,19,1152,1, +180,4099,1,181,4477, +19,1290,1,181,4112, +1,182,4478,19,1139, +1,182,4125,1,183, +4479,19,1278,1,183, +4125,1,184,4480,19, +919,1,184,4138,1, +185,4481,19,722,1, +185,4138,1,186,4482, +19,817,1,186,4138, +1,187,4483,19,845, +1,187,4138,1,188, +4484,19,865,1,188, +4151,1,189,4485,19, +911,1,189,4151,1, +190,4486,19,825,1, +190,4164,1,191,4487, +19,838,1,191,4164, +1,192,4488,19,791, +1,192,4177,1,193, +4489,19,830,1,193, +4177,1,194,4490,19, +1477,1,194,4190,1, +195,4491,19,1158,1, +195,4190,1,196,4492, +19,1509,1,196,4190, +1,197,4493,19,1541, +1,197,4190,1,198, +4494,19,1406,1,198, +4040,1,199,4495,19, +1466,1,199,4040,1, +200,4496,19,1133,1, +200,4053,1,201,4497, +19,1573,1,201,4053, +1,202,4498,19,1504, +1,202,4053,1,203, +4499,19,1451,1,203, +4053,1,204,4500,19, +1374,1,204,4053,1, +205,4501,19,1300,1, +205,4053,1,206,4502, +19,1310,1,206,4053, +1,207,4503,19,1128, +1,207,4053,1,208, +4504,19,1557,1,208, +4053,1,209,4505,19, +1499,1,209,4053,1, +210,4506,19,1441,1, +210,4053,1,211,4507, +19,1363,1,211,4053, +1,212,4508,19,1326, +1,212,4053,1,213, +4509,19,1111,1,213, +4053,1,214,4510,19, +1461,1,214,4053,1, +215,4511,19,1487,1, +215,4053,1,216,4512, +19,1434,1,216,4053, +1,217,4513,19,1456, +1,217,4053,1,218, +4514,19,1266,1,218, +4053,1,219,4515,19, +1170,1,219,4053,1, +220,4516,19,1100,1, +220,4053,1,221,4517, +19,1531,1,221,4053, +1,222,4518,19,1482, +1,222,4053,1,223, +4519,19,1429,1,223, +4053,1,224,4520,19, +1295,1,224,4086,1, +225,4521,19,1273,1, +225,4086,1,226,4522, +19,1562,1,226,4276, +1,227,4523,19,1586, +1,227,4276,1,228, +4524,19,1552,1,228, +4276,1,229,4525,19, +1547,1,229,4276,1, +230,4526,19,1568,1, +230,4276,1,231,4527, +19,1515,1,231,4276, +1,232,4528,19,1220, +1,232,4276,1,233, +4529,19,1395,1,233, +4352,1,234,4530,19, +1181,1,234,4352,1, +235,4531,19,1188,1, +235,4352,1,236,4532, +19,1209,1,236,4352, +1,237,4533,19,1204, +1,237,4352,1,238, +4534,19,1199,1,238, +4352,1,239,4535,19, +1194,1,239,4352,1, +240,4536,19,1384,1, +240,4352,1,241,4537, +19,1412,1,241,4352, +1,242,4538,19,1389, +1,242,4352,1,243, +4539,19,1379,1,243, +4352,1,244,4540,19, +1369,1,244,4352,1, +245,4541,19,1352,1, +245,4352,1,246,4542, +19,1305,1,246,4352, +1,247,4543,19,1214, +1,247,4352,1,248, +4544,19,1175,1,248, +4352,1,249,4545,19, +1123,1,249,4352,1, +250,4546,19,1581,1, +250,4352,1,251,4547, +19,1536,1,251,4352, +1,252,4548,19,1526, +1,252,4352,1,253, +4549,19,1521,1,253, +4352,1,254,4550,19, +1472,1,254,4352,1, +255,4551,19,1446,1, +255,4352,1,256,4552, +19,1422,1,256,4352, +1,257,4553,19,1417, +1,257,4352,1,258, +4554,19,1358,1,258, +4352,1,259,4555,19, +1334,1,259,4352,1, +260,4556,19,1400,1, +260,4352,1,261,4557, +19,1493,1,261,4352, +1,262,4558,19,1347, +1,262,4352,1,263, +4559,19,1341,1,263, +4352,1,264,4560,19, +1321,1,264,4352,1, +265,4561,19,1284,1, +265,4352,1,266,4562, +19,1261,1,266,4352, +1,267,4563,19,1106, +1,267,4352,1,268, +4564,19,1596,1,268, +4352,1,269,4565,19, +1226,1,269,4352,1, +270,4566,19,1231,1, +270,4352,1,271,4567, +19,1251,1,271,4352, +1,272,4568,19,1241, +1,272,4352,1,273, +4569,19,1246,1,273, +4352,1,274,4570,19, +1236,1,274,4352,1, +275,4571,19,1591,1, +275,4352,1,276,4572, +19,1256,1,276,4352, +1,277,4573,19,1316, +1,277,4195,1,278, +4574,19,1650,1,278, +4265,1,279,4575,19, +1686,1,279,4265,1, +280,4576,19,1666,1, +280,4269,1,281,4577, +19,1985,1,281,3969, +1,282,4578,19,1980, +1,282,3969,1,283, +4579,19,1975,1,283, +3969,1,284,4580,19, +1970,1,284,3969,1, +285,4581,19,1965,1, +285,3969,1,286,4582, +19,1960,1,286,3969, +1,287,4583,19,1955, +1,287,3969,1,288, +4584,19,1944,1,288, +3989,1,289,4585,19, +1939,1,289,3989,1, +290,4586,19,1934,1, +290,3989,1,291,4587, +19,1929,1,291,3989, +1,292,4588,19,1924, +1,292,3989,1,293, +4589,19,1919,1,293, +3989,1,294,4590,19, +1914,1,294,3989,1, +295,4591,19,1909,1, +295,3989,1,296,4592, +19,1904,1,296,3989, +1,297,4593,19,1739, +1,297,3989,1,298, +4594,19,1898,1,298, +3989,1,299,4595,19, +1893,1,299,3989,1, +300,4596,19,1888,1, +300,3989,1,301,4597, +19,1732,1,301,3989, +1,302,4598,19,1883, +1,302,3989,1,303, +4599,19,1878,1,303, +3989,1,304,4600,19, +1873,1,304,3989,1, +305,4601,19,1868,1, +305,3989,1,306,4602, +19,1863,1,306,3989, +1,307,4603,19,1858, +1,307,3989,1,308, +4604,19,1725,1,308, +3989,1,309,4605,19, +1852,1,309,3989,1, +310,4606,19,1847,1, +310,3989,1,311,4607, +19,1842,1,311,3989, +1,312,4608,19,1719, +1,312,3989,1,313, +4609,19,1836,1,313, +3989,1,314,4610,19, +1767,1,314,3989,1, +315,4611,19,1831,1, +315,3989,1,316,4612, +19,1826,1,316,3989, +1,317,4613,19,1821, +1,317,3989,1,318, +4614,19,1816,1,318, +3989,1,319,4615,19, +1811,1,319,3989,1, +320,4616,19,1806,1, +320,3989,1,321,4617, +19,1801,1,321,3989, +1,322,4618,19,4619, 4,50,65,0,114, 0,103,0,117,0, 109,0,101,0,110, @@ -10737,16 +10739,16 @@ public yyLSLSyntax 0,111,0,110,0, 76,0,105,0,115, 0,116,0,95,0, -52,0,1,324,3909, -1,325,4588,19,4589, +51,0,1,322,3945, +1,323,4620,19,4621, 4,28,65,0,114, 0,103,0,117,0, 109,0,101,0,110, 0,116,0,76,0, 105,0,115,0,116, -0,95,0,52,0, -1,325,4229,1,326, -4590,19,4591,4,50, +0,95,0,51,0, +1,323,4265,1,324, +4622,19,4623,4,50, 65,0,114,0,103, 0,117,0,109,0, 101,0,110,0,116, @@ -10756,8 +10758,28 @@ public yyLSLSyntax 116,0,105,0,111, 0,110,0,76,0, 105,0,115,0,116, -0,95,0,53,0, -1,326,3909,2,0,0}; +0,95,0,52,0, +1,324,3945,1,325, +4624,19,4625,4,28, +65,0,114,0,103, +0,117,0,109,0, +101,0,110,0,116, +0,76,0,105,0, +115,0,116,0,95, +0,52,0,1,325, +4265,1,326,4626,19, +4627,4,50,65,0, +114,0,103,0,117, +0,109,0,101,0, +110,0,116,0,68, +0,101,0,99,0, +108,0,97,0,114, +0,97,0,116,0, +105,0,111,0,110, +0,76,0,105,0, +115,0,116,0,95, +0,53,0,1,326, +3945,2,0,0}; new Sfactory(this,"ExpressionArgument_1",new SCreator(ExpressionArgument_1_factory)); new Sfactory(this,"SimpleAssignment_8",new SCreator(SimpleAssignment_8_factory)); new Sfactory(this,"StatementList_1",new SCreator(StatementList_1_factory)); -- cgit v1.1 From 51fe97a00c5aaed446dd46b9ef7c120c5ad29845 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Jun 2012 23:33:05 +0100 Subject: Set CreateDefaultAvatarEntries = true in Robust.HG.ini.example to match Robust.HG.ini Thanks to Ai Austin for the spot. --- bin/Robust.HG.ini.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 00e2fd7..9887ab5 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -185,7 +185,7 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ;; This switch creates the minimum set of body parts and avatar entries for a viewer 2 ;; to show a default "Ruth" avatar rather than a cloud for a newly created user. ;; Default is false - ; CreateDefaultAvatarEntries = false + CreateDefaultAvatarEntries = true ;; Allow the service to process HTTP createuser calls. ;; Default is false. -- cgit v1.1 From bab7dab4c586f9e7a71e9acec45c527fd8e5be07 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Jun 2012 23:37:16 +0100 Subject: Comment out the scene presence sitting debug log messages for now --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 029e0d7..3909fd4 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1899,9 +1899,9 @@ namespace OpenSim.Region.Framework.Scenes { if (SitTargetUnOccupied) { - m_log.DebugFormat( - "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied", - Name, part.Name, part.LocalId); +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied", +// Name, part.Name, part.LocalId); part.SitTargetAvatar = UUID; offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); @@ -1913,9 +1913,9 @@ namespace OpenSim.Region.Framework.Scenes { if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) { - m_log.DebugFormat( - "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m", - Name, part.Name, part.LocalId); +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m", +// Name, part.Name, part.LocalId); AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); canSit = true; -- cgit v1.1 From 8c7149063bce41cac6543757c7b917583f21ea90 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 12 Jun 2012 01:23:40 +0100 Subject: In PresenceDetector.OnConnectionClose(), use the IsChildAgent check already available on IClientAPI.SceneAgent rather than retrieving it again by scanning all scenes. --- OpenSim/Framework/IClientAPI.cs | 22 ++++++++++++++++------ .../Region/ClientStack/Linden/UDP/LLClientView.cs | 4 ++-- .../Presence/PresenceDetector.cs | 13 +------------ OpenSim/Region/Framework/Scenes/Scene.cs | 7 +++---- 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 869b069..f8b6a84 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -740,14 +740,24 @@ namespace OpenSim.Framework /// string Name { get; } - /// - /// Determines whether the client thread is doing anything or not. - /// + /// + /// True if the client is active (sending and receiving new UDP messages). False if the client is closing. + /// bool IsActive { get; set; } - /// - /// Determines whether the client is or has been removed from a given scene - /// + /// + /// Set if the client is closing due to a logout request or because of too much time since last ack. + /// + /// + /// Do not use this flag if you want to know if the client is closing, since it will not be set in other + /// circumstances (e.g. if a child agent is closed or the agent is kicked off the simulator). Use IsActive + /// instead. + /// + /// Only set for root agents. + /// + /// TODO: Too much time since last ack should probably be a separate property, or possibly part of a state + /// machine. + /// bool IsLoggingOut { get; set; } bool SendLogoutPacketWhenClosing { set; } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 74b9c6d..c4f167e 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -490,12 +490,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// public void Close() { + IsActive = false; + m_log.DebugFormat( "[CLIENT]: Close has been called for {0} attached to scene {1}", Name, m_scene.RegionInfo.RegionName); - IsActive = false; - // Shutdown the image manager ImageManager.Close(); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs index ccfbf78..b43745c 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs @@ -64,7 +64,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence scene.EventManager.OnNewClient -= OnNewClient; m_PresenceService.LogoutRegionAgents(scene.RegionInfo.RegionID); - } public void OnMakeRootAgent(ScenePresence sp) @@ -80,18 +79,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence public void OnConnectionClose(IClientAPI client) { - if (client.IsLoggingOut) + if (client.IsLoggingOut && !client.SceneAgent.IsChildAgent) { - object sp = null; - if (client.Scene.TryGetScenePresence(client.AgentId, out sp)) - { - if (sp is ScenePresence) - { - if (((ScenePresence)sp).IsChildAgent) - return; - } - } - // m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); m_PresenceService.LogoutAgent(client.SessionId); } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 7afde38..1305d83 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3463,10 +3463,9 @@ namespace OpenSim.Region.Framework.Scenes // Or the same user is trying to be root twice here, won't work. // Kill it. m_log.DebugFormat( - "[SCENE]: Zombie scene presence detected for {0} in {1}", - agent.AgentID, - RegionInfo.RegionName - ); + "[SCENE]: Zombie scene presence detected for {0} {1} in {2}", + sp.Name, sp.UUID, RegionInfo.RegionName); + sp.ControllingClient.Close(); sp = null; } -- cgit v1.1 From c89db34fc4372be7ff94d92472131b2c33de8605 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 12 Jun 2012 02:03:31 +0100 Subject: If the simulator closes a root agent due to ack timeout, then send the client a kick message with that reason, in case it is somehow still listening. --- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 7f86491..2036f61 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -558,9 +558,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (!client.IsLoggingOut && (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) { - m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); + m_log.WarnFormat( + "[LLUDPSERVER]: Ack timeout for {0} {1}, disconnecting", + client.Name, client.AgentId); + StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); - RemoveClient(client); + LogoutClientDueToTimeout(client); return; } @@ -1121,6 +1124,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP Util.FireAndForget(o => client.Close()); } + private void LogoutClientDueToTimeout(IClientAPI client) + { + // We must set IsLoggingOut synchronously so that we can stop the packet loop reinvoking this method. + client.IsLoggingOut = true; + + // 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 => + { if (!client.SceneAgent.IsChildAgent) + client.Kick("Simulator logged you out due to connection timeout"); + client.Close(); }); + } + private void IncomingPacketHandler() { // Set this culture for the thread that incoming packets are received -- cgit v1.1 From b099f26376a7d671eeb9113dd7611cfcb0e57de0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 12 Jun 2012 02:16:36 +0100 Subject: Set IClientAPI.IsActive = false early on client removal due to ack timeout rather than using IsLoggingOut flag. IsActive is more appropriate since unack timeout is not due to voluntary logout. This is in line with operations such as manual kick that do not set the IsLoggingOut flag. It's also slightly better race-wise since it reduces the chance of this operation clashing with another reason for client deactivation (e.g. manual kick). --- OpenSim/Framework/IClientAPI.cs | 9 +-- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 64 ++++++++++++---------- 2 files changed, 38 insertions(+), 35 deletions(-) diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index f8b6a84..2ea6de5 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -741,22 +741,19 @@ namespace OpenSim.Framework string Name { get; } /// - /// True if the client is active (sending and receiving new UDP messages). False if the client is closing. + /// True if the client is active (sending and receiving new UDP messages). False if the client is being closed. /// bool IsActive { get; set; } /// - /// Set if the client is closing due to a logout request or because of too much time since last ack. + /// Set if the client is closing due to a logout request /// /// /// Do not use this flag if you want to know if the client is closing, since it will not be set in other /// circumstances (e.g. if a child agent is closed or the agent is kicked off the simulator). Use IsActive - /// instead. + /// instead with a IClientAPI.SceneAgent.IsChildAgent check if necessary. /// /// Only set for root agents. - /// - /// TODO: Too much time since last ack should probably be a separate property, or possibly part of a state - /// machine. /// bool IsLoggingOut { get; set; } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 2036f61..37d2943 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -555,15 +555,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (udpClient.IsPaused) timeoutTicks = m_pausedAckTimeout; - if (!client.IsLoggingOut && + if (client.IsActive && (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) { - m_log.WarnFormat( - "[LLUDPSERVER]: Ack timeout for {0} {1}, disconnecting", - client.Name, client.AgentId); + // 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() + client.IsActive = false; - StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); - LogoutClientDueToTimeout(client); + // 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)); return; } @@ -792,7 +794,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Interlocked.Increment(ref udpClient.PacketsReceived); int now = Environment.TickCount & Int32.MaxValue; - udpClient.TickLastPacketReceived = now; +// udpClient.TickLastPacketReceived = now; #region ACK Receiving @@ -1113,30 +1115,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP return client; } - private void RemoveClient(IClientAPI client) + /// + /// Deactivates the client if we don't receive any packets within a certain amount of time (default 60 seconds). + /// + /// + /// If a connection is active then we will always receive packets even if nothing else is happening, due to + /// regular client pings. + /// + /// + private void DeactivateClientDueToTimeout(IClientAPI client) { - // We must set IsLoggingOut synchronously so that we can stop the packet loop reinvoking this method. - client.IsLoggingOut = true; + // 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() + client.IsActive = false; - // 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 => client.Close()); - } + m_log.WarnFormat( + "[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}", + client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName); - private void LogoutClientDueToTimeout(IClientAPI client) - { - // We must set IsLoggingOut synchronously so that we can stop the packet loop reinvoking this method. - client.IsLoggingOut = true; - - // 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 => - { if (!client.SceneAgent.IsChildAgent) - client.Kick("Simulator logged you out due to connection timeout"); - client.Close(); }); + StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); + + if (!client.SceneAgent.IsChildAgent) + client.Kick("Simulator logged you out due to connection timeout"); + + client.Close(); } private void IncomingPacketHandler() @@ -1450,8 +1452,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected void LogoutHandler(IClientAPI client) { client.SendLogoutPacket(); + if (!client.IsLoggingOut) - RemoveClient(client); + { + client.IsLoggingOut = true; + client.Close(); + } } } } \ No newline at end of file -- cgit v1.1 From 1b1f0a2d77fb4d2ac572f16c71a7560860c8c040 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 12 Jun 2012 02:43:33 +0100 Subject: OnConnectionClosed listeners, retrieve data from IClientAPI.SceneAgent rather than scanning all scene for the presence with the right id Stop checking IsLoggingOut on these listeners, if called with a root agent then we always want to perform these actions. This covers cases where the client is closed due to manual kick, simulator shutdown, etc. --- OpenSim/Framework/ISceneAgent.cs | 7 ++++ .../EntityTransfer/HGEntityTransferModule.cs | 46 ++++++++++------------ .../GridUser/ActivityDetector.cs | 28 +++---------- .../Presence/PresenceDetector.cs | 2 +- .../Framework/Scenes/AsyncInventorySender.cs | 2 +- .../SimianGrid/SimianActivityDetector.cs | 28 ++++--------- 6 files changed, 43 insertions(+), 70 deletions(-) diff --git a/OpenSim/Framework/ISceneAgent.cs b/OpenSim/Framework/ISceneAgent.cs index 824172d..563d906 100644 --- a/OpenSim/Framework/ISceneAgent.cs +++ b/OpenSim/Framework/ISceneAgent.cs @@ -26,6 +26,7 @@ */ using System; +using OpenMetaverse; namespace OpenSim.Framework { @@ -71,5 +72,11 @@ namespace OpenSim.Framework /// This includes scene object data and the appearance data of other avatars. /// void SendInitialDataToMe(); + + /// + /// Direction in which the scene presence is looking. + /// + /// Will be Vector3.Zero for a child agent. + Vector3 Lookat { get; } } } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 43a72e2..08863c2 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -325,34 +325,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer void OnConnectionClosed(IClientAPI obj) { - if (obj.IsLoggingOut) - { - object sp = null; - if (obj.Scene.TryGetScenePresence(obj.AgentId, out sp)) - { - if (((ScenePresence)sp).IsChildAgent) - return; - } + if (obj.SceneAgent.IsChildAgent) + return; - // Let's find out if this is a foreign user or a local user - IUserManagement uMan = Scene.RequestModuleInterface(); -// UserAccount account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, obj.AgentId); - if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) - { - // local grid user - return; - } + // Let's find out if this is a foreign user or a local user + IUserManagement uMan = Scene.RequestModuleInterface(); +// UserAccount account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, obj.AgentId); - AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode); + if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) + { + // local grid user + return; + } - if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) - { - string url = aCircuit.ServiceURLs["HomeURI"].ToString(); - IUserAgentService security = new UserAgentServiceConnector(url); - security.LogoutAgent(obj.AgentId, obj.SessionId); - //m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Sent logout call to UserAgentService @ {0}", url); - } - else + AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode); + + if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) + { + string url = aCircuit.ServiceURLs["HomeURI"].ToString(); + IUserAgentService security = new UserAgentServiceConnector(url); + security.LogoutAgent(obj.AgentId, obj.SessionId); + //m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Sent logout call to UserAgentService @ {0}", url); + } + else + { m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: HomeURI not found for agent {0} logout", obj.AgentId); } } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs index 4cf62ec..b0edce7 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs @@ -79,29 +79,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser public void OnConnectionClose(IClientAPI client) { - if (client.IsLoggingOut) - { - object sp = null; - Vector3 position = new Vector3(128, 128, 0); - Vector3 lookat = new Vector3(0, 1, 0); - - if (client.Scene.TryGetScenePresence(client.AgentId, out sp)) - { - if (sp is ScenePresence) - { - if (((ScenePresence)sp).IsChildAgent) - return; - - position = ((ScenePresence)sp).AbsolutePosition; - lookat = ((ScenePresence)sp).Lookat; - } - } - -// m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); - m_GridUserService.LoggedOut(client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, position, lookat); - } + if (client.SceneAgent.IsChildAgent) + return; +// m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); + m_GridUserService.LoggedOut( + client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, + client.SceneAgent.AbsolutePosition, client.SceneAgent.Lookat); } - } } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs index b43745c..172bea1 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs @@ -79,7 +79,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence public void OnConnectionClose(IClientAPI client) { - if (client.IsLoggingOut && !client.SceneAgent.IsChildAgent) + if (!client.SceneAgent.IsChildAgent) { // m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); m_PresenceService.LogoutAgent(client.SessionId); diff --git a/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs b/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs index 9cb5674..d9d2e64 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs @@ -137,7 +137,7 @@ namespace OpenSim.Region.Framework.Scenes } } - if (fh.Client.IsLoggingOut) + if (!fh.Client.IsActive) continue; // m_log.DebugFormat( diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs index 2267325..95e4bab 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs @@ -79,27 +79,13 @@ namespace OpenSim.Services.Connectors.SimianGrid public void OnConnectionClose(IClientAPI client) { - if (client.IsLoggingOut) - { - object sp = null; - Vector3 position = new Vector3(128, 128, 0); - Vector3 lookat = new Vector3(0, 1, 0); - - if (client.Scene.TryGetScenePresence(client.AgentId, out sp)) - { - if (sp is ScenePresence) - { - if (((ScenePresence)sp).IsChildAgent) - return; - - position = ((ScenePresence)sp).AbsolutePosition; - lookat = ((ScenePresence)sp).Lookat; - } - } + if (client.SceneAgent.IsChildAgent) + return; -// m_log.DebugFormat("[SIMIAN ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); - m_GridUserService.LoggedOut(client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, position, lookat); - } +// m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); + m_GridUserService.LoggedOut( + client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, + client.SceneAgent.AbsolutePosition, client.SceneAgent.Lookat); } void OnEnteringNewParcel(ScenePresence sp, int localLandID, UUID regionID) @@ -111,4 +97,4 @@ namespace OpenSim.Services.Connectors.SimianGrid }); } } -} +} \ No newline at end of file -- cgit v1.1 From 2ca31a9841991f748e972c96a3eba96e611f1dea Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 12 Jun 2012 02:46:14 +0100 Subject: Remove accidental timeout left in during earlier debugging. Has been in since two commits ago (b099f26) --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 37d2943..5126d84 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -794,7 +794,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Interlocked.Increment(ref udpClient.PacketsReceived); int now = Environment.TickCount & Int32.MaxValue; -// udpClient.TickLastPacketReceived = now; + udpClient.TickLastPacketReceived = now; #region ACK Receiving -- cgit v1.1 From c53c55fed02d02af419fb2968764fcefa5faac37 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Tue, 12 Jun 2012 17:07:10 -0400 Subject: Add variable timer configureation for the timer_Script Added "timer_Interval" to the OpenSimDefaults.ini, leaving the default value set to 1200, as the previous default setting. The value represents seconds. To change the default, copy the entry to OpenSim.ini and multiply the number of minutes for the interval by 60. --- OpenSim/Region/Application/OpenSim.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 9c38ebe..57a3c69 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -70,6 +70,7 @@ namespace OpenSim private Regex m_consolePromptRegex = new Regex(@"([^\\])\\(\w)", RegexOptions.Compiled); private string m_timedScript = "disabled"; + private int m_timeInterval = 1200; private Timer m_scriptTimer; public OpenSim(IConfigSource configSource) : base(configSource) @@ -99,6 +100,10 @@ namespace OpenSim m_consolePort = (uint)networkConfig.GetInt("console_port", 0); m_timedScript = startupConfig.GetString("timer_Script", "disabled"); + if (m_timedScript != "disabled") + { + m_timeInterval = startupConfig.GetInt("timer_Interval", 1200); + } if (m_logFileAppender != null) { @@ -216,7 +221,7 @@ namespace OpenSim { m_scriptTimer = new Timer(); m_scriptTimer.Enabled = true; - m_scriptTimer.Interval = 1200*1000; + m_scriptTimer.Interval = m_timeInterval*1000; m_scriptTimer.Elapsed += RunAutoTimerScript; } } -- cgit v1.1 From c6e375291a8fa3dbdcbd25cfb64bf0d536707fb0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Jun 2012 00:03:44 +0100 Subject: Don't include time to transmit response back to requester when assessing slow handling of requests. This is to avoid logging a 'slow' request when the source of delay is the viewer in processing a response. This is not something we can do much about on the server end - it's server-side delay that we're interested in. To ensure consistency, this commit also had to refactor and simplify inbound non-poll network request handling, though there should be no functional change. IOSHttpResponse no longer exposes the Send() method, only classes in OpenSim.Framework.Servers.HttpServer should be doing this. Only the GetTextureHandler was sending its own response. Now it leaves this to BaseHttpServer, like all other core handlers. --- .../Rest/Inventory/RestHandler.cs | 1 - .../Handlers/GetTexture/GetTextureHandler.cs | 2 - .../Framework/Servers/HttpServer/BaseHttpServer.cs | 413 ++++++--------------- .../HttpServer/Interfaces/IOSHttpResponse.cs | 8 +- .../Framework/Servers/HttpServer/OSHttpResponse.cs | 3 +- .../HttpServer/PollServiceRequestManager.cs | 6 +- .../Servers/HttpServer/PollServiceWorkerThread.cs | 53 ++- 7 files changed, 169 insertions(+), 317 deletions(-) diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs index db62d52..cb88695 100644 --- a/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs +++ b/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs @@ -539,7 +539,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory /// path has not already been registered, the method is added to the active /// handler table. /// - public void AddStreamHandler(string httpMethod, string path, RestMethod method) { if (!IsEnabled) diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index abdbc72..ae6c44b 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -77,7 +77,6 @@ namespace OpenSim.Capabilities.Handlers { m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return null; } UUID textureID; @@ -115,7 +114,6 @@ namespace OpenSim.Capabilities.Handlers // "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}", // textureID, httpResponse.StatusCode, httpResponse.ContentLength); - httpResponse.Send(); return null; } diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 401dfd3..ef6e259 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -408,7 +408,10 @@ namespace OpenSim.Framework.Servers.HttpServer string uriString = request.RawUrl; // string reqnum = "unknown"; - int tickstart = Environment.TickCount; + int requestStartTick = Environment.TickCount; + + // Will be adjusted later on. + int requestEndTick = requestStartTick; IRequestHandler requestHandler = null; @@ -433,6 +436,7 @@ namespace OpenSim.Framework.Servers.HttpServer { if (HandleAgentRequest(agentHandler, request, response)) { + requestEndTick = Environment.TickCount; return; } } @@ -442,6 +446,7 @@ namespace OpenSim.Framework.Servers.HttpServer string path = request.RawUrl; string handlerKey = GetHandlerKey(request.HttpMethod, path); + byte[] buffer = null; if (TryGetStreamHandler(handlerKey, out requestHandler)) { @@ -450,9 +455,6 @@ namespace OpenSim.Framework.Servers.HttpServer "[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}", request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description); - // Okay, so this is bad, but should be considered temporary until everything is IStreamHandler. - byte[] buffer = null; - response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type. if (requestHandler is IStreamedRequestHandler) @@ -507,8 +509,8 @@ namespace OpenSim.Framework.Servers.HttpServer //m_log.Warn("[HTTP]: " + requestBody); } - DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response); - return; + + buffer = DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response); } else { @@ -521,133 +523,100 @@ namespace OpenSim.Framework.Servers.HttpServer buffer = memoryStream.ToArray(); } } - - request.InputStream.Close(); - - // HTTP IN support. The script engine takes it from here - // Nothing to worry about for us. - // - if (buffer == null) - return; - - if (!response.SendChunked) - response.ContentLength64 = buffer.LongLength; - - try - { - response.OutputStream.Write(buffer, 0, buffer.Length); - //response.OutputStream.Close(); - } - catch (HttpListenerException) - { - m_log.WarnFormat("[BASE HTTP SERVER]: HTTP request abnormally terminated."); - } - //response.OutputStream.Close(); - try - { - response.Send(); - //response.FreeContext(); - } - catch (SocketException e) - { - // This has to be here to prevent a Linux/Mono crash - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); - } - catch (IOException e) - { - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}. ", e.Message), e); - } - - return; } - - if (request.AcceptTypes != null && request.AcceptTypes.Length > 0) + else { - foreach (string strAccept in request.AcceptTypes) + switch (request.ContentType) { - if (strAccept.Contains("application/llsd+xml") || - strAccept.Contains("application/llsd+json")) - { - if (DebugLevel >= 1) - m_log.DebugFormat( - "[BASE HTTP SERVER]: Found application/llsd+xml accept header handler for {0} {1}", - request.HttpMethod, request.Url.PathAndQuery); - - HandleLLSDRequests(request, response); - return; - } - } - } - - switch (request.ContentType) - { - case null: - case "text/html": - - if (DebugLevel >= 1) - m_log.DebugFormat( - "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", - request.ContentType, request.HttpMethod, request.Url.PathAndQuery); - - HandleHTTPRequest(request, response); - return; - - case "application/llsd+xml": - case "application/xml+llsd": - case "application/llsd+json": - - if (DebugLevel >= 1) - m_log.DebugFormat( - "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", - request.ContentType, request.HttpMethod, request.Url.PathAndQuery); - - HandleLLSDRequests(request, response); - return; - - case "text/xml": - case "application/xml": - case "application/json": - default: - //m_log.Info("[Debug BASE HTTP SERVER]: in default handler"); - // Point of note.. the DoWeHaveA methods check for an EXACT path - // if (request.RawUrl.Contains("/CAPS/EQG")) - // { - // int i = 1; - // } - //m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler"); - if (DoWeHaveALLSDHandler(request.RawUrl)) - { + case null: + case "text/html": + if (DebugLevel >= 1) m_log.DebugFormat( "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", request.ContentType, request.HttpMethod, request.Url.PathAndQuery); - - HandleLLSDRequests(request, response); - return; - } - -// m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl); - if (DoWeHaveAHTTPHandler(request.RawUrl)) - { + + buffer = HandleHTTPRequest(request, response); + break; + + case "application/llsd+xml": + case "application/xml+llsd": + case "application/llsd+json": + if (DebugLevel >= 1) m_log.DebugFormat( "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", request.ContentType, request.HttpMethod, request.Url.PathAndQuery); + + buffer = HandleLLSDRequests(request, response); + break; + + case "text/xml": + case "application/xml": + case "application/json": + default: + //m_log.Info("[Debug BASE HTTP SERVER]: in default handler"); + // Point of note.. the DoWeHaveA methods check for an EXACT path + // if (request.RawUrl.Contains("/CAPS/EQG")) + // { + // int i = 1; + // } + //m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler"); + if (DoWeHaveALLSDHandler(request.RawUrl)) + { + if (DebugLevel >= 1) + m_log.DebugFormat( + "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", + request.ContentType, request.HttpMethod, request.Url.PathAndQuery); + + buffer = HandleLLSDRequests(request, response); + } + // m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl); + else if (DoWeHaveAHTTPHandler(request.RawUrl)) + { + if (DebugLevel >= 1) + m_log.DebugFormat( + "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", + request.ContentType, request.HttpMethod, request.Url.PathAndQuery); + + buffer = HandleHTTPRequest(request, response); + } + else + { + + if (DebugLevel >= 1) + m_log.DebugFormat( + "[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}", + request.HttpMethod, request.Url.PathAndQuery); + + // generic login request. + buffer = HandleXmlRpcRequests(request, response); + } + + break; + } + } - HandleHTTPRequest(request, response); - return; - } - - if (DebugLevel >= 1) - m_log.DebugFormat( - "[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}", - request.HttpMethod, request.Url.PathAndQuery); + request.InputStream.Close(); - // generic login request. - HandleXmlRpcRequests(request, response); + if (buffer != null) + { + if (!response.SendChunked) + response.ContentLength64 = buffer.LongLength; - return; + response.OutputStream.Write(buffer, 0, buffer.Length); } + + // Do not include the time taken to actually send the response to the caller in the measurement + // time. This is to avoid logging when it's the client that is slow to process rather than the + // server + requestEndTick = Environment.TickCount; + + response.Send(); + + //response.OutputStream.Close(); + + //response.FreeContext(); } catch (SocketException e) { @@ -672,8 +641,8 @@ namespace OpenSim.Framework.Servers.HttpServer finally { // Every month or so this will wrap and give bad numbers, not really a problem - // since its just for reporting, tickdiff limit can be adjusted - int tickdiff = Environment.TickCount - tickstart; + // since its just for reporting + int tickdiff = requestEndTick - requestStartTick; if (tickdiff > 3000) { m_log.InfoFormat( @@ -805,7 +774,7 @@ namespace OpenSim.Framework.Servers.HttpServer ///
/// /// - private void HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response) + private byte[] HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response) { Stream requestStream = request.InputStream; @@ -817,7 +786,7 @@ namespace OpenSim.Framework.Servers.HttpServer requestStream.Close(); //m_log.Debug(requestBody); requestBody = requestBody.Replace("", ""); - string responseString = String.Empty; + string responseString = null; XmlRpcRequest xmlRprcRequest = null; try @@ -895,6 +864,7 @@ namespace OpenSim.Framework.Servers.HttpServer String.Format("Requested method [{0}] not found", methodName)); } + response.ContentType = "text/xml"; responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse); } else @@ -904,82 +874,25 @@ namespace OpenSim.Framework.Servers.HttpServer response.StatusCode = 404; response.StatusDescription = "Not Found"; response.ProtocolVersion = "HTTP/1.0"; - byte[] buf = Encoding.UTF8.GetBytes("Not found"); + responseString = "Not found"; response.KeepAlive = false; m_log.ErrorFormat( "[BASE HTTP SERVER]: Handler not found for http request {0} {1}", request.HttpMethod, request.Url.PathAndQuery); - - response.SendChunked = false; - response.ContentLength64 = buf.Length; - response.ContentEncoding = Encoding.UTF8; - - try - { - response.OutputStream.Write(buf, 0, buf.Length); - } - catch (Exception ex) - { - m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message); - } - finally - { - try - { - response.Send(); - //response.FreeContext(); - } - catch (SocketException e) - { - // This has to be here to prevent a Linux/Mono crash - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); - } - catch (IOException e) - { - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0} ", e.Message), e); - } - } - return; - //responseString = "Error"; } } - response.ContentType = "text/xml"; - byte[] buffer = Encoding.UTF8.GetBytes(responseString); response.SendChunked = false; response.ContentLength64 = buffer.Length; response.ContentEncoding = Encoding.UTF8; - try - { - response.OutputStream.Write(buffer, 0, buffer.Length); - } - catch (Exception ex) - { - m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message); - } - finally - { - try - { - response.Send(); - //response.FreeContext(); - } - catch (SocketException e) - { - // This has to be here to prevent a Linux/Mono crash - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); - } - catch (IOException e) - { - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0} ", e.Message), e); - } - } + + return buffer; } - private void HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response) + private byte[] HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response) { //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request"); Stream requestStream = request.InputStream; @@ -1065,34 +978,7 @@ namespace OpenSim.Framework.Servers.HttpServer response.ContentEncoding = Encoding.UTF8; response.KeepAlive = true; - try - { - response.OutputStream.Write(buffer, 0, buffer.Length); - } - catch (Exception ex) - { - m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message); - } - finally - { - //response.OutputStream.Close(); - try - { - response.Send(); - response.OutputStream.Flush(); - //response.FreeContext(); - //response.OutputStream.Close(); - } - catch (IOException e) - { - m_log.Warn(String.Format("[BASE HTTP SERVER]: LLSD IOException {0} ", e.Message), e); - } - catch (SocketException e) - { - // This has to be here to prevent a Linux/Mono crash - m_log.Warn(String.Format("[BASE HTTP SERVER]: LLSD issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); - } - } + return buffer; } private byte[] BuildLLSDResponse(OSHttpRequest request, OSHttpResponse response, OSD llsdResponse) @@ -1357,7 +1243,7 @@ namespace OpenSim.Framework.Servers.HttpServer } - public void HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response) + public byte[] HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response) { // m_log.DebugFormat( // "[BASE HTTP SERVER]: HandleHTTPRequest for request to {0}, method {1}", @@ -1367,15 +1253,14 @@ namespace OpenSim.Framework.Servers.HttpServer { case "OPTIONS": response.StatusCode = (int)OSHttpStatusCode.SuccessOk; - return; + return null; default: - HandleContentVerbs(request, response); - return; + return HandleContentVerbs(request, response); } } - private void HandleContentVerbs(OSHttpRequest request, OSHttpResponse response) + private byte[] HandleContentVerbs(OSHttpRequest request, OSHttpResponse response) { // m_log.DebugFormat("[BASE HTTP SERVER]: HandleContentVerbs for request to {0}", request.RawUrl); @@ -1391,6 +1276,8 @@ namespace OpenSim.Framework.Servers.HttpServer // to display the form, or process it. // a better way would be nifty. + byte[] buffer; + Stream requestStream = request.InputStream; Encoding encoding = Encoding.UTF8; @@ -1451,14 +1338,14 @@ namespace OpenSim.Framework.Servers.HttpServer if (foundHandler) { Hashtable responsedata1 = requestprocessor(keysvals); - DoHTTPGruntWork(responsedata1,response); + buffer = DoHTTPGruntWork(responsedata1,response); //SendHTML500(response); } else { // m_log.Warn("[BASE HTTP SERVER]: Handler Not Found"); - SendHTML404(response, host); + buffer = SendHTML404(response, host); } } else @@ -1468,16 +1355,18 @@ namespace OpenSim.Framework.Servers.HttpServer if (foundHandler) { Hashtable responsedata2 = requestprocessor(keysvals); - DoHTTPGruntWork(responsedata2, response); + buffer = DoHTTPGruntWork(responsedata2, response); //SendHTML500(response); } else { // m_log.Warn("[BASE HTTP SERVER]: Handler Not Found2"); - SendHTML404(response, host); + buffer = SendHTML404(response, host); } } + + return buffer; } private bool TryGetHTTPHandlerPathBased(string path, out GenericHTTPMethod httpHandler) @@ -1545,14 +1434,13 @@ namespace OpenSim.Framework.Servers.HttpServer } } - internal void DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response) + internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response) { //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response"); int responsecode = (int)responsedata["int_response_code"]; string responseString = (string)responsedata["str_response_string"]; string contentType = (string)responsedata["content_type"]; - if (responsedata.ContainsKey("error_status_text")) { response.StatusDescription = (string)responsedata["error_status_text"]; @@ -1616,38 +1504,10 @@ namespace OpenSim.Framework.Servers.HttpServer response.ContentLength64 = buffer.Length; response.ContentEncoding = Encoding.UTF8; - try - { - response.OutputStream.Write(buffer, 0, buffer.Length); - } - catch (Exception ex) - { - m_log.Warn("[HTTPD]: Error - " + ex.Message); - } - finally - { - //response.OutputStream.Close(); - try - { - response.OutputStream.Flush(); - response.Send(); - - //if (!response.KeepAlive && response.ReuseContext) - // response.FreeContext(); - } - catch (SocketException e) - { - // This has to be here to prevent a Linux/Mono crash - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); - } - catch (IOException e) - { - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0} ", e.Message), e); - } - } + return buffer; } - public void SendHTML404(OSHttpResponse response, string host) + public byte[] SendHTML404(OSHttpResponse response, string host) { // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s response.StatusCode = 404; @@ -1660,31 +1520,10 @@ namespace OpenSim.Framework.Servers.HttpServer response.ContentLength64 = buffer.Length; response.ContentEncoding = Encoding.UTF8; - try - { - response.OutputStream.Write(buffer, 0, buffer.Length); - } - catch (Exception ex) - { - m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message); - } - finally - { - //response.OutputStream.Close(); - try - { - response.Send(); - //response.FreeContext(); - } - catch (SocketException e) - { - // This has to be here to prevent a Linux/Mono crash - m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); - } - } + return buffer; } - public void SendHTML500(OSHttpResponse response) + public byte[] SendHTML500(OSHttpResponse response) { // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s response.StatusCode = (int)OSHttpStatusCode.SuccessOk; @@ -1696,28 +1535,8 @@ namespace OpenSim.Framework.Servers.HttpServer response.SendChunked = false; response.ContentLength64 = buffer.Length; response.ContentEncoding = Encoding.UTF8; - try - { - response.OutputStream.Write(buffer, 0, buffer.Length); - } - catch (Exception ex) - { - m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message); - } - finally - { - //response.OutputStream.Close(); - try - { - response.Send(); - //response.FreeContext(); - } - catch (SocketException e) - { - // This has to be here to prevent a Linux/Mono crash - m_log.Warn(String.Format("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e); - } - } + + return buffer; } public void Start() diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs index 33a1663..f61b090 100644 --- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs +++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs @@ -128,11 +128,5 @@ namespace OpenSim.Framework.Servers.HttpServer /// string containing the header field /// value void AddHeader(string key, string value); - - /// - /// Send the response back to the remote client - /// - void Send(); } -} - +} \ No newline at end of file diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs index f9227ac..89fb5d4 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs @@ -321,13 +321,12 @@ namespace OpenSim.Framework.Servers.HttpServer { _httpResponse.Body.Flush(); _httpResponse.Send(); - } + public void FreeContext() { if (_httpClientContext != null) _httpClientContext.Close(); } - } } \ No newline at end of file diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index f96fd1f..3252251 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs @@ -140,9 +140,8 @@ namespace OpenSim.Framework.Servers.HttpServer foreach (object o in m_requests) { PollServiceHttpRequest req = (PollServiceHttpRequest) o; - m_server.DoHTTPGruntWork( - req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id), - new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext)); + PollServiceWorkerThread.DoHTTPGruntWork( + m_server, req, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); } m_requests.Clear(); @@ -151,6 +150,7 @@ namespace OpenSim.Framework.Servers.HttpServer { t.Abort(); } + m_running = false; } } diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs index 5e171f0..2995421 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs @@ -90,15 +90,16 @@ namespace OpenSim.Framework.Servers.HttpServer } Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd()); - m_server.DoHTTPGruntWork(responsedata, - new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request),req.HttpContext)); + DoHTTPGruntWork(m_server, req, responsedata); } else { if ((Environment.TickCount - req.RequestTime) > m_timeout) { - m_server.DoHTTPGruntWork(req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id), - new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request),req.HttpContext)); + DoHTTPGruntWork( + m_server, + req, + req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); } else { @@ -119,5 +120,47 @@ namespace OpenSim.Framework.Servers.HttpServer { m_request.Enqueue(pPollServiceHttpRequest); } + + /// + /// FIXME: This should be part of BaseHttpServer + /// + internal static void DoHTTPGruntWork(BaseHttpServer server, PollServiceHttpRequest req, Hashtable responsedata) + { + OSHttpResponse response + = new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext); + + byte[] buffer + = server.DoHTTPGruntWork( + responsedata, new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext)); + + response.SendChunked = false; + response.ContentLength64 = buffer.Length; + response.ContentEncoding = Encoding.UTF8; + + try + { + response.OutputStream.Write(buffer, 0, buffer.Length); + } + catch (Exception ex) + { + m_log.Warn(string.Format("[POLL SERVICE WORKER THREAD]: Error ", ex)); + } + finally + { + //response.OutputStream.Close(); + try + { + response.OutputStream.Flush(); + response.Send(); + + //if (!response.KeepAlive && response.ReuseContext) + // response.FreeContext(); + } + catch (Exception e) + { + m_log.Warn(String.Format("[POLL SERVICE WORKER THREAD]: Error ", e)); + } + } + } } -} +} \ No newline at end of file -- cgit v1.1 From 4e18e71089eb1ef84bad8f09dd4a9d18f09bec5e Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 13 Jun 2012 02:32:25 +0100 Subject: Committing the Avination implementation of llCastRay. This is a complete rewrite wich does it's thing independently of physics. Enjoy! --- .../Shared/Api/Implementation/LSL_Api.cs | 445 ++++++++++++++++----- 1 file changed, 345 insertions(+), 100 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 89f2068..a8679e2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10781,155 +10781,400 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return rq.ToString(); } + private struct Tri + { + public Vector3 p1; + public Vector3 p2; + public Vector3 p3; + } + + private bool InBoundingBox(ScenePresence avatar, Vector3 point) + { + float height = avatar.Appearance.AvatarHeight; + Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2); + Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2); + + if (point.X > b1.X && point.X < b2.X && + point.Y > b1.Y && point.Y < b2.Y && + point.Z > b1.Z && point.Z < b2.Z) + return true; + return false; + } + + private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd) + { + List contacts = new List(); + + Vector3 ab = rayEnd - rayStart; + + World.ForEachScenePresence(delegate(ScenePresence sp) + { + Vector3 ac = sp.AbsolutePosition - rayStart; + Vector3 bc = sp.AbsolutePosition - rayEnd; + + double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); + + if (d > 1.5) + return; + + double d2 = Vector3.Dot(Vector3.Negate(ab), ac); + + if (d2 > 0) + return; + + double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d); + Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab)); + + if (!InBoundingBox(sp, p)) + return; + + ContactResult result = new ContactResult (); + result.ConsumerID = sp.LocalId; + result.Depth = Vector3.Distance(rayStart, p); + result.Normal = Vector3.Zero; + result.Pos = p; + + contacts.Add(result); + }); + + return contacts.ToArray(); + } + + private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom) + { + Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart)); + List contacts = new List(); + + Vector3 ab = rayEnd - rayStart; + + World.ForEachSOG(delegate(SceneObjectGroup group) + { + if (m_host.ParentGroup == group) + return; + + if (group.IsAttachment) + return; + + if (group.RootPart.PhysActor == null) + { + if (!includePhantom) + return; + } + else + { + if (group.RootPart.PhysActor.IsPhysical) + { + if (!includePhysical) + return; + } + else + { + if (!includeNonPhysical) + return; + } + } + + // Find the radius ouside of which we don't even need to hit test + float minX; + float maxX; + float minY; + float maxY; + float minZ; + float maxZ; + + float radius = 0.0f; + + group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ); + + if (Math.Abs(minX) > radius) + radius = Math.Abs(minX); + if (Math.Abs(minY) > radius) + radius = Math.Abs(minY); + if (Math.Abs(minZ) > radius) + radius = Math.Abs(minZ); + if (Math.Abs(maxX) > radius) + radius = Math.Abs(maxX); + if (Math.Abs(maxY) > radius) + radius = Math.Abs(maxY); + if (Math.Abs(maxZ) > radius) + radius = Math.Abs(maxZ); + + Vector3 ac = group.AbsolutePosition - rayStart; + Vector3 bc = group.AbsolutePosition - rayEnd; + + double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); + + // Too far off ray, don't bother + if (d > radius) + return; + + // Behind ray, drop + double d2 = Vector3.Dot(Vector3.Negate(ab), ac); + if (d2 > 0) + return; + + EntityIntersection intersection = group.TestIntersection(ray, true, false); + // Miss. + if (!intersection.HitTF) + return; + + ContactResult result = new ContactResult (); + result.ConsumerID = group.LocalId; + result.Depth = intersection.distance; + result.Normal = intersection.normal; + result.Pos = intersection.ipoint; + + contacts.Add(result); + }); + + return contacts.ToArray(); + } + + private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd) + { + double[,] heightfield = World.Heightmap.GetDoubles(); + List contacts = new List(); + + double min = 2048.0; + double max = 0.0; + + // Find the min and max of the heightfield + for (int x = 0 ; x < World.Heightmap.Width ; x++) + { + for (int y = 0 ; y < World.Heightmap.Height ; y++) + { + if (heightfield[x, y] > max) + max = heightfield[x, y]; + if (heightfield[x, y] < min) + min = heightfield[x, y]; + } + } + + + // A ray extends past rayEnd, but doesn't go back before + // rayStart. If the start is above the highest point of the ground + // and the ray goes up, we can't hit the ground. Ever. + if (rayStart.Z > max && rayEnd.Z >= rayStart.Z) + return null; + + // Same for going down + if (rayStart.Z < min && rayEnd.Z <= rayStart.Z) + return null; + + List trilist = new List(); + + // Create our triangle list + for (int x = 1 ; x < World.Heightmap.Width ; x++) + { + for (int y = 1 ; y < World.Heightmap.Height ; y++) + { + Tri t1 = new Tri(); + Tri t2 = new Tri(); + + Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]); + Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]); + Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]); + Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]); + + t1.p1 = p1; + t1.p2 = p2; + t1.p3 = p3; + + t2.p1 = p3; + t2.p2 = p4; + t2.p3 = p1; + + trilist.Add(t1); + trilist.Add(t2); + } + } + + // Ray direction + Vector3 rayDirection = rayEnd - rayStart; + + foreach (Tri t in trilist) + { + // Compute triangle plane normal and edges + Vector3 u = t.p2 - t.p1; + Vector3 v = t.p3 - t.p1; + Vector3 n = Vector3.Cross(u, v); + + if (n == Vector3.Zero) + continue; + + Vector3 w0 = rayStart - t.p1; + double a = -Vector3.Dot(n, w0); + double b = Vector3.Dot(n, rayDirection); + + // Not intersecting the plane, or in plane (same thing) + // Ignoring this MAY cause the ground to not be detected + // sometimes + if (Math.Abs(b) < 0.000001) + continue; + + double r = a / b; + + // ray points away from plane + if (r < 0.0) + continue; + + Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r); + + float uu = Vector3.Dot(u, u); + float uv = Vector3.Dot(u, v); + float vv = Vector3.Dot(v, v); + Vector3 w = ip - t.p1; + float wu = Vector3.Dot(w, u); + float wv = Vector3.Dot(w, v); + float d = uv * uv - uu * vv; + + float cs = (uv * wv - vv * wu) / d; + if (cs < 0 || cs > 1.0) + continue; + float ct = (uv * wu - uu * wv) / d; + if (ct < 0 || (cs + ct) > 1.0) + continue; + + // Add contact point + ContactResult result = new ContactResult (); + result.ConsumerID = 0; + result.Depth = Vector3.Distance(rayStart, ip); + result.Normal = n; + result.Pos = ip; + + contacts.Add(result); + } + + if (contacts.Count == 0) + return null; + + contacts.Sort(delegate(ContactResult a, ContactResult b) + { + return (int)(a.Depth - b.Depth); + }); + + return contacts[0]; + } + public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) { + LSL_List list = new LSL_List(); + m_host.AddScriptLPS(1); - Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); - Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); - Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); + Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z); + Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z); + Vector3 dir = rayEnd - rayStart; - int count = 0; -// int detectPhantom = 0; + float dist = Vector3.Mag(dir); + + int count = 1; + bool detectPhantom = false; int dataFlags = 0; int rejectTypes = 0; for (int i = 0; i < options.Length; i += 2) { if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) - { count = options.GetLSLIntegerItem(i + 1); - } -// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) -// { -// detectPhantom = options.GetLSLIntegerItem(i + 1); -// } + else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) + detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0); else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) - { dataFlags = options.GetLSLIntegerItem(i + 1); - } else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) - { rejectTypes = options.GetLSLIntegerItem(i + 1); - } } - LSL_List list = new LSL_List(); - List results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); - - double distance = Util.GetDistanceTo(startvector, endvector); + if (count > 16) + count = 16; - if (distance == 0) - distance = 0.001; - - Vector3 posToCheck = startvector; - ITerrainChannel channel = World.RequestModuleInterface(); + List results = new List(); bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); - for (float i = 0; i <= distance; i += 0.1f) + + if (checkTerrain) { - posToCheck = startvector + (dir * (i / (float)distance)); + ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); + if (groundContact != null) + results.Add((ContactResult)groundContact); + } - if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) - { - ContactResult result = new ContactResult(); - result.ConsumerID = 0; - result.Depth = 0; - result.Normal = Vector3.Zero; - result.Pos = posToCheck; - results.Add(result); - checkTerrain = false; - } + if (checkAgents) + { + ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); + foreach (ContactResult r in agentHits) + results.Add(r); + } - if (checkAgents) - { - World.ForEachRootScenePresence(delegate(ScenePresence sp) - { - if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X)) - { - ContactResult result = new ContactResult (); - result.ConsumerID = sp.LocalId; - result.Depth = 0; - result.Normal = Vector3.Zero; - result.Pos = posToCheck; - results.Add(result); - } - }); - } + if (checkPhysical || checkNonPhysical || detectPhantom) + { + ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); + foreach (ContactResult r in objectHits) + results.Add(r); } - int refcount = 0; + results.Sort(delegate(ContactResult a, ContactResult b) + { + return a.Depth.CompareTo(b.Depth); + }); + + int values = 0; + SceneObjectGroup thisgrp = m_host.ParentGroup; + foreach (ContactResult result in results) { - if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) - == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0) + if (result.Depth > dist) continue; - ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID); + // physics ray can return colisions with host prim + if (m_host.LocalId == result.ConsumerID) + continue; - if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS) - entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents + UUID itemID = UUID.Zero; + int linkNum = 0; - if (entity == null) + SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID); + // It's a prim! + if (part != null) { - list.Add(UUID.Zero); - - if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) - list.Add(0); + // dont detect members of same object ??? + if (part.ParentGroup == thisgrp) + continue; - list.Add(result.Pos); - - if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) - list.Add(result.Normal); + if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY) + itemID = part.ParentGroup.UUID; + else + itemID = part.UUID; - continue; //Can't find it, so add UUID.Zero + linkNum = part.LinkNum; } - - /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity && - ((ISceneChildEntity)intersection.obj).PhysActor == null) - continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects - - if (entity is SceneObjectPart) + else { - PhysicsActor pa = ((SceneObjectPart)entity).PhysActor; - - if (pa != null && pa.IsPhysical) - { - if (!checkPhysical) - continue; - } - else - { - if (!checkNonPhysical) - continue; - } + ScenePresence sp = World.GetScenePresence(result.ConsumerID); + /// It it a boy? a girl? + if (sp != null) + itemID = sp.UUID; } - refcount++; - if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) - list.Add(((SceneObjectPart)entity).ParentGroup.UUID); - else - list.Add(entity.UUID); + list.Add(new LSL_String(itemID.ToString())); + list.Add(new LSL_String(result.Pos.ToString())); if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) - { - if (entity is SceneObjectPart) - list.Add(((SceneObjectPart)entity).LinkNum); - else - list.Add(0); - } - - list.Add(result.Pos); + list.Add(new LSL_Integer(linkNum)); if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) - list.Add(result.Normal); + list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z)); + + values++; + if (values >= count) + break; } - list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED + list.Add(new LSL_Integer(values)); return list; } -- cgit v1.1 From 7c0843aad196f9198fd59605e1bbecee141ed067 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Tue, 12 Jun 2012 21:52:52 -0400 Subject: Add the updated OpenSimDefaults.ini for the prior timer_Interval patch. --- bin/OpenSimDefaults.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 0e1a3af..1b8a4b6 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -33,6 +33,10 @@ ; Console commands run every 20 minutes ; timer_Script = "filename" + ; timer_Script time interval (default 20 min) + ; The time is 60 per minute + ; timer_Interval = 1200 + ; ## ; ## SYSTEM ; ## -- cgit v1.1 From 5145356467244d6a4d66cd36eef22a23d6fc73a1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Jun 2012 03:49:22 +0100 Subject: Add "deregister region" by uuid command to grid service to allow manual deregistration of simulators. Useful if a simulator has crashed without removing its regions and those regions have been reconfigured differently --- OpenSim/Services/GridService/GridService.cs | 45 +++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index 8a60ca5..11897f8 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -85,6 +85,13 @@ namespace OpenSim.Services.GridService if (MainConsole.Instance != null) { MainConsole.Instance.Commands.AddCommand("Regions", true, + "deregister region", + "deregister region ", + "Deregister a region manually.", + String.Empty, + HandleDeregisterRegion); + + MainConsole.Instance.Commands.AddCommand("Regions", true, "show region", "show region ", "Show details on a region", @@ -495,6 +502,44 @@ namespace OpenSim.Services.GridService return -1; } + private void HandleDeregisterRegion(string module, string[] cmd) + { + if (cmd.Length != 3) + { + MainConsole.Instance.Output("Syntax: degregister region "); + return; + } + + string rawRegionUuid = cmd[2]; + UUID regionUuid; + + if (!UUID.TryParse(rawRegionUuid, out regionUuid)) + { + MainConsole.Instance.OutputFormat("{0} is not a valid region uuid", rawRegionUuid); + return; + } + + GridRegion region = GetRegionByUUID(UUID.Zero, regionUuid); + + if (region == null) + { + MainConsole.Instance.OutputFormat("No region with UUID {0}", regionUuid); + return; + } + + if (DeregisterRegion(regionUuid)) + { + MainConsole.Instance.OutputFormat("Deregistered {0} {1}", region.RegionName, regionUuid); + } + else + { + // I don't think this can ever occur if we know that the region exists. + MainConsole.Instance.OutputFormat("Error deregistering {0} {1}", region.RegionName, regionUuid); + } + + return; + } + private void HandleShowRegion(string module, string[] cmd) { if (cmd.Length != 3) -- cgit v1.1 From 1f34c8277d2584f0b43a43555f8b0abded4a1aa4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Jun 2012 04:05:02 +0100 Subject: In the osGetGrid functions, if the [GridInfo] section does not exist then return "Configuration Error", as already happens if there is no GridInfoURI --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 7ea8b7a..7fa25f5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -1965,7 +1965,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { string retval = String.Empty; IConfigSource config = m_ScriptEngine.ConfigSource; - string url = config.Configs["GridInfo"].GetString("GridInfoURI", String.Empty); + string url = null; + + IConfig gridInfoConfig = config.Configs["GridInfo"]; + + if (gridInfoConfig != null) + url = gridInfoConfig.GetString("GridInfoURI", String.Empty); if (String.IsNullOrEmpty(url)) return "Configuration Error!"; -- cgit v1.1 From f726150afdf3fd85f3ec08585fd84f75b5852e79 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Jun 2012 23:39:23 +0100 Subject: Add ObjectUpdate as one of the packets that can be screened out when setting debug packet level --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index c4f167e..ad39b50 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -11650,7 +11650,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (DebugPacketLevel <= 100 && (packet.Type == PacketType.AvatarAnimation || packet.Type == PacketType.ViewerEffect)) logPacket = false; - if (DebugPacketLevel <= 50 && packet.Type == PacketType.ImprovedTerseObjectUpdate) + if (DebugPacketLevel <= 50 + & (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate)) logPacket = false; if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily) -- cgit v1.1 From cf080a68d657e082dd61dacc24ffd17240154e90 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Jun 2012 23:42:22 +0100 Subject: Remove long obsolete and unused IClientAPI.KillEndDone() --- OpenSim/Framework/IClientAPI.cs | 2 -- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 4 ---- .../Agent/InternetRelayClientView/Server/IRCClientView.cs | 5 ----- OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | 4 ---- OpenSim/Tests/Common/Mock/TestClient.cs | 4 ---- 5 files changed, 19 deletions(-) diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 2ea6de5..4cc2e2c 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -1414,8 +1414,6 @@ namespace OpenSim.Framework void SendGroupVoteHistory(UUID groupID, UUID transactionID, GroupVoteHistory[] Votes); - void KillEndDone(); - bool AddGenericPacketHandler(string MethodName, GenericMessage handler); void SendRebakeAvatarTextures(UUID textureID); diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index ad39b50..4e0dadb 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -11861,10 +11861,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP return string.Empty; } - public void KillEndDone() - { - } - #region IClientCore private readonly Dictionary m_clientInterfaces = new Dictionary(); diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 43548e6..3a32528 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -1626,11 +1626,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server } - public void KillEndDone() - { - - } - public bool AddGenericPacketHandler(string MethodName, GenericMessage handler) { return true; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index e57e5e6..b3e1069 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -1044,10 +1044,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } - public void KillEndDone() - { - } - public void SendEventInfoReply (EventData info) { } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 36049a1..376465c 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -1123,10 +1123,6 @@ namespace OpenSim.Tests.Common.Mock { } - public void KillEndDone() - { - } - public void SendEventInfoReply (EventData info) { } -- cgit v1.1 From 16ffc764bf57dcc85461f2e5c6457ee8237e78c9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Jun 2012 23:54:32 +0100 Subject: minor: refactor part of LLClientView.ProcessEntityUpdates() to remove duplicate code --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 4e0dadb..85d83f8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3780,16 +3780,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (!canUseImproved && !canUseCompressed) { + ObjectUpdatePacket.ObjectDataBlock updateBlock; + if (update.Entity is ScenePresence) { - objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); - objectUpdates.Value.Add(update); + updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity); } else { - objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); - objectUpdates.Value.Add(update); + updateBlock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, AgentId); } + + objectUpdateBlocks.Value.Add(updateBlock); + objectUpdates.Value.Add(update); } else if (!canUseImproved) { @@ -3814,7 +3817,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion Block Construction } - #region Packet Sending ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); -- cgit v1.1 From 6a77a656753fd5433cbb105649b8dd1e3cf83337 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Jun 2012 00:35:26 +0100 Subject: minor: remove unnecessary IsAttachment = false setting for new object in UploadObjectAssetModule, property always starts as false --- .../Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs index f0f3984..ba902b2 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs @@ -333,7 +333,6 @@ namespace OpenSim.Region.ClientStack.Linden grp.AbsolutePosition = obj.Position; prim.RotationOffset = obj.Rotation; - grp.IsAttachment = false; // Required for linking grp.RootPart.ClearUpdateSchedule(); -- cgit v1.1 From cba8b4f8b8c2566426216e395561cdf4ae49c72e Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 6 Jun 2012 20:35:00 +0200 Subject: Fix not sending TransferInfo when an asset is not found. This clogs up the sound pipeline in the viewer. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 33 +++++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 85d83f8..8f55208 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -2719,6 +2719,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + public void SendAssetNotFound(AssetRequestToClient req) + { + TransferInfoPacket Transfer = new TransferInfoPacket(); + Transfer.TransferInfo.ChannelType = 2; + Transfer.TransferInfo.Status = -2; + Transfer.TransferInfo.TargetType = 0; + Transfer.TransferInfo.Params = req.Params; + Transfer.TransferInfo.Size = 0; + Transfer.TransferInfo.TransferID = req.TransferRequestID; + Transfer.Header.Zerocoded = true; + OutPacket(Transfer, ThrottleOutPacketType.Asset); + } + public void SendTexture(AssetBase TextureAsset) { @@ -11980,14 +11993,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// protected void AssetReceived(string id, Object sender, AssetBase asset) { - if (asset == null) - return; - TransferRequestPacket transferRequest = (TransferRequestPacket)sender; UUID requestID = UUID.Zero; byte source = (byte)SourceType.Asset; + AssetRequestToClient req = new AssetRequestToClient(); + + if (asset == null) + { + req.AssetInf = null; + req.AssetRequestSource = source; + req.IsTextureRequest = false; + req.NumPackets = 0; + req.Params = transferRequest.TransferInfo.Params; + req.RequestAssetID = requestID; + req.TransferRequestID = transferRequest.TransferInfo.TransferID; + + SendAssetNotFound(req); + return; + } + if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset) { requestID = new UUID(transferRequest.TransferInfo.Params, 0); @@ -12004,7 +12030,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP return; // The asset is known to exist and is in our cache, so add it to the AssetRequests list - AssetRequestToClient req = new AssetRequestToClient(); req.AssetInf = asset; req.AssetRequestSource = source; req.IsTextureRequest = false; -- cgit v1.1 From a4290048e5333d34910fd8c4dfd6cb9b5819d1c1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Jun 2012 01:12:16 +0100 Subject: Add SOG.HasPrivateAttachmentPoint to tell if a SOG has a private attachment point. HUDs attachment points are private. Change SOP.SendFullUpdateToClient() and SoundModule.PlayAttachedSound() to use this rather than different magic number formulations. This also corrects a bug in PlayAttachedSound() where the code assumed that all attachment points over 30 were HUDs. It appears this is no longer true with Neck and Root (Avatar Center) --- OpenSim/Region/CoreModules/World/Sound/SoundModule.cs | 7 ++----- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 16 ++++++++++++++++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 5 +++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index 93b1005..d768a1a 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs @@ -78,11 +78,8 @@ namespace OpenSim.Region.CoreModules.World.Sound if (grp.IsAttachment) { - if (grp.AttachmentPoint > 30) // HUD - { - if (sp.ControllingClient.AgentId != grp.OwnerID) - return; - } + if (grp.HasPrivateAttachmentPoint && sp.ControllingClient.AgentId != grp.OwnerID) + return; if (sp.ControllingClient.AgentId == grp.OwnerID) dis = 0; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 20d7a01..619296e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -180,6 +180,22 @@ namespace OpenSim.Region.Framework.Scenes } } + /// + /// If this scene object has an attachment point then indicate whether there is a point where + /// attachments are perceivable by avatars other than the avatar to which this object is attached. + /// + /// + /// HUDs are not perceivable by other avatars. + /// + public bool HasPrivateAttachmentPoint + { + get + { + return AttachmentPoint >= (uint)OpenMetaverse.AttachmentPoint.HUDCenter2 + && AttachmentPoint <= (uint)OpenMetaverse.AttachmentPoint.HUDBottomRight; + } + } + public void ClearPartAttachmentData() { AttachmentPoint = 0; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 17c7661..7640fc0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2573,8 +2573,9 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup.IsDeleted) return; - if (ParentGroup.IsAttachment && (ParentGroup.AttachedAvatar != remoteClient.AgentId) && - (ParentGroup.AttachmentPoint >= 31) && (ParentGroup.AttachmentPoint <= 38)) + if (ParentGroup.IsAttachment + && ParentGroup.AttachedAvatar != remoteClient.AgentId + && ParentGroup.HasPrivateAttachmentPoint) return; if (remoteClient.AgentId == OwnerID) -- cgit v1.1 From 917d753f1c1474b4ed3f905d8dd95db2e0e2fc9e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Jun 2012 01:36:37 +0100 Subject: Fix a race condition where an object update for a hud could be sent to non-owner avatars if the hud was attached directly from within the region. If this happens, then the non-owners would see unremovable huds that they did not own until relog, and sometimes even beyond that. This was due to a race between the entity update and the attachment code when moving an object from within scene to a hud. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 27 +++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 85d83f8..83e49f3 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3722,8 +3722,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - ++updatesThisCall; - #region UpdateFlags to packet type conversion PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; @@ -3788,7 +3786,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { - updateBlock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, AgentId); + SceneObjectPart part = (SceneObjectPart)update.Entity; + updateBlock = CreatePrimUpdateBlock(part, AgentId); + + // If the part has become a private hud since the update was scheduled then we do not + // want to send it to other avatars. + if (part.ParentGroup.IsAttachment + && part.ParentGroup.HasPrivateAttachmentPoint + && part.ParentGroup.AttachedAvatar != AgentId) + continue; } objectUpdateBlocks.Value.Add(updateBlock); @@ -3811,6 +3817,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP { // Everything else goes here terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); + + if (update.Entity is SceneObjectPart) + { + SceneObjectPart part = (SceneObjectPart)update.Entity; + + // If the part has become a private hud since the update was scheduled then we do not + // want to send it to other avatars. + if (part.ParentGroup.IsAttachment + && part.ParentGroup.HasPrivateAttachmentPoint + && part.ParentGroup.AttachedAvatar != AgentId) + continue; + } + terseUpdates.Value.Add(update); } } @@ -3880,6 +3899,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP // If any of the packets created from this call go unacknowledged, all of the updates will be resent OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); } + + ++updatesThisCall; } #endregion Packet Sending -- cgit v1.1 From 3c3ea196201b56407ccf6c21229064f7954c716d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Jun 2012 02:26:38 +0100 Subject: Fix a bug where scene objects attached as HUDs through scripts would not disappear for other avatars. We do this by sending a kill message for that object to all other avatars apart from the one that has the hud. --- .../CoreModules/Avatar/Attachments/AttachmentsModule.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 88071f6..d47b1ab 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -562,6 +562,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { m_scene.SendKillObject(new List { so.RootPart.LocalId }); } + else if (so.HasPrivateAttachmentPoint) + { +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}", +// so.Name, sp.Name, so.AttachmentPoint); + + // Remove the client from everyone in the + m_scene.ForEachClient( + client => + { if (client.AgentId != so.AttachedAvatar) + client.SendKillObject(m_scene.RegionInfo.RegionHandle, new List() { so.LocalId }); + }); + } so.IsSelected = false; // fudge.... so.ScheduleGroupForFullUpdate(); -- cgit v1.1 From 1aa746925314dea88ab18cef6cb91072993f1bd3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Jun 2012 02:30:40 +0100 Subject: correct wrong incomplete comment from previous commit 3c3ea19 in AttachmentsModule --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index d47b1ab..b74c0ba 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -568,7 +568,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}", // so.Name, sp.Name, so.AttachmentPoint); - // Remove the client from everyone in the + // As this scene object can now only be seen by the attaching avatar, tell everybody else in the + // scene that it's no longer in their awareness. m_scene.ForEachClient( client => { if (client.AgentId != so.AttachedAvatar) -- cgit v1.1 From 3888b9a670656cbcdcb5e6cd46365927a1888f27 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Jun 2012 03:32:44 +0100 Subject: If we're going to discard a terse update block because it's now someone else's hud, then don't still add it to the list of blocks for the update message. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 9f32c33..4ea977e 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3828,9 +3828,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { - // Everything else goes here - terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); + ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock + = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)); + // Everything else goes here if (update.Entity is SceneObjectPart) { SceneObjectPart part = (SceneObjectPart)update.Entity; @@ -3843,6 +3844,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP continue; } + terseUpdateBlocks.Value.Add(terseUpdateBlock); terseUpdates.Value.Add(update); } } -- cgit v1.1 From 2c6555021fdcf5dcd08a19d41412acf20f514b14 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Jun 2012 03:49:54 +0100 Subject: Fix very recent regression in 917d753 where I put the ++updatesThisCall outside the batching part of ProcessEntityUpdates() This stopped any batching happening and since this method is called periodically updates were sent very slowly --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 4ea977e..4cb7a3a 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3848,6 +3848,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP terseUpdates.Value.Add(update); } } + + ++updatesThisCall; #endregion Block Construction } @@ -3914,8 +3916,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP // If any of the packets created from this call go unacknowledged, all of the updates will be resent OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); } - - ++updatesThisCall; } #endregion Packet Sending -- cgit v1.1 From f4b02f8e39b9e437a5f5ce4ffc307354fa39bd39 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Jun 2012 04:29:15 +0100 Subject: Fix a regression in BaseHttpServer.HandleXmlRpcRequests() from recent c6e3752 Accidentally make responseString null by default instead of String.Empty. It needs to be something in case the XmlRpcRequest deserialize throws an exception due to bad xml (a failure which we silently swallow!) --- OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index ef6e259..9064464 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -786,7 +786,7 @@ namespace OpenSim.Framework.Servers.HttpServer requestStream.Close(); //m_log.Debug(requestBody); requestBody = requestBody.Replace("", ""); - string responseString = null; + string responseString = String.Empty; XmlRpcRequest xmlRprcRequest = null; try -- cgit v1.1 From 9825861f4ac8d78665c33e2630824d97b356e642 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Jun 2012 23:46:09 +0100 Subject: Shuffle "debug http" levels so that 1 and 2 now cause different levels of warn to be logged if we receive invalid xml for xmlrpc. --- .../Framework/Servers/HttpServer/BaseHttpServer.cs | 35 +++++++++++++++++----- OpenSim/Region/Application/OpenSim.cs | 9 +++--- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 9064464..35a0be4 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -82,6 +82,11 @@ namespace OpenSim.Framework.Servers.HttpServer /// /// Control the printing of certain debug messages. /// + /// + /// If DebugLevel >= 1, then short warnings are logged when receiving bad input data. + /// If DebugLevel >= 2, then long warnings are logged when receiving bad input data. + /// If DebugLevel >= 3, then short notices about all incoming non-poll HTTP requests are logged. + /// public int DebugLevel { get; set; } public uint SSLPort @@ -450,7 +455,7 @@ namespace OpenSim.Framework.Servers.HttpServer if (TryGetStreamHandler(handlerKey, out requestHandler)) { - if (DebugLevel >= 1) + if (DebugLevel >= 3) m_log.DebugFormat( "[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}", request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description); @@ -531,7 +536,7 @@ namespace OpenSim.Framework.Servers.HttpServer case null: case "text/html": - if (DebugLevel >= 1) + if (DebugLevel >= 3) m_log.DebugFormat( "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", request.ContentType, request.HttpMethod, request.Url.PathAndQuery); @@ -543,7 +548,7 @@ namespace OpenSim.Framework.Servers.HttpServer case "application/xml+llsd": case "application/llsd+json": - if (DebugLevel >= 1) + if (DebugLevel >= 3) m_log.DebugFormat( "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", request.ContentType, request.HttpMethod, request.Url.PathAndQuery); @@ -564,7 +569,7 @@ namespace OpenSim.Framework.Servers.HttpServer //m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler"); if (DoWeHaveALLSDHandler(request.RawUrl)) { - if (DebugLevel >= 1) + if (DebugLevel >= 3) m_log.DebugFormat( "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", request.ContentType, request.HttpMethod, request.Url.PathAndQuery); @@ -574,7 +579,7 @@ namespace OpenSim.Framework.Servers.HttpServer // m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl); else if (DoWeHaveAHTTPHandler(request.RawUrl)) { - if (DebugLevel >= 1) + if (DebugLevel >= 3) m_log.DebugFormat( "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", request.ContentType, request.HttpMethod, request.Url.PathAndQuery); @@ -583,8 +588,7 @@ namespace OpenSim.Framework.Servers.HttpServer } else { - - if (DebugLevel >= 1) + if (DebugLevel >= 3) m_log.DebugFormat( "[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}", request.HttpMethod, request.Url.PathAndQuery); @@ -793,8 +797,23 @@ namespace OpenSim.Framework.Servers.HttpServer { xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody); } - catch (XmlException) + catch (XmlException e) { + if (DebugLevel >= 1) + { + if (DebugLevel >= 2) + m_log.Warn( + string.Format( + "[BASE HTTP SERVER]: Got XMLRPC request with invalid XML from {0}. XML was '{1}'. Sending blank response. Exception ", + request.RemoteIPEndPoint, requestBody), + e); + else + { + m_log.WarnFormat( + "[BASE HTTP SERVER]: Got XMLRPC request with invalid XML from {0}, length {1}. Sending blank response.", + request.RemoteIPEndPoint, requestBody.Length); + } + } } if (xmlRprcRequest != null) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 57a3c69..96d41a4 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -250,10 +250,11 @@ namespace OpenSim m_console.Commands.AddCommand("Comms", false, "debug http", "debug http ", - "Turn on inbound http request debugging for everything except the event queue (see debug eq).", - "If level >= 2 then the handler used to service the request is logged.\n" - + "If level >= 1 then incoming HTTP requests are logged.\n" - + "If level <= 0 then no extra http logging is done.\n", + "Turn on inbound non-poll http request debugging for everything except the event queue (see debug eq).", + "If level <= 0, then no extra logging is done.\n" + + "If level >= 1, then short warnings are logged when receiving bad input data.\n" + + "If level >= 2, then long warnings are logged when receiving bad input data.\n" + + "If level >= 3, then short notices about all incoming non-poll HTTP requests are logged.\n", Debug); m_console.Commands.AddCommand("Comms", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug); -- cgit v1.1 From 93ba0332c4ccbb0c60e6d60fff71dc7d1567c9dd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Jun 2012 23:54:12 +0100 Subject: minor: Extend 'debug http' usage statement to 0..3 from 0..2 --- OpenSim/Region/Application/OpenSim.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 96d41a4..00ae880 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -927,7 +927,7 @@ namespace OpenSim } } - MainConsole.Instance.Output("Usage: debug http 0..2"); + MainConsole.Instance.Output("Usage: debug http 0..3"); break; case "scene": -- cgit v1.1 From 6993a26ba599ae38dc6f66332980657d5621987a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Jun 2012 00:40:12 +0100 Subject: Get rid of some unnecessary null checks in RegionApplicationBase.StartupSpecific() - a constructor can never return null. Also adds some method doc to MainServer --- OpenSim/Framework/Servers/MainServer.cs | 31 +++++++++++++++++++--- .../Region/ClientStack/RegionApplicationBase.cs | 14 ++++------ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs index b8ab8d9..ea972ef 100644 --- a/OpenSim/Framework/Servers/MainServer.cs +++ b/OpenSim/Framework/Servers/MainServer.cs @@ -47,20 +47,43 @@ namespace OpenSim.Framework.Servers set { instance = value; } } - public static IHttpServer GetHttpServer(uint port) + /// + /// Add an already started HTTP server to the collection of known servers. + /// + /// + public static void AddHttpServer(BaseHttpServer server) { - return GetHttpServer(port,null); + m_Servers.Add(server.Port, server); } - public static void AddHttpServer(BaseHttpServer server) + /// + /// Get the default http server or an http server for a specific port. + /// + /// + /// If the requested HTTP server doesn't already exist then a new one is instantiated and started. + /// + /// + /// If 0 then the default HTTP server is returned. + public static IHttpServer GetHttpServer(uint port) { - m_Servers.Add(server.Port, server); + return GetHttpServer(port, null); } + /// + /// Get the default http server, an http server for a specific port + /// and/or an http server bound to a specific address + /// + /// + /// If the requested HTTP server doesn't already exist then a new one is instantiated and started. + /// + /// + /// If 0 then the default HTTP server is returned. + /// A specific IP address to bind to. If null then the default IP address is used. public static IHttpServer GetHttpServer(uint port, IPAddress ipaddr) { if (port == 0) return Instance; + if (instance != null && port == Instance.Port) return Instance; diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs index 6e78d6d..27a5879 100644 --- a/OpenSim/Region/ClientStack/RegionApplicationBase.cs +++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs @@ -99,17 +99,13 @@ namespace OpenSim.Region.ClientStack // "OOB" Server if (m_networkServersInfo.ssl_listener) { - BaseHttpServer server = null; - server = new BaseHttpServer( + BaseHttpServer server = new BaseHttpServer( m_networkServersInfo.https_port, m_networkServersInfo.ssl_listener, m_networkServersInfo.cert_path, m_networkServersInfo.cert_pass); - // Add the server to m_Servers - if(server != null) - { - m_log.InfoFormat("[REGION SERVER]: Starting HTTPS server on port {0}", server.Port); - MainServer.AddHttpServer(server); - server.Start(); - } + + m_log.InfoFormat("[REGION SERVER]: Starting HTTPS server on port {0}", server.Port); + MainServer.AddHttpServer(server); + server.Start(); } base.StartupSpecific(); -- cgit v1.1 From 10e87f9cdc6c2cbd01da863e01abca8f7e671f9c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Jun 2012 00:59:53 +0100 Subject: Make XMLRPCModule use an existing HTTP server if one already exists on the desired port. --- OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs index 40ffcb4..0003af2 100644 --- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs @@ -131,11 +131,12 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC { // Start http server // Attach xmlrpc handlers - m_log.Info("[XML RPC MODULE]: " + - "Starting up XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands."); - BaseHttpServer httpServer = new BaseHttpServer((uint) m_remoteDataPort); +// m_log.InfoFormat( +// "[XML RPC MODULE]: Starting up XMLRPC Server on port {0} for llRemoteData commands.", +// m_remoteDataPort); + + IHttpServer httpServer = MainServer.GetHttpServer((uint)m_remoteDataPort); httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData); - httpServer.Start(); } } -- cgit v1.1 From 478acfff34b94c7c42bdb927be531b669c43af72 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Jun 2012 01:24:36 +0100 Subject: When setting debug http level, do this for all known http servers, not just the main instance. --- .../Framework/Servers/HttpServer/BaseHttpServer.cs | 20 +++++------ OpenSim/Framework/Servers/MainServer.cs | 41 ++++++++++++++++------ OpenSim/Region/Application/OpenSim.cs | 2 +- 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 35a0be4..6b52485 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -53,6 +53,16 @@ namespace OpenSim.Framework.Servers.HttpServer private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private HttpServerLogWriter httpserverlog = new HttpServerLogWriter(); + /// + /// Control the printing of certain debug messages. + /// + /// + /// If DebugLevel >= 1, then short warnings are logged when receiving bad input data. + /// If DebugLevel >= 2, then long warnings are logged when receiving bad input data. + /// If DebugLevel >= 3, then short notices about all incoming non-poll HTTP requests are logged. + /// + public int DebugLevel { get; set; } + private volatile int NotSocketErrors = 0; public volatile bool HTTPDRunning = false; @@ -79,16 +89,6 @@ namespace OpenSim.Framework.Servers.HttpServer private PollServiceRequestManager m_PollServiceManager; - /// - /// Control the printing of certain debug messages. - /// - /// - /// If DebugLevel >= 1, then short warnings are logged when receiving bad input data. - /// If DebugLevel >= 2, then long warnings are logged when receiving bad input data. - /// If DebugLevel >= 3, then short notices about all incoming non-poll HTTP requests are logged. - /// - public int DebugLevel { get; set; } - public uint SSLPort { get { return m_sslport; } diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs index ea972ef..efac6e1 100644 --- a/OpenSim/Framework/Servers/MainServer.cs +++ b/OpenSim/Framework/Servers/MainServer.cs @@ -38,8 +38,23 @@ namespace OpenSim.Framework.Servers private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static BaseHttpServer instance = null; - private static Dictionary m_Servers = - new Dictionary(); + private static Dictionary m_Servers = new Dictionary(); + + public static int DebugLevel + { + get { return s_debugLevel; } + set + { + s_debugLevel = value; + Instance.DebugLevel = s_debugLevel; + + lock (m_Servers) + foreach (BaseHttpServer server in m_Servers.Values) + server.DebugLevel = s_debugLevel; + } + } + + private static int s_debugLevel; public static BaseHttpServer Instance { @@ -53,7 +68,8 @@ namespace OpenSim.Framework.Servers /// public static void AddHttpServer(BaseHttpServer server) { - m_Servers.Add(server.Port, server); + lock (m_Servers) + m_Servers.Add(server.Port, server); } /// @@ -87,18 +103,21 @@ namespace OpenSim.Framework.Servers if (instance != null && port == Instance.Port) return Instance; - if (m_Servers.ContainsKey(port)) - return m_Servers[port]; + lock (m_Servers) + { + if (m_Servers.ContainsKey(port)) + return m_Servers[port]; - m_Servers[port] = new BaseHttpServer(port); + m_Servers[port] = new BaseHttpServer(port); - if (ipaddr != null) - m_Servers[port].ListenIPAddress = ipaddr; + if (ipaddr != null) + m_Servers[port].ListenIPAddress = ipaddr; - m_log.InfoFormat("[MAIN HTTP SERVER]: Starting main http server on port {0}", port); - m_Servers[port].Start(); + m_log.InfoFormat("[MAIN HTTP SERVER]: Starting main http server on port {0}", port); + m_Servers[port].Start(); + } return m_Servers[port]; } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 00ae880..9043137 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -921,7 +921,7 @@ namespace OpenSim int newDebug; if (int.TryParse(args[2], out newDebug)) { - MainServer.Instance.DebugLevel = newDebug; + MainServer.DebugLevel = newDebug; MainConsole.Instance.OutputFormat("Debug http level set to {0}", newDebug); break; } -- cgit v1.1 From aeed4d3041af75cf18d140208cc4c744a73d0492 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Jun 2012 01:27:29 +0100 Subject: minor: Tell user the current debug http level if "debug http" console command is executed without a level parameter --- OpenSim/Region/Application/OpenSim.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 9043137..abb30a9 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -249,12 +249,13 @@ namespace OpenSim Debug); m_console.Commands.AddCommand("Comms", false, "debug http", - "debug http ", + "debug http []", "Turn on inbound non-poll http request debugging for everything except the event queue (see debug eq).", "If level <= 0, then no extra logging is done.\n" + "If level >= 1, then short warnings are logged when receiving bad input data.\n" + "If level >= 2, then long warnings are logged when receiving bad input data.\n" - + "If level >= 3, then short notices about all incoming non-poll HTTP requests are logged.\n", + + "If level >= 3, then short notices about all incoming non-poll HTTP requests are logged.\n" + + "If no level is specified then the current level is returned.", Debug); m_console.Commands.AddCommand("Comms", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug); @@ -926,8 +927,15 @@ namespace OpenSim break; } } + else if (args.Length == 2) + { + MainConsole.Instance.OutputFormat("Current debug http level is {0}", MainServer.DebugLevel); + } + else + { + MainConsole.Instance.Output("Usage: debug http 0..3"); + } - MainConsole.Instance.Output("Usage: debug http 0..3"); break; case "scene": -- cgit v1.1 From 257b1b517dec58bf902bac63bc7ab7080286d415 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Jun 2012 02:03:50 +0100 Subject: Add main instance to internal MainServer.m_Servers list to simplify internal logic. This does require the server to be added before it is set as the main Instance --- .../Framework/Servers/HttpServer/BaseHttpServer.cs | 8 --- OpenSim/Framework/Servers/MainServer.cs | 64 +++++++++++++++++++++- .../Caps/EventQueue/Tests/EventQueueTests.cs | 11 +++- .../Region/ClientStack/RegionApplicationBase.cs | 1 + OpenSim/Server/Base/HttpServerBase.cs | 13 +---- 5 files changed, 75 insertions(+), 22 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 6b52485..0db1329 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -53,14 +53,6 @@ namespace OpenSim.Framework.Servers.HttpServer private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private HttpServerLogWriter httpserverlog = new HttpServerLogWriter(); - /// - /// Control the printing of certain debug messages. - /// - /// - /// If DebugLevel >= 1, then short warnings are logged when receiving bad input data. - /// If DebugLevel >= 2, then long warnings are logged when receiving bad input data. - /// If DebugLevel >= 3, then short notices about all incoming non-poll HTTP requests are logged. - /// public int DebugLevel { get; set; } private volatile int NotSocketErrors = 0; diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs index efac6e1..becbbc2 100644 --- a/OpenSim/Framework/Servers/MainServer.cs +++ b/OpenSim/Framework/Servers/MainServer.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using System.Collections.Generic; using System.Reflection; using System.Net; @@ -40,13 +41,20 @@ namespace OpenSim.Framework.Servers private static BaseHttpServer instance = null; private static Dictionary m_Servers = new Dictionary(); + /// + /// Control the printing of certain debug messages. + /// + /// + /// If DebugLevel >= 1, then short warnings are logged when receiving bad input data. + /// If DebugLevel >= 2, then long warnings are logged when receiving bad input data. + /// If DebugLevel >= 3, then short notices about all incoming non-poll HTTP requests are logged. + /// public static int DebugLevel { get { return s_debugLevel; } set { s_debugLevel = value; - Instance.DebugLevel = s_debugLevel; lock (m_Servers) foreach (BaseHttpServer server in m_Servers.Values) @@ -56,20 +64,70 @@ namespace OpenSim.Framework.Servers private static int s_debugLevel; + /// + /// Set the main HTTP server instance. + /// + /// + /// This will be used to register all handlers that listen to the default port. + /// + /// + /// Thrown if the HTTP server has not already been registered via AddHttpServer() + /// public static BaseHttpServer Instance { get { return instance; } - set { instance = value; } + + set + { + lock (m_Servers) + if (!m_Servers.ContainsValue(value)) + throw new Exception("HTTP server must already have been registered to be set as the main instance"); + + instance = value; + } } /// - /// Add an already started HTTP server to the collection of known servers. + /// Register an already started HTTP server to the collection of known servers. /// /// public static void AddHttpServer(BaseHttpServer server) { lock (m_Servers) + { + if (m_Servers.ContainsKey(server.Port)) + throw new Exception(string.Format("HTTP server for port {0} already exists.", server.Port)); + m_Servers.Add(server.Port, server); + } + } + + /// + /// Removes the http server listening on the given port. + /// + /// + /// It is the responsibility of the caller to do clean up. + /// + /// + /// + public static bool RemoveHttpServer(uint port) + { + lock (m_Servers) + return m_Servers.Remove(port); + } + + /// + /// Does this collection of servers contain one with the given port? + /// + /// + /// Unlike GetHttpServer, this will not instantiate a server if one does not exist on that port. + /// + /// + /// true if a server with the given port is registered, false otherwise. + public static bool ContainsHttpServer(uint port) + { + lock (m_Servers) + return m_Servers.ContainsKey(port); } /// diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs index c25b58c..cd70410 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs @@ -51,7 +51,16 @@ namespace OpenSim.Region.ClientStack.Linden.Tests [SetUp] public void SetUp() { - MainServer.Instance = new BaseHttpServer(9999, false, 9998, ""); + uint port = 9999; + uint sslPort = 9998; + + // This is an unfortunate bit of clean up we have to do because MainServer manages things through static + // variables and the VM is not restarted between tests. + MainServer.RemoveHttpServer(port); + + BaseHttpServer server = new BaseHttpServer(port, false, sslPort, ""); + MainServer.AddHttpServer(server); + MainServer.Instance = server; IConfigSource config = new IniConfigSource(); config.AddConfig("Startup"); diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs index 27a5879..c4324e8 100644 --- a/OpenSim/Region/ClientStack/RegionApplicationBase.cs +++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs @@ -94,6 +94,7 @@ namespace OpenSim.Region.ClientStack m_log.InfoFormat("[REGION SERVER]: Starting HTTP server on port {0}", m_httpServerPort); m_httpServer.Start(); + MainServer.AddHttpServer(m_httpServer); MainServer.Instance = m_httpServer; // "OOB" Server diff --git a/OpenSim/Server/Base/HttpServerBase.cs b/OpenSim/Server/Base/HttpServerBase.cs index d471559..7014303 100644 --- a/OpenSim/Server/Base/HttpServerBase.cs +++ b/OpenSim/Server/Base/HttpServerBase.cs @@ -138,6 +138,7 @@ namespace OpenSim.Server.Base m_HttpServer = new BaseHttpServer(port, ssl_main, cert_path, cert_pass); } + MainServer.AddHttpServer(m_HttpServer); MainServer.Instance = m_HttpServer; // If https_listener = true, then add an ssl listener on the https_port... @@ -157,16 +158,8 @@ namespace OpenSim.Server.Base System.Console.WriteLine("Password for X509 certificate is missing, server can't start."); Thread.CurrentThread.Abort(); } - // Add our https_server - BaseHttpServer server = null; - server = new BaseHttpServer(https_port, ssl_listener, cert_path, cert_pass); - if (server != null) - { - m_Log.InfoFormat("[SERVER]: Starting HTTPS server on port {0}", https_port); - m_Servers.Add(https_port,server); - } - else - System.Console.WriteLine(String.Format("Failed to start HTTPS server on port {0}",https_port)); + + m_Servers.Add(https_port, new BaseHttpServer(https_port, ssl_listener, cert_path, cert_pass)); } } -- cgit v1.1 From 94517c8d5c63f9e8a1ea9a83b04db956f27aa25d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Jun 2012 02:51:52 +0100 Subject: Make the "debug http" command available for robust as well as the simulator. This allows one to see incoming requests as they happen. This required making everything use the common MainServer class for registering and retrieving http servers, rather than duplicate structures. --- .../Framework/Servers/HttpServer/BaseHttpServer.cs | 3 + OpenSim/Framework/Servers/MainServer.cs | 60 +++++++++++++++-- OpenSim/Region/Application/OpenSim.cs | 34 +--------- OpenSim/Server/Base/HttpServerBase.cs | 78 +++++----------------- OpenSim/Server/ServerMain.cs | 26 ++++---- prebuild.xml | 1 + 6 files changed, 92 insertions(+), 110 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 0db1329..3de7f9c 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -1557,6 +1557,9 @@ namespace OpenSim.Framework.Servers.HttpServer private void StartHTTP() { + m_log.InfoFormat( + "[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port); + try { //m_httpListener = new HttpListener(); diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs index becbbc2..07ff60c 100644 --- a/OpenSim/Framework/Servers/MainServer.cs +++ b/OpenSim/Framework/Servers/MainServer.cs @@ -30,13 +30,15 @@ using System.Collections.Generic; using System.Reflection; using System.Net; using log4net; +using OpenSim.Framework; +using OpenSim.Framework.Console; using OpenSim.Framework.Servers.HttpServer; namespace OpenSim.Framework.Servers { public class MainServer { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static BaseHttpServer instance = null; private static Dictionary m_Servers = new Dictionary(); @@ -88,6 +90,57 @@ namespace OpenSim.Framework.Servers } /// + /// Get all the registered servers. + /// + /// + /// Returns a copy of the dictionary so this can be iterated through without locking. + /// + /// + public static Dictionary Servers + { + get { return new Dictionary(m_Servers); } + } + + + public static void RegisterHttpConsoleCommands(ICommandConsole console) + { + console.Commands.AddCommand( + "Comms", false, "debug http", "debug http []", + "Turn on inbound non-poll http request debugging.", + "If level <= 0, then no extra logging is done.\n" + + "If level >= 1, then short warnings are logged when receiving bad input data.\n" + + "If level >= 2, then long warnings are logged when receiving bad input data.\n" + + "If level >= 3, then short notices about all incoming non-poll HTTP requests are logged.\n" + + "If no level is specified then the current level is returned.", + HandleDebugHttpCommand); + } + + /// + /// Turn on some debugging values for OpenSim. + /// + /// + private static void HandleDebugHttpCommand(string module, string[] args) + { + if (args.Length == 3) + { + int newDebug; + if (int.TryParse(args[2], out newDebug)) + { + MainServer.DebugLevel = newDebug; + MainConsole.Instance.OutputFormat("Debug http level set to {0}", newDebug); + } + } + else if (args.Length == 2) + { + MainConsole.Instance.OutputFormat("Current debug http level is {0}", MainServer.DebugLevel); + } + else + { + MainConsole.Instance.Output("Usage: debug http 0..3"); + } + } + + /// /// Register an already started HTTP server to the collection of known servers. /// /// @@ -171,11 +224,10 @@ namespace OpenSim.Framework.Servers if (ipaddr != null) m_Servers[port].ListenIPAddress = ipaddr; - m_log.InfoFormat("[MAIN HTTP SERVER]: Starting main http server on port {0}", port); m_Servers[port].Start(); - } - return m_Servers[port]; + return m_Servers[port]; + } } } } \ No newline at end of file diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index abb30a9..faa9e09 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -231,6 +231,8 @@ namespace OpenSim /// private void RegisterConsoleCommands() { + MainServer.RegisterHttpConsoleCommands(m_console); + m_console.Commands.AddCommand("Objects", false, "force update", "force update", "Force the update of all objects on clients", @@ -248,16 +250,6 @@ namespace OpenSim + "If an avatar name is given then only packets from that avatar are logged", Debug); - m_console.Commands.AddCommand("Comms", false, "debug http", - "debug http []", - "Turn on inbound non-poll http request debugging for everything except the event queue (see debug eq).", - "If level <= 0, then no extra logging is done.\n" - + "If level >= 1, then short warnings are logged when receiving bad input data.\n" - + "If level >= 2, then long warnings are logged when receiving bad input data.\n" - + "If level >= 3, then short notices about all incoming non-poll HTTP requests are logged.\n" - + "If no level is specified then the current level is returned.", - Debug); - m_console.Commands.AddCommand("Comms", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug); m_console.Commands.AddCommand("Regions", false, "debug scene", @@ -916,28 +908,6 @@ namespace OpenSim break; - case "http": - if (args.Length == 3) - { - int newDebug; - if (int.TryParse(args[2], out newDebug)) - { - MainServer.DebugLevel = newDebug; - MainConsole.Instance.OutputFormat("Debug http level set to {0}", newDebug); - break; - } - } - else if (args.Length == 2) - { - MainConsole.Instance.OutputFormat("Current debug http level is {0}", MainServer.DebugLevel); - } - else - { - MainConsole.Instance.Output("Usage: debug http 0..3"); - } - - break; - case "scene": if (args.Length == 4) { diff --git a/OpenSim/Server/Base/HttpServerBase.cs b/OpenSim/Server/Base/HttpServerBase.cs index 7014303..7ba0ca8 100644 --- a/OpenSim/Server/Base/HttpServerBase.cs +++ b/OpenSim/Server/Base/HttpServerBase.cs @@ -42,42 +42,9 @@ namespace OpenSim.Server.Base { // Logger // - private static readonly ILog m_Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - // The http server instance - // - protected BaseHttpServer m_HttpServer = null; - protected uint m_Port = 0; - protected Dictionary m_Servers = - new Dictionary(); - protected uint m_consolePort = 0; - - public IHttpServer HttpServer - { - get { return m_HttpServer; } - } - - public uint DefaultPort - { - get { return m_Port; } - } - - public IHttpServer GetHttpServer(uint port) - { - m_Log.InfoFormat("[SERVER]: Requested port {0}", port); - if (port == m_Port) - return HttpServer; - - if (m_Servers.ContainsKey(port)) - return m_Servers[port]; - - m_Servers[port] = new BaseHttpServer(port); - - m_Log.InfoFormat("[SERVER]: Starting new HTTP server on port {0}", port); - m_Servers[port].Start(); - - return m_Servers[port]; - } + private uint m_consolePort; // Handle all the automagical stuff // @@ -94,19 +61,21 @@ namespace OpenSim.Server.Base System.Console.WriteLine("Section 'Network' not found, server can't start"); Thread.CurrentThread.Abort(); } + uint port = (uint)networkConfig.GetInt("port", 0); if (port == 0) { - Thread.CurrentThread.Abort(); } - // + bool ssl_main = networkConfig.GetBoolean("https_main",false); bool ssl_listener = networkConfig.GetBoolean("https_listener",false); m_consolePort = (uint)networkConfig.GetInt("ConsolePort", 0); - m_Port = port; + + BaseHttpServer httpServer = null; + // // This is where to make the servers: // @@ -118,8 +87,7 @@ namespace OpenSim.Server.Base // if ( !ssl_main ) { - m_HttpServer = new BaseHttpServer(port); - + httpServer = new BaseHttpServer(port); } else { @@ -135,11 +103,12 @@ namespace OpenSim.Server.Base System.Console.WriteLine("Password for X509 certificate is missing, server can't start."); Thread.CurrentThread.Abort(); } - m_HttpServer = new BaseHttpServer(port, ssl_main, cert_path, cert_pass); + + httpServer = new BaseHttpServer(port, ssl_main, cert_path, cert_pass); } - MainServer.AddHttpServer(m_HttpServer); - MainServer.Instance = m_HttpServer; + MainServer.AddHttpServer(httpServer); + MainServer.Instance = httpServer; // If https_listener = true, then add an ssl listener on the https_port... if ( ssl_listener == true ) { @@ -159,34 +128,23 @@ namespace OpenSim.Server.Base Thread.CurrentThread.Abort(); } - m_Servers.Add(https_port, new BaseHttpServer(https_port, ssl_listener, cert_path, cert_pass)); + MainServer.AddHttpServer(new BaseHttpServer(https_port, ssl_listener, cert_path, cert_pass)); } } protected override void Initialise() { - m_Log.InfoFormat("[SERVER]: Starting HTTP server on port {0}", m_HttpServer.Port); - m_HttpServer.Start(); - - if (m_Servers.Count > 0) - { - foreach (BaseHttpServer s in m_Servers.Values) - { - if (!s.UseSSL) - m_Log.InfoFormat("[SERVER]: Starting HTTP server on port {0}", s.Port); - else - m_Log.InfoFormat("[SERVER]: Starting HTTPS server on port {0}", s.Port); + foreach (BaseHttpServer s in MainServer.Servers.Values) + s.Start(); - s.Start(); - } - } + MainServer.RegisterHttpConsoleCommands(MainConsole.Instance); if (MainConsole.Instance is RemoteConsole) { if (m_consolePort == 0) - ((RemoteConsole)MainConsole.Instance).SetServer(m_HttpServer); + ((RemoteConsole)MainConsole.Instance).SetServer(MainServer.Instance); else - ((RemoteConsole)MainConsole.Instance).SetServer(GetHttpServer(m_consolePort)); + ((RemoteConsole)MainConsole.Instance).SetServer(MainServer.GetHttpServer(m_consolePort)); } } } diff --git a/OpenSim/Server/ServerMain.cs b/OpenSim/Server/ServerMain.cs index 9503c4c..21fb678 100644 --- a/OpenSim/Server/ServerMain.cs +++ b/OpenSim/Server/ServerMain.cs @@ -30,6 +30,7 @@ using log4net; using System.Reflection; using System; using System.Collections.Generic; +using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Server.Base; using OpenSim.Server.Handlers.Base; @@ -92,27 +93,24 @@ namespace OpenSim.Server if (parts.Length > 1) friendlyName = parts[1]; - IHttpServer server = m_Server.HttpServer; - if (port != 0) - server = m_Server.GetHttpServer(port); + IHttpServer server; - if (port != m_Server.DefaultPort && port != 0) - m_log.InfoFormat("[SERVER]: Loading {0} on port {1}", friendlyName, port); + if (port != 0) + server = MainServer.GetHttpServer(port); else - m_log.InfoFormat("[SERVER]: Loading {0}", friendlyName); + server = MainServer.Instance; + + m_log.InfoFormat("[SERVER]: Loading {0} on port {1}", friendlyName, server.Port); IServiceConnector connector = null; - Object[] modargs = new Object[] { m_Server.Config, server, - configName }; - connector = ServerUtils.LoadPlugin(conn, - modargs); + Object[] modargs = new Object[] { m_Server.Config, server, configName }; + connector = ServerUtils.LoadPlugin(conn, modargs); + if (connector == null) { modargs = new Object[] { m_Server.Config, server }; - connector = - ServerUtils.LoadPlugin(conn, - modargs); + connector = ServerUtils.LoadPlugin(conn, modargs); } if (connector != null) @@ -132,4 +130,4 @@ namespace OpenSim.Server return 0; } } -} +} \ No newline at end of file diff --git a/prebuild.xml b/prebuild.xml index d02f2b9..45f58c7 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1385,6 +1385,7 @@ + -- cgit v1.1 From c935f0346750d510e5c3c3c2ff62c84609a115e3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Jun 2012 03:32:43 +0100 Subject: Put all debug console commands into a single Debug section rather than scattering them over other categories --- OpenSim/Framework/Servers/MainServer.cs | 2 +- OpenSim/Region/Application/OpenSim.cs | 6 +++--- .../ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs | 2 +- OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs index 07ff60c..8dc0e3a 100644 --- a/OpenSim/Framework/Servers/MainServer.cs +++ b/OpenSim/Framework/Servers/MainServer.cs @@ -105,7 +105,7 @@ namespace OpenSim.Framework.Servers public static void RegisterHttpConsoleCommands(ICommandConsole console) { console.Commands.AddCommand( - "Comms", false, "debug http", "debug http []", + "Debug", false, "debug http", "debug http []", "Turn on inbound non-poll http request debugging.", "If level <= 0, then no extra logging is done.\n" + "If level >= 1, then short warnings are logged when receiving bad input data.\n" diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index faa9e09..04ff4e6 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -238,7 +238,7 @@ namespace OpenSim "Force the update of all objects on clients", HandleForceUpdate); - m_console.Commands.AddCommand("Comms", false, "debug packet", + m_console.Commands.AddCommand("Debug", false, "debug packet", "debug packet [ ]", "Turn on packet debugging", "If level > 255 then all incoming and outgoing packets are logged.\n" @@ -250,9 +250,9 @@ namespace OpenSim + "If an avatar name is given then only packets from that avatar are logged", Debug); - m_console.Commands.AddCommand("Comms", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug); + m_console.Commands.AddCommand("Debug", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug); - m_console.Commands.AddCommand("Regions", false, "debug scene", + m_console.Commands.AddCommand("Debug", false, "debug scene", "debug scene ", "Turn on scene debugging", Debug); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index ae759ca..594b229 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -106,7 +106,7 @@ namespace OpenSim.Region.ClientStack.Linden scene.EventManager.OnRegisterCaps += OnRegisterCaps; MainConsole.Instance.Commands.AddCommand( - "Comms", + "Debug", false, "debug eq", "debug eq [0|1|2]", diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 555509c..4f72463 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -221,7 +221,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions "Force permissions on or off", HandleForcePermissions); - m_scene.AddCommand("Users", this, "debug permissions", + m_scene.AddCommand("Debug", this, "debug permissions", "debug permissions ", "Turn on permissions debugging", HandleDebugPermissions); -- cgit v1.1 From aaa30dcebc223d74d59ecb5d9f8e1e69532efb7c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Jun 2012 05:01:36 +0100 Subject: Add region name to UseCircuitCode log messages --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 5126d84..44c65e0 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -986,8 +986,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1]; m_log.DebugFormat( - "[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} from {1}", - uccp.CircuitCode.Code, buffer.RemoteEndPoint); + "[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}", + uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, buffer.RemoteEndPoint); remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint; @@ -1016,8 +1016,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP { // Don't create clients for unauthorized requesters. m_log.WarnFormat( - "[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}", - uccp.CircuitCode.ID, uccp.CircuitCode.Code, remoteEndPoint); + "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", + uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint); } // m_log.DebugFormat( -- cgit v1.1 From 22f25dfcab4a5c0d4df0a3df74a6337ab80c5ee8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jun 2012 03:32:47 +0100 Subject: Implement max_external_urls_per_simulator setting in [LL-Functions] to allow configuration of how many urls can be set up by llRequestURL() Defaults remains as 100. This setting is per simulator instead of per region due to how the url script module is structured. --- OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | 9 ++++++++- bin/OpenSimDefaults.ini | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index d2cd163..77dfcc6 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -76,7 +76,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp private Dictionary m_UrlMap = new Dictionary(); - + /// + /// Maximum number of external urls that can be set up by this module. + /// private int m_TotalUrls = 100; private uint https_port = 0; @@ -107,6 +109,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp { https_port = (uint) config.Configs["Network"].GetInt("https_port",0); } + + IConfig llFunctionsConfig = config.Configs["LL-Functions"]; + + if (llFunctionsConfig != null) + m_TotalUrls = llFunctionsConfig.GetInt("max_urls_per_simulator", m_TotalUrls); } public void PostInitialise() diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 1b8a4b6..ededdc05 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -1168,7 +1168,9 @@ ; Maximum number of llListen events we allow per script ; Set this to 0 to have no limit imposed. max_listens_per_script = 64 - + + ; Maximum number of external urls that scripts can set up in this simulator (e.g. via llRequestURL()) + max_external_urls_per_simulator = 100 [DataSnapshot] ; The following set of configs pertains to search. -- cgit v1.1 From ed513fc7bee7945a71ad9cb66d83ac68335a7774 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jun 2012 03:43:45 +0100 Subject: Fix bug introduced in commit c6e3752 (13 Jun 2012) where poll responses would always return OK even if some other status code had been set --- OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs index 2995421..35a8dee 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs @@ -129,9 +129,7 @@ namespace OpenSim.Framework.Servers.HttpServer OSHttpResponse response = new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext); - byte[] buffer - = server.DoHTTPGruntWork( - responsedata, new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext)); + byte[] buffer = server.DoHTTPGruntWork(responsedata, response); response.SendChunked = false; response.ContentLength64 = buffer.Length; -- cgit v1.1 From 7119de56ffb9c37b6baa57c5f30b81ac3f86c91c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Jun 2012 04:12:53 +0100 Subject: Change read config paramter from max_urls_per_simulator to max_external_urls_per_simulator, which is what it was meant to be --- OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 77dfcc6..61afc76 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -113,7 +113,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp IConfig llFunctionsConfig = config.Configs["LL-Functions"]; if (llFunctionsConfig != null) - m_TotalUrls = llFunctionsConfig.GetInt("max_urls_per_simulator", m_TotalUrls); + m_TotalUrls = llFunctionsConfig.GetInt("max_external_urls_per_simulator", m_TotalUrls); } public void PostInitialise() -- cgit v1.1 From 2ed768cbf5734f6b0c8825beecc4347bf9537f6f Mon Sep 17 00:00:00 2001 From: BlueWall Date: Sat, 16 Jun 2012 06:25:12 -0400 Subject: Adjust Robust*.ini.examples V3 webprofile entries --- bin/Robust.HG.ini.example | 14 +++++++++----- bin/Robust.ini.example | 10 +++++++--- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 9887ab5..63a13d7 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -237,12 +237,16 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 WelcomeMessage = "Welcome, Avatar!" AllowRemoteSetLoginLevel = "false" - - ; For V2 map - MapTileURL = "http://127.0.0.1:8002"; - ; For WebProfiles (V3) - ProfileServerURL = "http://127.0.0.1/profiles/[AGENT_NAME]" + ; For V2/3 Web Profiles + ; Work in progress: The ProfileServerURL/OpenIDServerURL are + ; being used in a development viewer as support for webprofiles + ; is being developed across the componets + ; + ; ProfileServerURL = "http://127.0.0.1/profiles/[AGENT_NAME]" + ; + ; For V2/V3 webapp authentication SSO + ; OpenIDServerURL = "http://127.0.0.1/openid/openidserver/" ; If you run this login server behind a proxy, set this to true ; HasProxy = false diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index f70d13b..5a9d613 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -225,10 +225,14 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 MapTileURL = "http://127.0.0.1:8002"; ; For V2/3 Web Profiles - ProfileServerURL = "http://127.0.0.1/profiles/[AGENT_NAME]" - + ; Work in progress: The ProfileServerURL/OpenIDServerURL are + ; being used in a development viewer as support for webprofiles + ; is being developed across the componets + ; + ; ProfileServerURL = "http://127.0.0.1/profiles/[AGENT_NAME]" + ; ; For V2/V3 webapp authentication SSO - OpenIDServerURL = "http://127.0.0.1/openid/openidserver/" + ; OpenIDServerURL = "http://127.0.0.1/openid/openidserver/" ; If you run this login server behind a proxy, set this to true ; HasProxy = false -- cgit v1.1 From 5c5b359bcb80e8bdea2086cae117312541083787 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Sat, 16 Jun 2012 07:24:27 -0400 Subject: Oops! putting back the entry for map urls --- bin/Robust.HG.ini.example | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 63a13d7..3eecdd9 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -238,6 +238,9 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 WelcomeMessage = "Welcome, Avatar!" AllowRemoteSetLoginLevel = "false" + ; For V2 map + MapTileURL = "http://127.0.0.1:8002"; + ; For V2/3 Web Profiles ; Work in progress: The ProfileServerURL/OpenIDServerURL are ; being used in a development viewer as support for webprofiles -- cgit v1.1 From 8e7032ece87d3e0e75f091ea84d482151e90795e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jun 2012 01:53:50 +0100 Subject: minor: Add a little more detail to IOException logging in XEngine.SetXMLState() Also removes superflous Close() commands for statements taking place within using() constructs Also adds some comment out debug log messages for future use. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index a9b6e67..35c338d 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1743,6 +1743,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine public bool SetXMLState(UUID itemID, string xml) { +// m_log.DebugFormat("[XEngine]: Writing state for script item with ID {0}", itemID); + if (xml == String.Empty) return false; @@ -1803,14 +1805,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine { using (FileStream fs = File.Create(path)) { +// m_log.DebugFormat("[XEngine]: Writing assembly file {0}", path); + fs.Write(filedata, 0, filedata.Length); - fs.Close(); } } catch (IOException ex) { // if there already exists a file at that location, it may be locked. - m_log.ErrorFormat("[XEngine]: File {0} already exists! {1}", path, ex.Message); + m_log.ErrorFormat("[XEngine]: Error whilst writing assembly file {0}, {1}", path, ex.Message); } string textpath = path + ".text"; @@ -1820,16 +1823,16 @@ namespace OpenSim.Region.ScriptEngine.XEngine { using (StreamWriter sw = new StreamWriter(fs)) { +// m_log.DebugFormat("[XEngine]: Writing .text file {0}", textpath); + sw.Write(base64); - sw.Close(); } - fs.Close(); } } catch (IOException ex) { // if there already exists a file at that location, it may be locked. - m_log.ErrorFormat("[XEngine]: File {0} already exists! {1}", textpath, ex.Message); + m_log.ErrorFormat("[XEngine]: Error whilst writing .text file {0}, {1}", textpath, ex.Message); } } } @@ -1843,16 +1846,16 @@ namespace OpenSim.Region.ScriptEngine.XEngine { using (StreamWriter ssw = new StreamWriter(sfs)) { +// m_log.DebugFormat("[XEngine]: Writing state file {0}", statepath); + ssw.Write(stateE.OuterXml); - ssw.Close(); } - sfs.Close(); } } catch (IOException ex) { // if there already exists a file at that location, it may be locked. - m_log.ErrorFormat("[XEngine]: File {0} already exists! {1}", statepath, ex.Message); + m_log.ErrorFormat("[XEngine]: Error whilst writing state file {0}, {1}", statepath, ex.Message); } XmlNodeList mapL = rootE.GetElementsByTagName("LineMap"); @@ -1869,16 +1872,16 @@ namespace OpenSim.Region.ScriptEngine.XEngine { using (StreamWriter msw = new StreamWriter(mfs)) { +// m_log.DebugFormat("[XEngine]: Writing linemap file {0}", mappath); + msw.Write(mapE.InnerText); - msw.Close(); } - mfs.Close(); } } catch (IOException ex) { // if there already exists a file at that location, it may be locked. - m_log.ErrorFormat("[XEngine]: File {0} already exists! {1}", mappath, ex.Message); + m_log.ErrorFormat("[XEngine]: Linemap file {0} already exists! {1}", mappath, ex.Message); } } -- cgit v1.1 From ef686ead37f475ad9e16f637fe1efc41cfbbd6f4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Jun 2012 02:11:46 +0100 Subject: Like the assembly and text files, only write the c#-lsl linemap in XEngine.SetXMLState() if the trust binaries flag is set. This doesn't affect other locations where the map is written, such as on script compilation. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 54 +++++++++++++------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 35c338d..aedf2c1 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1835,6 +1835,33 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_log.ErrorFormat("[XEngine]: Error whilst writing .text file {0}, {1}", textpath, ex.Message); } } + + XmlNodeList mapL = rootE.GetElementsByTagName("LineMap"); + if (mapL.Count > 0) + { + XmlElement mapE = (XmlElement)mapL[0]; + + string mappath = Path.Combine(m_ScriptEnginesPath, World.RegionInfo.RegionID.ToString()); + mappath = Path.Combine(mappath, mapE.GetAttribute("Filename")); + + try + { + using (FileStream mfs = File.Create(mappath)) + { + using (StreamWriter msw = new StreamWriter(mfs)) + { + // m_log.DebugFormat("[XEngine]: Writing linemap file {0}", mappath); + + msw.Write(mapE.InnerText); + } + } + } + catch (IOException ex) + { + // if there already exists a file at that location, it may be locked. + m_log.ErrorFormat("[XEngine]: Linemap file {0} already exists! {1}", mappath, ex.Message); + } + } } string statepath = Path.Combine(m_ScriptEnginesPath, World.RegionInfo.RegionID.ToString()); @@ -1858,33 +1885,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_log.ErrorFormat("[XEngine]: Error whilst writing state file {0}, {1}", statepath, ex.Message); } - XmlNodeList mapL = rootE.GetElementsByTagName("LineMap"); - if (mapL.Count > 0) - { - XmlElement mapE = (XmlElement)mapL[0]; - - string mappath = Path.Combine(m_ScriptEnginesPath, World.RegionInfo.RegionID.ToString()); - mappath = Path.Combine(mappath, mapE.GetAttribute("Filename")); - - try - { - using (FileStream mfs = File.Create(mappath)) - { - using (StreamWriter msw = new StreamWriter(mfs)) - { -// m_log.DebugFormat("[XEngine]: Writing linemap file {0}", mappath); - - msw.Write(mapE.InnerText); - } - } - } - catch (IOException ex) - { - // if there already exists a file at that location, it may be locked. - m_log.ErrorFormat("[XEngine]: Linemap file {0} already exists! {1}", mappath, ex.Message); - } - } - return true; } -- cgit v1.1 From e23d7ff9c0a2e4f106650359255f1fbe52abf21c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Jun 2012 00:05:48 +0100 Subject: minor: If logging because mesh/sculpt data isn't present for an object, log object UUID rather than local id, since UUID doesn't potentially vary between simulator starts. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 7640fc0..9303ff4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1625,7 +1625,7 @@ namespace OpenSim.Region.Framework.Scenes else m_log.WarnFormat( "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data", - Name, LocalId, id); + Name, UUID, id); } /// -- cgit v1.1 From 9737e6d52eb7ebb815accca0a1b2f3fee381e680 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Jun 2012 00:07:03 +0100 Subject: If RegionReady is active, don't falsely say that logins are enabled in the main scene loop before RegionReady is signalled when initial script compilation finishes. Also raises this logging level to Info from Debug since this information is of high importance. This matches the behaviour of the RegionReady module --- OpenSim/Region/Framework/Scenes/Scene.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 1305d83..385febf 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1474,11 +1474,11 @@ namespace OpenSim.Region.Framework.Scenes LoginLock = false; EventManager.TriggerLoginsEnabled(RegionInfo.RegionName); } - m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); // For RegionReady lockouts - if(LoginLock == false) + if (!LoginLock) { + m_log.InfoFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); LoginsDisabled = false; } -- cgit v1.1 From 0fa303b1cf244b3066395413e640318b2122c19f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Jun 2012 00:10:19 +0100 Subject: Log how many scripts are candidates for starting and how many are actually started. Adds DebugLevel infrastructure to XEngine though currently commented out and unused. --- .../Framework/Interfaces/IEntityInventory.cs | 19 +++- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 21 +++- .../Framework/Scenes/SceneObjectGroup.Inventory.cs | 18 +++- .../Framework/Scenes/SceneObjectPartInventory.cs | 110 +++++++++++---------- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 64 +++++++++++- 5 files changed, 166 insertions(+), 66 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 4370fcc..1c9bdce 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -81,7 +81,12 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Start all the scripts contained in this entity's inventory /// - void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource); + /// + /// + /// + /// + /// Number of scripts started. + int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource); ArrayList GetScriptErrors(UUID itemID); void ResumeScripts(); @@ -102,7 +107,11 @@ namespace OpenSim.Region.Framework.Interfaces /// /// /// - void CreateScriptInstance( + /// + /// true if the script instance was valid for starting, false otherwise. This does not guarantee + /// that the script was actually started, just that the script was valid (i.e. its asset data could be found, etc.) + /// + bool CreateScriptInstance( TaskInventoryItem item, int startParam, bool postOnRez, string engine, int stateSource); /// @@ -113,7 +122,11 @@ namespace OpenSim.Region.Framework.Interfaces /// /// /// - void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource); + /// + /// true if the script instance was valid for starting, false otherwise. This does not guarantee + /// that the script was actually started, just that the script was valid (i.e. its asset data could be found, etc.) + /// + bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource); /// /// Stop a script which is in this prim's inventory. diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index b59fd05..e413281 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -60,19 +60,32 @@ namespace OpenSim.Region.Framework.Scenes /// /// Creates all the scripts in the scene which should be started. /// - public void CreateScriptInstances() + /// + /// Number of scripts that were valid for starting. This does not guarantee that all these scripts + /// were actually started, but just that the start could be attempt (e.g. the asset data for the script could be found) + /// + public int CreateScriptInstances() { - m_log.Info("[PRIM INVENTORY]: Creating scripts in scene"); + m_log.InfoFormat("[SCENE]: Initializing script instances in {0}", RegionInfo.RegionName); + + int scriptsValidForStarting = 0; EntityBase[] entities = Entities.GetEntities(); foreach (EntityBase group in entities) { if (group is SceneObjectGroup) { - ((SceneObjectGroup) group).CreateScriptInstances(0, false, DefaultScriptEngine, 0); + scriptsValidForStarting + += ((SceneObjectGroup) group).CreateScriptInstances(0, false, DefaultScriptEngine, 0); ((SceneObjectGroup) group).ResumeScripts(); } } + + m_log.InfoFormat( + "[SCENE]: Initialized {0} script instances in {1}", + scriptsValidForStarting, RegionInfo.RegionName); + + return scriptsValidForStarting; } /// @@ -80,7 +93,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void StartScripts() { - m_log.Info("[PRIM INVENTORY]: Starting scripts in scene"); + m_log.InfoFormat("[SCENE]: Starting scripts in {0}, please wait.", RegionInfo.RegionName); IScriptModule[] engines = RequestModuleInterfaces(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 10012d0..2866b54 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -54,16 +54,28 @@ namespace OpenSim.Region.Framework.Scenes /// /// Start the scripts contained in all the prims in this group. /// - public void CreateScriptInstances(int startParam, bool postOnRez, - string engine, int stateSource) + /// + /// + /// + /// + /// + /// Number of scripts that were valid for starting. This does not guarantee that all these scripts + /// were actually started, but just that the start could be attempt (e.g. the asset data for the script could be found) + /// + public int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) { + int scriptsStarted = 0; + // Don't start scripts if they're turned off in the region! if (!m_scene.RegionInfo.RegionSettings.DisableScripts) { SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) - parts[i].Inventory.CreateScriptInstances(startParam, postOnRez, engine, stateSource); + scriptsStarted + += parts[i].Inventory.CreateScriptInstances(startParam, postOnRez, engine, stateSource); } + + return scriptsStarted; } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 8810903..c223474 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -217,14 +217,16 @@ namespace OpenSim.Region.Framework.Scenes } } - /// - /// Start all the scripts contained in this prim's inventory - /// - public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) + public int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) { + int scriptsValidForStarting = 0; + List scripts = GetInventoryItems(InventoryType.LSL); foreach (TaskInventoryItem item in scripts) - CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); + if (CreateScriptInstance(item, startParam, postOnRez, engine, stateSource)) + scriptsValidForStarting++; + + return scriptsValidForStarting; } public ArrayList GetScriptErrors(UUID itemID) @@ -264,61 +266,65 @@ namespace OpenSim.Region.Framework.Scenes /// Start a script which is in this prim's inventory. /// /// - /// - public void CreateScriptInstance(TaskInventoryItem item, int startParam, bool postOnRez, string engine, int stateSource) + /// true if the script instance was created, false otherwise + public bool CreateScriptInstance(TaskInventoryItem item, int startParam, bool postOnRez, string engine, int stateSource) { // m_log.DebugFormat("[PRIM INVENTORY]: Starting script {0} {1} in prim {2} {3} in {4}", // item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) - return; + return false; m_part.AddFlag(PrimFlags.Scripted); - if (!m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts) + if (m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts) + return false; + + if (stateSource == 2 && // Prim crossing + m_part.ParentGroup.Scene.m_trustBinaries) { - if (stateSource == 2 && // Prim crossing - m_part.ParentGroup.Scene.m_trustBinaries) + lock (m_items) { - lock (m_items) - { - m_items[item.ItemID].PermsMask = 0; - m_items[item.ItemID].PermsGranter = UUID.Zero; - } - - m_part.ParentGroup.Scene.EventManager.TriggerRezScript( - m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); - m_part.ParentGroup.AddActiveScriptCount(1); - m_part.ScheduleFullUpdate(); - return; + m_items[item.ItemID].PermsMask = 0; + m_items[item.ItemID].PermsGranter = UUID.Zero; } + + m_part.ParentGroup.Scene.EventManager.TriggerRezScript( + m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); + m_part.ParentGroup.AddActiveScriptCount(1); + m_part.ScheduleFullUpdate(); + return true; + } - AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); - if (null == asset) + AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); + if (null == asset) + { + m_log.ErrorFormat( + "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", + item.Name, item.ItemID, m_part.AbsolutePosition, + m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); + + return false; + } + else + { + if (m_part.ParentGroup.m_savedScriptState != null) + item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); + + lock (m_items) { - m_log.ErrorFormat( - "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", - item.Name, item.ItemID, m_part.AbsolutePosition, - m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); + m_items[item.ItemID].OldItemID = item.OldItemID; + m_items[item.ItemID].PermsMask = 0; + m_items[item.ItemID].PermsGranter = UUID.Zero; } - else - { - if (m_part.ParentGroup.m_savedScriptState != null) - item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); - lock (m_items) - { - m_items[item.ItemID].OldItemID = item.OldItemID; - m_items[item.ItemID].PermsMask = 0; - m_items[item.ItemID].PermsGranter = UUID.Zero; - } + string script = Utils.BytesToString(asset.Data); + m_part.ParentGroup.Scene.EventManager.TriggerRezScript( + m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); + m_part.ParentGroup.AddActiveScriptCount(1); + m_part.ScheduleFullUpdate(); - string script = Utils.BytesToString(asset.Data); - m_part.ParentGroup.Scene.EventManager.TriggerRezScript( - m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); - m_part.ParentGroup.AddActiveScriptCount(1); - m_part.ScheduleFullUpdate(); - } + return true; } } @@ -384,22 +390,22 @@ namespace OpenSim.Region.Framework.Scenes return stateID; } - /// - /// Start a script which is in this prim's inventory. - /// - /// - /// A - /// - public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) + public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) { TaskInventoryItem item = GetInventoryItem(itemId); if (item != null) - CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); + { + return CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); + } else + { m_log.ErrorFormat( "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", itemId, m_part.Name, m_part.UUID, m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); + + return false; + } } /// diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index aedf2c1..3f623de 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -62,6 +62,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + /// + /// Control the printing of certain debug messages. + /// + /// + /// If DebugLevel >= 1, then we log every time that a script is started. + /// +// public int DebugLevel { get; set; } + private SmartThreadPool m_ThreadPool; private int m_MaxScriptQueue; private Scene m_Scene; @@ -216,9 +224,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve; - m_log.InfoFormat("[XEngine] Initializing scripts in region {0}", - scene.RegionInfo.RegionName); m_Scene = scene; + m_log.InfoFormat("[XEngine]: Initializing scripts in region {0}", m_Scene.RegionInfo.RegionName); m_MinThreads = m_ScriptConfig.GetInt("MinThreads", 2); m_MaxThreads = m_ScriptConfig.GetInt("MaxThreads", 100); @@ -321,9 +328,42 @@ namespace OpenSim.Region.ScriptEngine.XEngine "Starts all stopped scripts." + "If a is given then only that script will be started. Otherwise, all suitable scripts are started.", (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript)); + +// MainConsole.Instance.Commands.AddCommand( +// "Debug", false, "debug xengine", "debug xengine []", +// "Turn on detailed xengine debugging.", +// "If level <= 0, then no extra logging is done.\n" +// + "If level >= 1, then we log every time that a script is started.", +// HandleDebugLevelCommand); } /// + /// Change debug level + /// + /// + /// +// private void HandleDebugLevelCommand(string module, string[] args) +// { +// if (args.Length == 3) +// { +// int newDebug; +// if (int.TryParse(args[2], out newDebug)) +// { +// DebugLevel = newDebug; +// MainConsole.Instance.OutputFormat("Debug level set to {0}", newDebug); +// } +// } +// else if (args.Length == 2) +// { +// MainConsole.Instance.OutputFormat("Current debug level is {0}", DebugLevel); +// } +// else +// { +// MainConsole.Instance.Output("Usage: debug xengine 0..1"); +// } +// } + + /// /// Parse the raw item id into a script instance from the command params if it's present. /// /// @@ -825,8 +865,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine } object[] o; + + int scriptsStarted = 0; + while (m_CompileQueue.Dequeue(out o)) - DoOnRezScript(o); + { + if (DoOnRezScript(o)) + { + scriptsStarted++; + +// if (scriptsStarted % 50 == 0) +// m_log.DebugFormat( +// "[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.RegionInfo.RegionName); + } + } + + m_log.DebugFormat( + "[XEngine]: Completed starting {0} scripts on {1}", scriptsStarted, m_Scene.RegionInfo.RegionName); // NOTE: Despite having a lockless queue, this lock is required // to make sure there is never no compile thread while there @@ -1066,7 +1121,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine part.ParentGroup.RootPart.Name, item.Name, startParam, postOnRez, stateSource, m_MaxScriptQueue); - + +// if (DebugLevel >= 1) m_log.DebugFormat( "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, -- cgit v1.1 From 881e92a7260a5823867b8f93b88c1b706a13cb56 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Jun 2012 00:19:50 +0100 Subject: Raise some IO associated Exception logging in XEngine to error level, in line with other similar cases. Remove more unnecessary Close() calls - these are being triggered by the Dispose() called when exiting the using statement for these sdk io objects. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 3f623de..35b58ee 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1715,14 +1715,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine FileMode.Open, FileAccess.Read)) { tfs.Read(tdata, 0, tdata.Length); - tfs.Close(); } assem = new System.Text.ASCIIEncoding().GetString(tdata); } catch (Exception e) { - m_log.DebugFormat("[XEngine]: Unable to open script textfile {0}, reason: {1}", assemName+".text", e.Message); + m_log.ErrorFormat( + "[XEngine]: Unable to open script textfile {0}{1}, reason: {2}", + assemName, ".text", e.Message); } } } @@ -1739,16 +1740,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine using (FileStream fs = File.Open(assemName, FileMode.Open, FileAccess.Read)) { fs.Read(data, 0, data.Length); - fs.Close(); } assem = System.Convert.ToBase64String(data); } catch (Exception e) { - m_log.DebugFormat("[XEngine]: Unable to open script assembly {0}, reason: {1}", assemName, e.Message); + m_log.ErrorFormat( + "[XEngine]: Unable to open script assembly {0}, reason: {1}", assemName, e.Message); } - } } @@ -1761,9 +1761,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine using (StreamReader msr = new StreamReader(mfs)) { map = msr.ReadToEnd(); - msr.Close(); } - mfs.Close(); } } -- cgit v1.1 From 625e5e913a52b26f9af343d6c5bb33c3f8a4ead8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Jun 2012 00:24:39 +0100 Subject: Comment out recently added log message detailing number of scripts started when compile queue empties for now --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 35b58ee..e961e76 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -880,8 +880,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine } } - m_log.DebugFormat( - "[XEngine]: Completed starting {0} scripts on {1}", scriptsStarted, m_Scene.RegionInfo.RegionName); +// m_log.DebugFormat( +// "[XEngine]: Completed starting {0} scripts on {1}", scriptsStarted, m_Scene.RegionInfo.RegionName); // NOTE: Despite having a lockless queue, this lock is required // to make sure there is never no compile thread while there -- cgit v1.1 From 6b3f9fcde00c9581e5d4f74df2b21ff6bd303f63 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Jun 2012 00:42:54 +0100 Subject: Comment out the neighbour and land in connectors from info logging that they are starting up --- OpenSim/Framework/Servers/BaseOpenSimServer.cs | 2 +- .../ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs | 2 +- .../ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 06a8021..88c3ebb 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -320,7 +320,7 @@ namespace OpenSim.Framework.Servers TimeSpan timeTaken = DateTime.Now - m_startuptime; - m_log.InfoFormat("[STARTUP]: Startup took {0}m {1}s", timeTaken.Minutes, timeTaken.Seconds); +// m_log.InfoFormat("[STARTUP]: Startup took {0}m {1}s", timeTaken.Minutes, timeTaken.Seconds); } /// diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs index c8f45f6..2f3c350 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs @@ -75,7 +75,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Land if (!m_Enabled) return; - m_log.Info("[LAND IN CONNECTOR]: Starting..."); +// m_log.Info("[LAND IN CONNECTOR]: Starting..."); } public void Close() diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs index 3fd89b9..b544ab3 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs @@ -74,7 +74,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Neighbour if (!m_Enabled) return; - m_log.Info("[NEIGHBOUR IN CONNECTOR]: Starting..."); +// m_log.Info("[NEIGHBOUR IN CONNECTOR]: Starting..."); } public void Close() -- cgit v1.1 From 4cfaa01c0a5e36f4414141a38541067460121a9b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Jun 2012 01:06:55 +0100 Subject: Remove STARTUP COMPLETE message from the startuplogo.txt file and into main logging --- OpenSim/Framework/Servers/BaseOpenSimServer.cs | 4 +++- bin/startuplogo.txt | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 88c3ebb..62ea9e3 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -320,7 +320,9 @@ namespace OpenSim.Framework.Servers TimeSpan timeTaken = DateTime.Now - m_startuptime; -// m_log.InfoFormat("[STARTUP]: Startup took {0}m {1}s", timeTaken.Minutes, timeTaken.Seconds); + m_log.InfoFormat( + "[STARTUP]: Non-script portion of startup took {0}m {1}s. PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS.", + timeTaken.Minutes, timeTaken.Seconds); } /// diff --git a/bin/startuplogo.txt b/bin/startuplogo.txt index 0d11e77..e69de29 100644 --- a/bin/startuplogo.txt +++ b/bin/startuplogo.txt @@ -1 +0,0 @@ -STARTUP COMPLETE -- cgit v1.1 From 7b6c0232a54c4c083e16c028fd475121b20b8bff Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Jun 2012 01:10:18 +0100 Subject: Change default logging level for XEngine to WARN instead of DEBUG. This is to reduce log spam from script loading, which is especially spammy for avatar movements with scripted attachments. All important messages are at warn or above. If you still want/need to see these messages, set in the section of OpenSim.exe.config. This affects no other package logs, which still output at the root configured level (currently DEBUG by default). --- bin/OpenSim.exe.config | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bin/OpenSim.exe.config b/bin/OpenSim.exe.config index 4a49fc5..f1e3709 100755 --- a/bin/OpenSim.exe.config +++ b/bin/OpenSim.exe.config @@ -31,5 +31,10 @@ + + + + + -- cgit v1.1 From 6c312bce7f12efa856ad0e86662c4cffc56a1e75 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Jun 2012 01:28:55 +0100 Subject: minor: Lower flotsam asset cache warning about not having a FlotsamCache.ini to debug It's perfectly okay not to have this section. --- OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index dd6026b..fab489d 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -143,7 +143,7 @@ namespace Flotsam.RegionModules.AssetCache IConfig assetConfig = source.Configs["AssetCache"]; if (assetConfig == null) { - m_log.Warn( + m_log.Debug( "[FLOTSAM ASSET CACHE]: AssetCache section missing from config (not copied config-include/FlotsamCache.ini.example? Using defaults."); } else -- cgit v1.1 From 9ec9dafae6d8de93332c510ee7fa0159059dd983 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Jun 2012 01:33:25 +0100 Subject: Lower warn logging on not having friends/group module on permissions to debug. It's a valid configuration not to have these modules, but I think it's still worth logging the fact that certain permissions won't work (always return true) --- OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 4f72463..7a8a57c 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -348,12 +348,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions m_friendsModule = m_scene.RequestModuleInterface(); if (m_friendsModule == null) - m_log.Warn("[PERMISSIONS]: Friends module not found, friend permissions will not work"); + m_log.Debug("[PERMISSIONS]: Friends module not found, friend permissions will not work"); m_groupsModule = m_scene.RequestModuleInterface(); if (m_groupsModule == null) - m_log.Warn("[PERMISSIONS]: Groups module not found, group permissions will not work"); + m_log.Debug("[PERMISSIONS]: Groups module not found, group permissions will not work"); m_moapModule = m_scene.RequestModuleInterface(); -- cgit v1.1 From b23425c7c499d423235a724bc10c2cccc823132c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Jun 2012 02:26:58 +0100 Subject: As with LLSDInventoryItem from commit 01a2b0b, send type values in LLSDInventoryFolder for inventory CAPs as integers rather than strings. Should also resolve some issues with exceptions being thrown in some inventory fetches. --- .../WebFetchInventoryDescendents/WebFetchInvDescHandler.cs | 8 ++------ OpenSim/Capabilities/LLSDInventoryFolder.cs | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs index 849cad2..515637e 100644 --- a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs +++ b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs @@ -393,12 +393,8 @@ namespace OpenSim.Capabilities.Handlers llsdFolder.folder_id = invFolder.ID; llsdFolder.parent_id = invFolder.ParentID; llsdFolder.name = invFolder.Name; - - if (invFolder.Type == (short)AssetType.Unknown || !Enum.IsDefined(typeof(AssetType), (sbyte)invFolder.Type)) - llsdFolder.type = "-1"; - else - llsdFolder.type = Utils.AssetTypeToString((AssetType)invFolder.Type); - llsdFolder.preferred_type = "-1"; + llsdFolder.type = invFolder.Type; + llsdFolder.preferred_type = -1; return llsdFolder; } diff --git a/OpenSim/Capabilities/LLSDInventoryFolder.cs b/OpenSim/Capabilities/LLSDInventoryFolder.cs index 3c216e9..d085430 100644 --- a/OpenSim/Capabilities/LLSDInventoryFolder.cs +++ b/OpenSim/Capabilities/LLSDInventoryFolder.cs @@ -35,7 +35,7 @@ namespace OpenSim.Framework.Capabilities public UUID folder_id; public UUID parent_id; public string name; - public string type; - public string preferred_type; + public int type; + public int preferred_type; } } -- cgit v1.1 From 714db90832522d8035df744594afd07b227af232 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Jun 2012 22:46:01 +0100 Subject: refactor: use SOG.HasPrivateAttachmentPoint in SOP.SendTerseUpdateToClient() instead of attachmentpoint magic numbers. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 9303ff4..3d81358 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4431,8 +4431,9 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup.IsDeleted) return; - if (ParentGroup.IsAttachment && ((ParentGroup.RootPart != this) || - ((ParentGroup.AttachedAvatar != remoteClient.AgentId) && (ParentGroup.AttachmentPoint >= 31) && (ParentGroup.AttachmentPoint <= 38)))) + if (ParentGroup.IsAttachment + && (ParentGroup.RootPart != this + || ParentGroup.AttachedAvatar != remoteClient.AgentId && ParentGroup.HasPrivateAttachmentPoint)) return; // Causes this thread to dig into the Client Thread Data. -- cgit v1.1 From 68ea096f1b1276e09510633d48313d6e870d0d97 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Jun 2012 23:25:07 +0100 Subject: Use HasPrivateAttachmentPoint properties in SOG.DeleteGroupFromScene() instead of magic numbers --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 619296e..18877c1e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1205,8 +1205,9 @@ namespace OpenSim.Region.Framework.Scenes part.ClearUpdateSchedule(); if (part == m_rootPart) { - if (!IsAttachment || (AttachedAvatar == avatar.ControllingClient.AgentId) || - (AttachmentPoint < 31) || (AttachmentPoint > 38)) + if (!IsAttachment + || AttachedAvatar == avatar.ControllingClient.AgentId + || !HasPrivateAttachmentPoint) avatar.ControllingClient.SendKillObject(m_regionHandle, new List { part.LocalId }); } } -- cgit v1.1 From 5709bed548aa4897d84bb616a2c344e158fe89ff Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 21 Jun 2012 02:09:14 +0100 Subject: Add state file location to errors logged when there's some issue with retrieving state (e.g. exceeds memory limit) --- OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 329e361..b8bcb35 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -331,15 +331,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance else { m_log.ErrorFormat( - "[SCRIPT INSTANCE]: Unable to load script state from assembly {0}: Memory limit exceeded", - assembly); + "[SCRIPT INSTANCE]: Unable to load script state file {0} from assembly {1}: Memory limit exceeded", + savedState, assembly); } } catch (Exception e) { m_log.ErrorFormat( - "[SCRIPT INSTANCE]: Unable to load script state from assembly {0}. XML is {1}. Exception {2}{3}", - assembly, xml, e.Message, e.StackTrace); + "[SCRIPT INSTANCE]: Unable to load script state file {0} from assembly {1}. XML is {2}. Exception {3}{4}", + savedState, assembly, xml, e.Message, e.StackTrace); } } // else -- cgit v1.1 From afcabf5244415f2d78391cb03269dc9979b5b3d2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 21 Jun 2012 02:13:03 +0100 Subject: Retrigger build - last jenkins run was glitched --- OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index b8bcb35..8c53b1f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -354,7 +354,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public void Init() { - if (!m_startOnInit) return; + if (!m_startOnInit) + return; if (m_startedFromSavedState) { -- cgit v1.1 From d24122b706cb3ec4ac9c8d1efc30e511a07e1aa7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 21 Jun 2012 02:24:44 +0100 Subject: Add item id, name, prim name and id to log message when state exists but loading fails. Drop logging about memory limit exceeded to warn from error --- OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 8c53b1f..5dfe58e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -330,16 +330,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance } else { - m_log.ErrorFormat( - "[SCRIPT INSTANCE]: Unable to load script state file {0} from assembly {1}: Memory limit exceeded", - savedState, assembly); + m_log.WarnFormat( + "[SCRIPT INSTANCE]: Unable to load script state file {0} for script {1} {2} in {3} {4} (assembly {5}). Memory limit exceeded", + savedState, ScriptName, ItemID, PrimName, ObjectID, assembly); } } catch (Exception e) { m_log.ErrorFormat( - "[SCRIPT INSTANCE]: Unable to load script state file {0} from assembly {1}. XML is {2}. Exception {3}{4}", - savedState, assembly, xml, e.Message, e.StackTrace); + "[SCRIPT INSTANCE]: Unable to load script state file {0} for script {1} {2} in {3} {4} (assembly {5}). XML is {6}. Exception {7}{8}", + savedState, ScriptName, ItemID, PrimName, ObjectID, assembly, xml, e.Message, e.StackTrace); } } // else -- cgit v1.1 From 06617ffd06c743cebffa768bc56a979f473b5b5b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Jun 2012 00:18:30 +0100 Subject: Add regression test for updating attachment position --- .../Attachments/Tests/AttachmentsModuleTests.cs | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 5e89eec..94c0030 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -303,6 +303,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); } + [Test] + public void TestUpdateAttachmentPosition() + { + TestHelpers.InMethod(); + + UUID userId = TestHelpers.ParseTail(0x1); + UUID attItemId = TestHelpers.ParseTail(0x2); + UUID attAssetId = TestHelpers.ParseTail(0x3); + string attName = "att"; + + UserAccountHelpers.CreateUserWithInventory(scene, userId); + InventoryItemBase attItem + = UserInventoryHelpers.CreateInventoryItem( + scene, attName, attItemId, attAssetId, userId, InventoryType.Object); + + AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); + acd.Appearance = new AvatarAppearance(); + acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, acd); + + SceneObjectGroup attSo = sp.GetAttachments()[0]; + + Vector3 newPosition = new Vector3(1, 2, 4); + + scene.SceneGraph.UpdatePrimGroupPosition(attSo.LocalId, newPosition, sp.ControllingClient); + + Assert.That(attSo.AbsolutePosition, Is.EqualTo(sp.AbsolutePosition)); + Assert.That(attSo.RootPart.AttachedPos, Is.EqualTo(newPosition)); + } + // I'm commenting this test because scene setup NEEDS InventoryService to // be non-null //[Test] -- cgit v1.1 From 798846c5b6c05f37c661dde70fb9aaf51306e407 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Jun 2012 00:39:41 +0100 Subject: refactor AttachmentsModule tests to use a common method for standard attachment item setup --- .../Attachments/Tests/AttachmentsModuleTests.cs | 139 ++++++++++----------- 1 file changed, 69 insertions(+), 70 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 94c0030..8f4a807 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -58,6 +58,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests private AttachmentsModule m_attMod; private ScenePresence m_presence; + /// + /// Standard user ID + /// + private UUID m_userId = TestHelpers.ParseTail(0x1); + +// /// +// /// Standard attachment item ID +// /// +// private UUID m_attItemId = TestHelpers.ParseTail(0x10); +// +// /// +// /// Standard attachment asset ID +// /// +// private UUID m_attAssetId = TestHelpers.ParseTail(0x11); + [TestFixtureSetUp] public void FixtureInit() { @@ -86,13 +101,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests } /// - /// Add the standard presence for a test. + /// Creates an attachment item in the given user's inventory. Does not attach. /// - private void AddPresence() + /// + /// A user with the given ID and an inventory must already exist. + /// + /// + /// The attachment item. + /// + /// + /// + /// + /// + private InventoryItemBase CreateAttachmentItem(UUID userId, string attName, int rawItemId, int rawAssetId) { - UUID userId = TestHelpers.ParseTail(0x1); - UserAccountHelpers.CreateUserWithInventory(scene, userId); - m_presence = SceneHelpers.AddScenePresence(scene, userId); + return UserInventoryHelpers.CreateInventoryItem( + scene, + attName, + TestHelpers.ParseTail(rawItemId), + TestHelpers.ParseTail(rawAssetId), + userId, + InventoryType.Object); } [Test] @@ -101,7 +130,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); - AddPresence(); + UserAccountHelpers.CreateUserWithInventory(scene, m_userId); + m_presence = SceneHelpers.AddScenePresence(scene, m_userId); + string attName = "att"; SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, m_presence.UUID).ParentGroup; @@ -140,24 +171,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - AddPresence(); - - UUID attItemId = TestHelpers.ParseTail(0x2); - UUID attAssetId = TestHelpers.ParseTail(0x3); - string attName = "att"; + UserAccountHelpers.CreateUserWithInventory(scene, m_userId); + m_presence = SceneHelpers.AddScenePresence(scene, m_userId); - UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); + InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); m_attMod.RezSingleAttachmentFromInventory( - m_presence, attItemId, (uint)AttachmentPoint.Chest); + m_presence, attItem.ID, (uint)AttachmentPoint.Chest); // Check scene presence status Assert.That(m_presence.HasAttachments(), Is.True); List attachments = m_presence.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; - Assert.That(attSo.Name, Is.EqualTo(attName)); + Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); @@ -165,7 +192,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Check appearance status Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(1)); - Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); + Assert.That(m_presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); } [Test] @@ -174,17 +201,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - AddPresence(); - - UUID attItemId = TestHelpers.ParseTail(0x2); - UUID attAssetId = TestHelpers.ParseTail(0x3); - string attName = "att"; + UserAccountHelpers.CreateUserWithInventory(scene, m_userId); + m_presence = SceneHelpers.AddScenePresence(scene, m_userId); - UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); + InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); - ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory( - m_presence, attItemId, (uint)AttachmentPoint.Chest); + ISceneEntity so + = m_attMod.RezSingleAttachmentFromInventory( + m_presence, attItem.ID, (uint)AttachmentPoint.Chest); m_attMod.DetachSingleAttachmentToGround(m_presence, so.LocalId); // Check scene presence status @@ -196,7 +220,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(0)); // Check item status - Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItemId)), Is.Null); + Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItem.ID)), Is.Null); // Check object in scene Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null); @@ -208,18 +232,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - AddPresence(); - - UUID attItemId = TestHelpers.ParseTail(0x2); - UUID attAssetId = TestHelpers.ParseTail(0x3); - string attName = "att"; + UserAccountHelpers.CreateUserWithInventory(scene, m_userId); + m_presence = SceneHelpers.AddScenePresence(scene, m_userId); - UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); + InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); m_attMod.RezSingleAttachmentFromInventory( - m_presence, attItemId, (uint)AttachmentPoint.Chest); - m_attMod.DetachSingleAttachmentToInv(m_presence, attItemId); + m_presence, attItem.ID, (uint)AttachmentPoint.Chest); + m_attMod.DetachSingleAttachmentToInv(m_presence, attItem.ID); // Check status on scene presence Assert.That(m_presence.HasAttachments(), Is.False); @@ -227,7 +247,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attachments.Count, Is.EqualTo(0)); // Check item status - Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0)); + Assert.That(m_presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo(0)); } /// @@ -239,17 +259,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - UUID userId = TestHelpers.ParseTail(0x1); - UUID attItemId = TestHelpers.ParseTail(0x2); - UUID attAssetId = TestHelpers.ParseTail(0x3); - string attName = "att"; - - UserAccountHelpers.CreateUserWithInventory(scene, userId); - InventoryItemBase attItem - = UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, userId, InventoryType.Object); + UserAccountHelpers.CreateUserWithInventory(scene, m_userId); + InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); - AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); + AgentCircuitData acd = SceneHelpers.GenerateAgentData(m_userId); acd.Appearance = new AvatarAppearance(); acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); @@ -268,17 +281,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - UUID userId = TestHelpers.ParseTail(0x1); - UUID attItemId = TestHelpers.ParseTail(0x2); - UUID attAssetId = TestHelpers.ParseTail(0x3); - string attName = "att"; - - UserAccountHelpers.CreateUserWithInventory(scene, userId); - InventoryItemBase attItem - = UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, userId, InventoryType.Object); + UserAccountHelpers.CreateUserWithInventory(scene, m_userId); + InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); - AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); + AgentCircuitData acd = SceneHelpers.GenerateAgentData(m_userId); acd.Appearance = new AvatarAppearance(); acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); @@ -288,7 +294,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; - Assert.That(attSo.Name, Is.EqualTo(attName)); + Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); @@ -298,9 +304,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests List retreivedAttachments = presence.Appearance.GetAttachments(); Assert.That(retreivedAttachments.Count, Is.EqualTo(1)); Assert.That(retreivedAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest)); - Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItemId)); - Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attAssetId)); - Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); + Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItem.ID)); + Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attItem.AssetID)); + Assert.That(presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); } [Test] @@ -308,17 +314,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests { TestHelpers.InMethod(); - UUID userId = TestHelpers.ParseTail(0x1); - UUID attItemId = TestHelpers.ParseTail(0x2); - UUID attAssetId = TestHelpers.ParseTail(0x3); - string attName = "att"; - - UserAccountHelpers.CreateUserWithInventory(scene, userId); - InventoryItemBase attItem - = UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, userId, InventoryType.Object); + UserAccountHelpers.CreateUserWithInventory(scene, m_userId); + InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); - AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); + AgentCircuitData acd = SceneHelpers.GenerateAgentData(m_userId); acd.Appearance = new AvatarAppearance(); acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); ScenePresence sp = SceneHelpers.AddScenePresence(scene, acd); -- cgit v1.1 From fda39c11bf8e440414f44e8233aa67818da51036 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Jun 2012 01:33:27 +0100 Subject: Fix bug where attachments would not retain position if just rotated and not moved. This was because we were not setting AttachedPos in SOG.UpdateGroupPositionPR, unlike UpdateGroupPosition --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 18877c1e..1e900a0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2911,6 +2911,11 @@ namespace OpenSim.Region.Framework.Scenes m_scene.PhysicsScene.AddPhysicsActorTaint(actor); } + if (IsAttachment) + { + m_rootPart.AttachedPos = pos; + } + AbsolutePosition = pos; HasGroupChanged = true; -- cgit v1.1 From 4cf49369b51c21a0eadd719eb46f53d207e1e5f7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Jun 2012 01:39:39 +0100 Subject: Stop flicking IsAttachment false and then true in AttachmentsModule.UpdateAttachmentPosition() in order to avoid a hud update race condition. Previously, setting IsAttachment to false then true was necessary to serialize the updated attachment object information. However, UpdateAttachmentPosition no longer does this update. Whilst IsAttachment is set to false there is a race condition where the update thread can wrongly send hud object updates to clients that do not own the hud, resulting in screen artifacts. --- .../Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index b74c0ba..a2b95eb 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -408,17 +408,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (!Enabled) return; - // First we save the - // attachment point information, then we update the relative - // positioning. Then we have to mark the object as NOT an - // attachment. This is necessary in order to correctly save - // and retrieve GroupPosition information for the attachment. - // Finally, we restore the object's attachment status. - uint attachmentPoint = sog.AttachmentPoint; sog.UpdateGroupPosition(pos); - sog.IsAttachment = false; - sog.AbsolutePosition = sog.RootPart.AttachedPos; - sog.AttachmentPoint = attachmentPoint; sog.HasGroupChanged = true; } -- cgit v1.1 From f907182ab28cd761bebd398dab38f9a997ecd19d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Jun 2012 01:57:14 +0100 Subject: Eliminate unnecessary extra call to TriggerEmptyScriptCompileQueue in XEngine.DoOnRezScriptQueue() The later invocation of this function will happen on an empty compile queue. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index e961e76..26df758 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -855,13 +855,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine { m_InitialStartup = false; System.Threading.Thread.Sleep(15000); - - if (m_CompileQueue.Count == 0) - { - // No scripts on region, so won't get triggered later - // by the queue becoming empty so we trigger it here - m_Scene.EventManager.TriggerEmptyScriptCompileQueue(0, String.Empty); - } } object[] o; @@ -889,11 +882,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine // due to a race condition // lock (m_CompileQueue) - { m_CurrentCompile = null; - } + m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount, m_ScriptErrorMessage); + m_ScriptFailCount = 0; return null; -- cgit v1.1 From 9f3feeff8d3a00b965b2151477df5b0b2de3ff1d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Jun 2012 02:10:27 +0100 Subject: If starting scripts on initial sim start, provide INFO level log feedback each time 50 scripts have been started. This is to provide an indication of what's happening now that the default isn't to report every single script start. Changes XEngine logging level in OpenSim.exe.config from WARN to INFO. --- OpenSim/Framework/Servers/BaseOpenSimServer.cs | 2 +- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 16 ++++++++++------ bin/OpenSim.exe.config | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 62ea9e3..9459f76 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -321,7 +321,7 @@ namespace OpenSim.Framework.Servers TimeSpan timeTaken = DateTime.Now - m_startuptime; m_log.InfoFormat( - "[STARTUP]: Non-script portion of startup took {0}m {1}s. PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS.", + "[STARTUP]: Non-script portion of startup took {0}m {1}s. PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS ONCE SCRIPTS HAVE STARTED.", timeTaken.Minutes, timeTaken.Seconds); } diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 26df758..40f48e3 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -853,7 +853,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine { if (m_InitialStartup) { - m_InitialStartup = false; + // This delay exists to stop mono problems where script compilation and startup would stop the sim + // working properly for the session. System.Threading.Thread.Sleep(15000); } @@ -867,14 +868,16 @@ namespace OpenSim.Region.ScriptEngine.XEngine { scriptsStarted++; -// if (scriptsStarted % 50 == 0) -// m_log.DebugFormat( -// "[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.RegionInfo.RegionName); + if (m_InitialStartup) + if (scriptsStarted % 50 == 0) + m_log.InfoFormat( + "[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.RegionInfo.RegionName); } } -// m_log.DebugFormat( -// "[XEngine]: Completed starting {0} scripts on {1}", scriptsStarted, m_Scene.RegionInfo.RegionName); + if (m_InitialStartup) + m_log.InfoFormat( + "[XEngine]: Completed starting {0} scripts on {1}", scriptsStarted, m_Scene.RegionInfo.RegionName); // NOTE: Despite having a lockless queue, this lock is required // to make sure there is never no compile thread while there @@ -888,6 +891,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_ScriptErrorMessage); m_ScriptFailCount = 0; + m_InitialStartup = false; return null; } diff --git a/bin/OpenSim.exe.config b/bin/OpenSim.exe.config index f1e3709..e3107ab 100755 --- a/bin/OpenSim.exe.config +++ b/bin/OpenSim.exe.config @@ -33,7 +33,7 @@ - + -- cgit v1.1 From 80a41e670dd9bbd2771fbcf250362cefa2797306 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Jun 2012 02:23:25 +0100 Subject: Avoid race condition between m_PrimObjects iteration in XEngine.PostObjectEvent and places where the list is modified by extending the m_PrimObjects lock. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 40f48e3..25b27b9 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1363,22 +1363,22 @@ namespace OpenSim.Region.ScriptEngine.XEngine return false; uuids = m_PrimObjects[localID]; - } - foreach (UUID itemID in uuids) - { - IScriptInstance instance = null; - try - { - if (m_Scripts.ContainsKey(itemID)) - instance = m_Scripts[itemID]; - } - catch { /* ignore race conditions */ } - - if (instance != null) + foreach (UUID itemID in uuids) { - instance.PostEvent(p); - result = true; + IScriptInstance instance = null; + try + { + if (m_Scripts.ContainsKey(itemID)) + instance = m_Scripts[itemID]; + } + catch { /* ignore race conditions */ } + + if (instance != null) + { + instance.PostEvent(p); + result = true; + } } } -- cgit v1.1 From dca04c7b61abb7b7ea70299a192425ce3bd05937 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Jun 2012 23:16:18 +0100 Subject: Avoid a race condition where an incoming request to a script external URL can trigger an exception is the URL was being removed at the same time. This involves three steps 1) Return gracefully in UrlModule.HttpRequestHandler() instead of throwing an exception when the url cannot be found in its index 2) Return true instead of false in HasEvents() if no matching request is found in the map. This call will only happen in the first place for raced requests. 3) Return a 404 in GetEvents() if the request is not in the index, rather than a blank 200 OK. Many thanks to Tom Haines in http://opensimulator.org/mantis/view.php?id=6051 for doing some of the work on this. --- .../Servers/HttpServer/PollServiceEventArgs.cs | 9 +- .../Servers/HttpServer/PollServiceHttpRequest.cs | 7 +- .../CoreModules/Scripting/LSLHttp/UrlModule.cs | 108 ++++++++++++++------- 3 files changed, 84 insertions(+), 40 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs index 9d512c6..3089351 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using OpenMetaverse; + namespace OpenSim.Framework.Servers.HttpServer { public delegate void RequestMethod(UUID requestID, Hashtable request); @@ -44,7 +45,11 @@ namespace OpenSim.Framework.Servers.HttpServer public NoEventsMethod NoEvents; public RequestMethod Request; public UUID Id; - public PollServiceEventArgs(RequestMethod pRequest, HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,UUID pId) + + public PollServiceEventArgs( + RequestMethod pRequest, + HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, + UUID pId) { Request = pRequest; HasEvents = pHasEvents; @@ -53,4 +58,4 @@ namespace OpenSim.Framework.Servers.HttpServer Id = pId; } } -} +} \ No newline at end of file diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs index 553a7eb..723530a 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs @@ -31,7 +31,6 @@ using OpenMetaverse; namespace OpenSim.Framework.Servers.HttpServer { - public class PollServiceHttpRequest { public readonly PollServiceEventArgs PollServiceArgs; @@ -39,7 +38,9 @@ namespace OpenSim.Framework.Servers.HttpServer public readonly IHttpRequest Request; public readonly int RequestTime; public readonly UUID RequestID; - public PollServiceHttpRequest(PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest) + + public PollServiceHttpRequest( + PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest) { PollServiceArgs = pPollServiceArgs; HttpContext = pHttpContext; @@ -48,4 +49,4 @@ namespace OpenSim.Framework.Servers.HttpServer RequestID = UUID.Random(); } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 61afc76..5c05500 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -64,17 +64,25 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp public string uri; } + /// + /// This module provides external URLs for in-world scripts. + /// public class UrlModule : ISharedRegionModule, IUrlModule { private static readonly ILog m_log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); - private Dictionary m_RequestMap = - new Dictionary(); + /// + /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the request ID + /// randomly generated when a request is received for this URL. + /// + private Dictionary m_RequestMap = new Dictionary(); - private Dictionary m_UrlMap = - new Dictionary(); + /// + /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the full URL + /// + private Dictionary m_UrlMap = new Dictionary(); /// /// Maximum number of external urls that can be set up by this module. @@ -224,7 +232,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp urlData.urlcode = urlcode; urlData.requests = new Dictionary(); - m_UrlMap[url] = urlData; string uri = "/lslhttps/" + urlcode.ToString() + "/"; @@ -286,7 +293,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp { if (m_RequestMap.ContainsKey(requestId)) { - UrlData urlData=m_RequestMap[requestId]; + UrlData urlData = m_RequestMap[requestId]; string value; if (urlData.requests[requestId].headers.TryGetValue(header,out value)) return value; @@ -295,6 +302,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp { m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId); } + return String.Empty; } @@ -339,6 +347,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp { RemoveUrl(url.Value); removeURLs.Add(url.Key); + foreach (UUID req in url.Value.requests.Keys) m_RequestMap.Remove(req); } @@ -349,20 +358,31 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp } } - private void RemoveUrl(UrlData data) { - m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/"); + m_HttpServer.RemoveHTTPHandler("", "/lslhttp/" + data.urlcode.ToString() + "/"); } private Hashtable NoEvents(UUID requestID, UUID sessionID) { Hashtable response = new Hashtable(); UrlData url; + lock (m_RequestMap) { + // We need to return a 404 here in case the request URL was removed at exactly the same time that a + // request was made. In this case, the request thread can outrace llRemoveURL() and still be polling + // for the request ID. if (!m_RequestMap.ContainsKey(requestID)) + { + response["int_response_code"] = 404; + response["str_response_string"] = ""; + response["keepalive"] = false; + response["reusecontext"] = false; + return response; + } + url = m_RequestMap[requestID]; } @@ -384,53 +404,57 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp return response; } - return response; } private bool HasEvents(UUID requestID, UUID sessionID) { - UrlData url=null; + UrlData url = null; lock (m_RequestMap) { + // We return true here because an external URL request that happened at the same time as an llRemoveURL() + // can still make it through to HttpRequestHandler(). That will return without setting up a request + // when it detects that the URL has been removed. The poller, however, will continue to ask for + // events for that request, so here we will signal that there are events and in GetEvents we will + // return a 404. if (!m_RequestMap.ContainsKey(requestID)) { - return false; + return true; } + url = m_RequestMap[requestID]; if (!url.requests.ContainsKey(requestID)) { - return false; + return true; } } - if (System.Environment.TickCount-url.requests[requestID].startTime>25000) + // Trigger return of timeout response. + if (System.Environment.TickCount - url.requests[requestID].startTime > 25000) { return true; } - if (url.requests[requestID].requestDone) - return true; - else - return false; - + return url.requests[requestID].requestDone; } + private Hashtable GetEvents(UUID requestID, UUID sessionID, string request) { - UrlData url = null; + UrlData url = null; RequestData requestData = null; lock (m_RequestMap) { if (!m_RequestMap.ContainsKey(requestID)) - return NoEvents(requestID,sessionID); + return NoEvents(requestID, sessionID); + url = m_RequestMap[requestID]; requestData = url.requests[requestID]; } if (!requestData.requestDone) - return NoEvents(requestID,sessionID); + return NoEvents(requestID, sessionID); Hashtable response = new Hashtable(); @@ -443,6 +467,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp response["reusecontext"] = false; return response; } + //put response response["int_response_code"] = requestData.responseCode; response["str_response_string"] = requestData.responseBody; @@ -459,6 +484,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp return response; } + public void HttpRequestHandler(UUID requestID, Hashtable request) { lock (request) @@ -483,11 +509,22 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp pathInfo = uri.Substring(pos3); - UrlData url = null; - if (!is_ssl) - url = m_UrlMap["http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp]; - else - url = m_UrlMap["https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp]; + UrlData urlData = null; + + lock (m_UrlMap) + { + string url; + + if (is_ssl) + url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; + else + url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; + + // Avoid a race - the request URL may have been released via llRequestUrl() whilst this + // request was being processed. + if (!m_UrlMap.TryGetValue(url, out urlData)) + return; + } //for llGetHttpHeader support we need to store original URI here //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers @@ -520,11 +557,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp queryString = queryString + key + "=" + val + "&"; } } + if (queryString.Length > 1) queryString = queryString.Substring(0, queryString.Length - 1); - } - } //if this machine is behind DNAT/port forwarding, currently this is being @@ -532,26 +568,28 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"]; requestData.headers["x-path-info"] = pathInfo; requestData.headers["x-query-string"] = queryString; - requestData.headers["x-script-url"] = url.url; + requestData.headers["x-script-url"] = urlData.url; //requestData.ev = new ManualResetEvent(false); - lock (url.requests) + lock (urlData.requests) { - url.requests.Add(requestID, requestData); + urlData.requests.Add(requestID, requestData); } + lock (m_RequestMap) { - //add to request map - m_RequestMap.Add(requestID, url); + m_RequestMap.Add(requestID, urlData); } - url.engine.PostScriptEvent(url.itemID, "http_request", new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() }); + urlData.engine.PostScriptEvent( + urlData.itemID, + "http_request", + new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() }); //send initial response? // Hashtable response = new Hashtable(); return; - } catch (Exception we) { -- cgit v1.1 From 78143769bfdf316bbec63e6232bf9be993eb078a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Jun 2012 23:49:52 +0100 Subject: Resolve various race conditions between accessing and removing external script URLs by more consistently locking on m_UrlMap --- .../CoreModules/Scripting/LSLHttp/UrlModule.cs | 280 +++++++++++---------- 1 file changed, 148 insertions(+), 132 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 5c05500..05d54f0 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -41,13 +41,39 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Scripting.LSLHttp { + /// + /// Data describing an external URL set up by a script. + /// public class UrlData { + /// + /// Scene object part hosting the script + /// public UUID hostID; + + /// + /// The item ID of the script that requested the URL. + /// public UUID itemID; + + /// + /// The script engine that runs the script. + /// public IScriptModule engine; + + /// + /// The generated URL. + /// public string url; + + /// + /// The random UUID component of the generated URL. + /// public UUID urlcode; + + /// + /// The external requests currently being processed or awaiting retrieval for this URL. + /// public Dictionary requests; } @@ -77,6 +103,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the request ID /// randomly generated when a request is received for this URL. /// + /// + /// Manipulation or retrieval from this dictionary must be locked on m_UrlMap to preserve consistency with + /// m_UrlMap + /// private Dictionary m_RequestMap = new Dictionary(); /// @@ -113,10 +143,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp { m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName); bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener",false); + if (ssl_enabled) - { https_port = (uint) config.Configs["Network"].GetInt("https_port",0); - } IConfig llFunctionsConfig = config.Configs["LL-Functions"]; @@ -275,32 +304,38 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp public void HttpResponse(UUID request, int status, string body) { - if (m_RequestMap.ContainsKey(request)) - { - UrlData urlData = m_RequestMap[request]; - urlData.requests[request].responseCode = status; - urlData.requests[request].responseBody = body; - //urlData.requests[request].ev.Set(); - urlData.requests[request].requestDone =true; - } - else + lock (m_UrlMap) { - m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString()); + if (m_RequestMap.ContainsKey(request)) + { + UrlData urlData = m_RequestMap[request]; + urlData.requests[request].responseCode = status; + urlData.requests[request].responseBody = body; + //urlData.requests[request].ev.Set(); + urlData.requests[request].requestDone =true; + } + else + { + m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString()); + } } } public string GetHttpHeader(UUID requestId, string header) { - if (m_RequestMap.ContainsKey(requestId)) - { - UrlData urlData = m_RequestMap[requestId]; - string value; - if (urlData.requests[requestId].headers.TryGetValue(header,out value)) - return value; - } - else + lock (m_UrlMap) { - m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId); + if (m_RequestMap.ContainsKey(requestId)) + { + UrlData urlData = m_RequestMap[requestId]; + string value; + if (urlData.requests[requestId].headers.TryGetValue(header, out value)) + return value; + } + else + { + m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId); + } } return String.Empty; @@ -308,7 +343,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp public int GetFreeUrls() { - return m_TotalUrls - m_UrlMap.Count; + lock (m_UrlMap) + return m_TotalUrls - m_UrlMap.Count; } public void ScriptRemoved(UUID itemID) @@ -366,9 +402,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp private Hashtable NoEvents(UUID requestID, UUID sessionID) { Hashtable response = new Hashtable(); - UrlData url; + UrlData urlData; - lock (m_RequestMap) + lock (m_UrlMap) { // We need to return a 404 here in case the request URL was removed at exactly the same time that a // request was made. In this case, the request thread can outrace llRemoveURL() and still be polling @@ -383,25 +419,22 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp return response; } - url = m_RequestMap[requestID]; - } - - if (System.Environment.TickCount - url.requests[requestID].startTime > 25000) - { - response["int_response_code"] = 500; - response["str_response_string"] = "Script timeout"; - response["content_type"] = "text/plain"; - response["keepalive"] = false; - response["reusecontext"] = false; + urlData = m_RequestMap[requestID]; - //remove from map - lock (url) + if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000) { - url.requests.Remove(requestID); + response["int_response_code"] = 500; + response["str_response_string"] = "Script timeout"; + response["content_type"] = "text/plain"; + response["keepalive"] = false; + response["reusecontext"] = false; + + //remove from map + urlData.requests.Remove(requestID); m_RequestMap.Remove(requestID); - } - return response; + return response; + } } return response; @@ -409,9 +442,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp private bool HasEvents(UUID requestID, UUID sessionID) { - UrlData url = null; - - lock (m_RequestMap) + lock (m_UrlMap) { // We return true here because an external URL request that happened at the same time as an llRemoveURL() // can still make it through to HttpRequestHandler(). That will return without setting up a request @@ -423,61 +454,61 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp return true; } - url = m_RequestMap[requestID]; - if (!url.requests.ContainsKey(requestID)) + UrlData urlData = m_RequestMap[requestID]; + + if (!urlData.requests.ContainsKey(requestID)) { return true; } - } - // Trigger return of timeout response. - if (System.Environment.TickCount - url.requests[requestID].startTime > 25000) - { - return true; - } + // Trigger return of timeout response. + if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000) + { + return true; + } - return url.requests[requestID].requestDone; + return urlData.requests[requestID].requestDone; + } } private Hashtable GetEvents(UUID requestID, UUID sessionID, string request) { - UrlData url = null; - RequestData requestData = null; + Hashtable response; - lock (m_RequestMap) + lock (m_UrlMap) { + UrlData url = null; + RequestData requestData = null; + if (!m_RequestMap.ContainsKey(requestID)) return NoEvents(requestID, sessionID); url = m_RequestMap[requestID]; requestData = url.requests[requestID]; - } - if (!requestData.requestDone) - return NoEvents(requestID, sessionID); - - Hashtable response = new Hashtable(); + if (!requestData.requestDone) + return NoEvents(requestID, sessionID); - if (System.Environment.TickCount - requestData.startTime > 25000) - { - response["int_response_code"] = 500; - response["str_response_string"] = "Script timeout"; + response = new Hashtable(); + + if (System.Environment.TickCount - requestData.startTime > 25000) + { + response["int_response_code"] = 500; + response["str_response_string"] = "Script timeout"; + response["content_type"] = "text/plain"; + response["keepalive"] = false; + response["reusecontext"] = false; + return response; + } + + //put response + response["int_response_code"] = requestData.responseCode; + response["str_response_string"] = requestData.responseBody; response["content_type"] = "text/plain"; response["keepalive"] = false; response["reusecontext"] = false; - return response; - } - //put response - response["int_response_code"] = requestData.responseCode; - response["str_response_string"] = requestData.responseBody; - response["content_type"] = "text/plain"; - response["keepalive"] = false; - response["reusecontext"] = false; - - //remove from map - lock (url) - { + //remove from map url.requests.Remove(requestID); m_RequestMap.Remove(requestID); } @@ -487,44 +518,41 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp public void HttpRequestHandler(UUID requestID, Hashtable request) { - lock (request) - { - string uri = request["uri"].ToString(); - bool is_ssl = uri.Contains("lslhttps"); + string uri = request["uri"].ToString(); + bool is_ssl = uri.Contains("lslhttps"); - try - { - Hashtable headers = (Hashtable)request["headers"]; + try + { + Hashtable headers = (Hashtable)request["headers"]; // string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/"; - int pos1 = uri.IndexOf("/");// /lslhttp - int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/ - int pos3 = uri.IndexOf("/", pos2 + 1);// /lslhttp// - string uri_tmp = uri.Substring(0, pos3 + 1); - //HTTP server code doesn't provide us with QueryStrings - string pathInfo; - string queryString; - queryString = ""; + int pos1 = uri.IndexOf("/");// /lslhttp + int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/ + int pos3 = uri.IndexOf("/", pos2 + 1);// /lslhttp// + string uri_tmp = uri.Substring(0, pos3 + 1); + //HTTP server code doesn't provide us with QueryStrings + string pathInfo; + string queryString; + queryString = ""; - pathInfo = uri.Substring(pos3); + pathInfo = uri.Substring(pos3); - UrlData urlData = null; + UrlData urlData = null; - lock (m_UrlMap) - { - string url; + lock (m_UrlMap) + { + string url; - if (is_ssl) - url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; - else - url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; + if (is_ssl) + url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; + else + url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; - // Avoid a race - the request URL may have been released via llRequestUrl() whilst this - // request was being processed. - if (!m_UrlMap.TryGetValue(url, out urlData)) - return; - } + // Avoid a race - the request URL may have been released via llRequestUrl() whilst this + // request was being processed. + if (!m_UrlMap.TryGetValue(url, out urlData)) + return; //for llGetHttpHeader support we need to store original URI here //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers @@ -544,6 +572,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp string value = (string)header.Value; requestData.headers.Add(key, value); } + foreach (DictionaryEntry de in request) { if (de.Key.ToString() == "querystringkeys") @@ -570,34 +599,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp requestData.headers["x-query-string"] = queryString; requestData.headers["x-script-url"] = urlData.url; - //requestData.ev = new ManualResetEvent(false); - lock (urlData.requests) - { - urlData.requests.Add(requestID, requestData); - } - - lock (m_RequestMap) - { - m_RequestMap.Add(requestID, urlData); - } - - urlData.engine.PostScriptEvent( - urlData.itemID, - "http_request", - new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() }); - - //send initial response? -// Hashtable response = new Hashtable(); - - return; - } - catch (Exception we) - { - //Hashtable response = new Hashtable(); - m_log.Warn("[HttpRequestHandler]: http-in request failed"); - m_log.Warn(we.Message); - m_log.Warn(we.StackTrace); + urlData.requests.Add(requestID, requestData); + m_RequestMap.Add(requestID, urlData); } + + urlData.engine.PostScriptEvent( + urlData.itemID, + "http_request", + new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() }); + } + catch (Exception we) + { + //Hashtable response = new Hashtable(); + m_log.Warn("[HttpRequestHandler]: http-in request failed"); + m_log.Warn(we.Message); + m_log.Warn(we.StackTrace); } } @@ -606,4 +622,4 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp ScriptRemoved(itemID); } } -} +} \ No newline at end of file -- cgit v1.1 From 6d3ee8bb39d47ed7b32e8905fa0b2fc31c5a9f80 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Sat, 23 Jun 2012 04:11:31 -0400 Subject: Fix script "Running" behavior Unchecking "Running" box in script editor now persists. This fixes http://opensimulator.org/mantis/view.php?id=6057 --- OpenSim/Region/Framework/Interfaces/IScriptModule.cs | 2 ++ OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 14 ++++++++++++++ OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs | 10 ++++++++++ .../Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 9 +++++++++ .../ScriptEngine/Shared/Instance/ScriptSerializer.cs | 11 +++++++++++ OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 7 +++++++ 6 files changed, 53 insertions(+) diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs index 0d488df..cbaf241 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs @@ -75,6 +75,8 @@ namespace OpenSim.Region.Framework.Interfaces /// The item ID of the script. bool GetScriptState(UUID itemID); + void SetRunEnable(UUID instanceID, bool enable); + void SaveAllState(); /// diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index e413281..9ff8467 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2143,10 +2143,24 @@ namespace OpenSim.Region.Framework.Scenes if (part == null) return; + IScriptModule[] engines = RequestModuleInterfaces(); + if (running) + { + foreach (IScriptModule engine in engines) + { + engine.SetRunEnable(itemID, true); + } EventManager.TriggerStartScript(part.LocalId, itemID); + } else + { + foreach (IScriptModule engine in engines) + { + engine.SetRunEnable(itemID, false); + } EventManager.TriggerStopScript(part.LocalId, itemID); + } } public void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID) diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index b04f6b6..ec13b6c 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -64,6 +64,16 @@ namespace OpenSim.Region.ScriptEngine.Interfaces bool Running { get; set; } /// + /// Gets or sets a value indicating whether this + /// is run. + /// For viewer script editor control + /// + /// + /// true if run; otherwise, false. + /// + bool Run { get; set; } + + /// /// Is the script suspended? /// bool Suspended { get; set; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 5dfe58e..306090e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -120,6 +120,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public bool Running { get; set; } + public bool Run { get; set; } + public bool Suspended { get { return m_Suspended; } @@ -215,6 +217,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_postOnRez = postOnRez; m_AttachedAvatar = part.ParentGroup.AttachedAvatar; m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID; + Run = true; if (part != null) { @@ -359,6 +362,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance if (m_startedFromSavedState) { + if (!Run) + return; + Start(); if (m_postOnRez) { @@ -391,6 +397,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance } else { + if (!Run) + return; + Start(); PostEvent(new EventParams("state_entry", new Object[0], new DetectParams[0])); diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptSerializer.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptSerializer.cs index bcdc7bf..797bce3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptSerializer.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptSerializer.cs @@ -55,6 +55,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public static string Serialize(ScriptInstance instance) { bool running = instance.Running; + bool enabled = instance.Run; XmlDocument xmldoc = new XmlDocument(); @@ -77,6 +78,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance rootElement.AppendChild(run); + XmlElement run_enable = xmldoc.CreateElement("", "Run", ""); + run_enable.AppendChild(xmldoc.CreateTextNode( + enabled.ToString())); + + rootElement.AppendChild(run_enable); + Dictionary vars = instance.GetVars(); XmlElement variables = xmldoc.CreateElement("", "Variables", ""); @@ -225,6 +232,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance { object varValue; XmlNodeList partL = rootNode.ChildNodes; + instance.Run = true; foreach (XmlNode part in partL) { @@ -236,6 +244,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance case "Running": instance.Running=bool.Parse(part.InnerText); break; + case "Run": + instance.Run = bool.Parse(part.InnerText); + break; case "Variables": XmlNodeList varL = part.ChildNodes; foreach (XmlNode var in varL) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 25b27b9..06ed9d6 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1503,6 +1503,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine } } + public void SetRunEnable(UUID instanceID, bool enable) + { + IScriptInstance instance = GetInstance(instanceID); + if (instance != null) + instance.Run = enable; + } + public bool GetScriptState(UUID itemID) { IScriptInstance instance = GetInstance(itemID); -- cgit v1.1 From 5301648cff6b451fef4cca0baf8cda1bdb1455a6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 25 Jun 2012 21:08:19 +0100 Subject: In AttachmentsModule.DetachSingleAttachmentToInvInternal(), remove attachment before changing properties for correct inventory serialization. Serialization of attachments requires IsAttachment = false so that correct positions are serialized instead of avatar position. However, doing this when a hud is still attached allows race conditions with update threads, resulting in hud artifacts on other viewers. This change sets SOG.IsDeleted before serialization changes take place (IsDeleted itself is not a serialized property). LLClientView then screens out any deleted SOGs before sending updates to viewers. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 33 +++++++++++++++++++++- .../Avatar/Attachments/AttachmentsModule.cs | 2 +- .../Scenes/Tests/SceneObjectBasicTests.cs | 9 ++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 4cb7a3a..8874585 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3808,6 +3808,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP && part.ParentGroup.HasPrivateAttachmentPoint && part.ParentGroup.AttachedAvatar != AgentId) continue; + + // If the part has since been deleted, then drop the update. In the case of attachments, + // this is to avoid spurious updates to other viewers since post-processing of attachments + // has to change the IsAttachment flag for various reasons (which will end up in a pass + // of the test above). + // + // Actual deletions (kills) happen in another method. + if (part.ParentGroup.IsDeleted) + continue; } objectUpdateBlocks.Value.Add(updateBlock); @@ -3815,7 +3824,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else if (!canUseImproved) { - compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); + SceneObjectPart part = (SceneObjectPart)update.Entity; + ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock + = CreateCompressedUpdateBlock(part, updateFlags); + + // If the part has since been deleted, then drop the update. In the case of attachments, + // this is to avoid spurious updates to other viewers since post-processing of attachments + // has to change the IsAttachment flag for various reasons (which will end up in a pass + // of the test above). + // + // Actual deletions (kills) happen in another method. + if (part.ParentGroup.IsDeleted) + continue; + + compressedUpdateBlocks.Value.Add(compressedBlock); compressedUpdates.Value.Add(update); } else @@ -3842,6 +3864,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP && part.ParentGroup.HasPrivateAttachmentPoint && part.ParentGroup.AttachedAvatar != AgentId) continue; + + // If the part has since been deleted, then drop the update. In the case of attachments, + // this is to avoid spurious updates to other viewers since post-processing of attachments + // has to change the IsAttachment flag for various reasons (which will end up in a pass + // of the test above). + // + // Actual deletions (kills) happen in another method. + if (part.ParentGroup.IsDeleted) + continue; } terseUpdateBlocks.Value.Add(terseUpdateBlock); diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index a2b95eb..99e0153 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -628,6 +628,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); sp.RemoveAttachment(group); + m_scene.DeleteSceneObject(group, false); // Prepare sog for storage group.AttachedAvatar = UUID.Zero; @@ -636,7 +637,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments group.AbsolutePosition = group.RootPart.AttachedPos; UpdateKnownItem(sp, group, true); - m_scene.DeleteSceneObject(group, false); return; } diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs index 453e077..81add43 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs @@ -187,8 +187,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene scene = new SceneHelpers().SetupScene(); SceneObjectPart part = SceneHelpers.AddSceneObject(scene); + + Assert.That(part.ParentGroup.IsDeleted, Is.False); + scene.DeleteSceneObject(part.ParentGroup, false); + Assert.That(part.ParentGroup.IsDeleted, Is.True); + SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); Assert.That(retrievedPart, Is.Null); } @@ -219,8 +224,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(retrievedPart, Is.Not.Null); + Assert.That(part.ParentGroup.IsDeleted, Is.False); + sogd.InventoryDeQueueAndDelete(); + Assert.That(part.ParentGroup.IsDeleted, Is.True); + SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(part.LocalId); Assert.That(retrievedPart2, Is.Null); } -- cgit v1.1 From e5b739aaebace6b028f3f6bf05d21ff7a7c5affe Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 25 Jun 2012 22:48:13 +0100 Subject: When attachments are being saved and deleted for a closing root agent, delete first to avoid a hud race condition with update threads. If delete doesn't occur first then the update thread can outrace the IsAttachment = false necessary to save attachments and send hud artifacts to other viewers. --- .../Avatar/Attachments/AttachmentsModule.cs | 33 ++++++++++++++-------- .../Framework/Interfaces/IAttachmentsModule.cs | 11 ++++++-- OpenSim/Region/Framework/Scenes/Scene.cs | 24 ++++++++-------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3 -- 4 files changed, 42 insertions(+), 29 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 99e0153..2b0e4ab 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -152,31 +152,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } - public void SaveChangedAttachments(IScenePresence sp, bool saveAllScripted) + public void DeRezAttachments(IScenePresence sp, bool saveChanged, bool saveAllScripted) { -// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); - if (!Enabled) return; - foreach (SceneObjectGroup grp in sp.GetAttachments()) +// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); + + lock (sp.AttachmentsSyncLock) { - grp.IsAttachment = false; - grp.AbsolutePosition = grp.RootPart.AttachedPos; - UpdateKnownItem(sp, grp, saveAllScripted); - grp.IsAttachment = true; + foreach (SceneObjectGroup grp in sp.GetAttachments()) + { + grp.Scene.DeleteSceneObject(grp, false); + + if (saveChanged || saveAllScripted) + { + grp.IsAttachment = false; + grp.AbsolutePosition = grp.RootPart.AttachedPos; + UpdateKnownItem(sp, grp, saveAllScripted); + } + } + + sp.ClearAttachments(); } } public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent) { -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", -// m_scene.RegionInfo.RegionName, sp.Name, silent); - if (!Enabled) return; +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", +// m_scene.RegionInfo.RegionName, sp.Name, silent); + foreach (SceneObjectGroup sop in sp.GetAttachments()) { sop.Scene.DeleteSceneObject(sop, silent); diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index eb07165..fde5de1 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -43,10 +43,15 @@ namespace OpenSim.Region.Framework.Interfaces void RezAttachments(IScenePresence sp); /// - /// Save the attachments that have change on this presence. + /// Derez the attachements for a scene presence that is closing. /// - /// - void SaveChangedAttachments(IScenePresence sp, bool saveAllScripted); + /// + /// Attachment changes are saved. + /// + /// The presence closing + /// Save changed attachments. + /// Save attachments with scripts even if they haven't changed. + void DeRezAttachments(IScenePresence sp, bool saveChanged, bool saveAllScripted); /// /// Delete all the presence's attachments from the scene diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 385febf..d449116 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -500,6 +500,7 @@ namespace OpenSim.Region.Framework.Scenes public IAttachmentsModule AttachmentsModule { get; set; } public IEntityTransferModule EntityTransferModule { get; private set; } public IAgentAssetTransactions AgentTransactionsModule { get; private set; } + public IUserManagement UserManagementModule { get; private set; } public IAvatarFactoryModule AvatarFactory { @@ -1243,6 +1244,7 @@ namespace OpenSim.Region.Framework.Scenes EntityTransferModule = RequestModuleInterface(); m_groupsModule = RequestModuleInterface(); AgentTransactionsModule = RequestModuleInterface(); + UserManagementModule = RequestModuleInterface(); } #endregion @@ -2021,9 +2023,8 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.SetGroup(groupID, null); } - IUserManagement uman = RequestModuleInterface(); - if (uman != null) - sceneObject.RootPart.CreatorIdentification = uman.GetUserUUI(ownerID); + if (UserManagementModule != null) + sceneObject.RootPart.CreatorIdentification = UserManagementModule.GetUserUUI(ownerID); sceneObject.ScheduleGroupForFullUpdate(); @@ -2711,14 +2712,13 @@ namespace OpenSim.Region.Framework.Scenes /// private void CacheUserName(ScenePresence sp, AgentCircuitData aCircuit) { - IUserManagement uMan = RequestModuleInterface(); - if (uMan != null) + if (UserManagementModule != null) { string first = aCircuit.firstname, last = aCircuit.lastname; if (sp.PresenceType == PresenceType.Npc) { - uMan.AddUser(aCircuit.AgentID, first, last); + UserManagementModule.AddUser(aCircuit.AgentID, first, last); } else { @@ -2737,7 +2737,7 @@ namespace OpenSim.Region.Framework.Scenes } } - uMan.AddUser(aCircuit.AgentID, first, last, homeURL); + UserManagementModule.AddUser(aCircuit.AgentID, first, last, homeURL); } } } @@ -3292,17 +3292,19 @@ namespace OpenSim.Region.Framework.Scenes if (!isChildAgent) { - if (AttachmentsModule != null && avatar.PresenceType != PresenceType.Npc) + if (AttachmentsModule != null) { - IUserManagement uMan = RequestModuleInterface(); // Don't save attachments for HG visitors, it // messes up their inventory. When a HG visitor logs // out on a foreign grid, their attachments will be // reloaded in the state they were in when they left // the home grid. This is best anyway as the visited // grid may use an incompatible script engine. - if (uMan == null || uMan.IsLocalGridUser(avatar.UUID)) - AttachmentsModule.SaveChangedAttachments(avatar, false); + bool saveChanged + = avatar.PresenceType != PresenceType.Npc + && (UserManagementModule == null || UserManagementModule.IsLocalGridUser(avatar.UUID)); + + AttachmentsModule.DeRezAttachments(avatar, saveChanged, false); } ForEachClient( diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 3909fd4..909c7c8 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3416,9 +3416,6 @@ namespace OpenSim.Region.Framework.Scenes public void Close() { - if (!IsChildAgent && m_scene.AttachmentsModule != null) - m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false); - // Clear known regions KnownRegions = new Dictionary(); -- cgit v1.1 From f5316984abfcf72870c7e4d50c95c1cabc8cc588 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 25 Jun 2012 23:31:22 +0100 Subject: minor: update currently commented out log message at top of AvatarFactoryModule.SetAppearance() for future use --- .../Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 705233c..68a4cde 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -128,7 +128,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory /// public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) { - // m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}", client.AgentId); +// m_log.DebugFormat( +// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", +// sp.Name, textureEntry, visualParams); // TODO: This is probably not necessary any longer, just assume the // textureEntry set implies that the appearance transaction is complete -- cgit v1.1 From 854f2a913cdedfa252b69d5c3118d35604ab6b4a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 25 Jun 2012 23:55:14 +0100 Subject: Add "show region at" command to grid service to get the details of a region at a specific location. "show region" command becomes "show region name" to disambiguate This is the same format as used by "show object name", etc. "deregister region" also becomes "deregister region id" --- OpenSim/Services/GridService/GridService.cs | 91 ++++++++++++++++++++++------- 1 file changed, 69 insertions(+), 22 deletions(-) diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index 11897f8..7d2dadb 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -85,20 +85,27 @@ namespace OpenSim.Services.GridService if (MainConsole.Instance != null) { MainConsole.Instance.Commands.AddCommand("Regions", true, - "deregister region", - "deregister region ", + "deregister region id", + "deregister region id ", "Deregister a region manually.", String.Empty, HandleDeregisterRegion); MainConsole.Instance.Commands.AddCommand("Regions", true, - "show region", - "show region ", + "show region name", + "show region name ", "Show details on a region", String.Empty, HandleShowRegion); MainConsole.Instance.Commands.AddCommand("Regions", true, + "show region at", + "show region at ", + "Show details on a region at the given co-ordinate.", + "For example, show region at 1000 1000", + HandleShowRegionAt); + + MainConsole.Instance.Commands.AddCommand("Regions", true, "set region flags", "set region flags ", "Set database flags for region", @@ -504,13 +511,13 @@ namespace OpenSim.Services.GridService private void HandleDeregisterRegion(string module, string[] cmd) { - if (cmd.Length != 3) + if (cmd.Length != 4) { - MainConsole.Instance.Output("Syntax: degregister region "); + MainConsole.Instance.Output("Syntax: degregister region id "); return; } - string rawRegionUuid = cmd[2]; + string rawRegionUuid = cmd[3]; UUID regionUuid; if (!UUID.TryParse(rawRegionUuid, out regionUuid)) @@ -542,34 +549,74 @@ namespace OpenSim.Services.GridService private void HandleShowRegion(string module, string[] cmd) { - if (cmd.Length != 3) + if (cmd.Length != 4) { - MainConsole.Instance.Output("Syntax: show region "); + MainConsole.Instance.Output("Syntax: show region name "); return; } - List regions = m_Database.Get(cmd[2], UUID.Zero); + + string regionName = cmd[3]; + + List regions = m_Database.Get(regionName, UUID.Zero); if (regions == null || regions.Count < 1) { - MainConsole.Instance.Output("Region not found"); + MainConsole.Instance.Output("No region with name {0} found", regionName); return; } - foreach (RegionData r in regions) + OutputRegionsToConsole(regions); + } + + private void HandleShowRegionAt(string module, string[] cmd) + { + if (cmd.Length != 5) { - OpenSim.Data.RegionFlags flags = (OpenSim.Data.RegionFlags)Convert.ToInt32(r.Data["flags"]); + MainConsole.Instance.Output("Syntax: show region at "); + return; + } - ConsoleDisplayList dispList = new ConsoleDisplayList(); - dispList.AddRow("Region Name", r.RegionName); - dispList.AddRow("Region ID", r.RegionID); - dispList.AddRow("Location", string.Format("{0},{1}", r.coordX, r.coordY)); - dispList.AddRow("URI", r.Data["serverURI"]); - dispList.AddRow("Owner ID", r.Data["owner_uuid"]); - dispList.AddRow("Flags", flags); + int x, y; + if (!int.TryParse(cmd[3], out x)) + { + MainConsole.Instance.Output("x-coord must be an integer"); + return; + } - MainConsole.Instance.Output(dispList.ToString()); + if (!int.TryParse(cmd[4], out y)) + { + MainConsole.Instance.Output("y-coord must be an integer"); + return; } - return; + RegionData region = m_Database.Get(x * (int)Constants.RegionSize, y * (int)Constants.RegionSize, UUID.Zero); + if (region == null) + { + MainConsole.Instance.OutputFormat("No region found at {0},{1}", x, y); + return; + } + + OutputRegionToConsole(region); + } + + private void OutputRegionToConsole(RegionData r) + { + OpenSim.Data.RegionFlags flags = (OpenSim.Data.RegionFlags)Convert.ToInt32(r.Data["flags"]); + + ConsoleDisplayList dispList = new ConsoleDisplayList(); + dispList.AddRow("Region Name", r.RegionName); + dispList.AddRow("Region ID", r.RegionID); + dispList.AddRow("Location", string.Format("{0},{1}", r.coordX, r.coordY)); + dispList.AddRow("URI", r.Data["serverURI"]); + dispList.AddRow("Owner ID", r.Data["owner_uuid"]); + dispList.AddRow("Flags", flags); + + MainConsole.Instance.Output(dispList.ToString()); + } + + private void OutputRegionsToConsole(List regions) + { + foreach (RegionData r in regions) + OutputRegionToConsole(r); } private int ParseFlags(int prev, string flags) -- cgit v1.1 From 5292b8b8be85696604f4f8086376da568b8342b5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 26 Jun 2012 00:34:37 +0100 Subject: Add "show regions" console command to ROBUST to show all regions currently registered. Command is not added in standalone, which has its own version of "show regions" that can also show estate name --- OpenSim/Services/GridService/GridService.cs | 44 +++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index 7d2dadb..e4c3246 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -91,6 +91,18 @@ namespace OpenSim.Services.GridService String.Empty, HandleDeregisterRegion); + // A messy way of stopping this command being added if we are in standalone (since the simulator + // has an identically named command + // + // XXX: We're relying on the OpenSimulator version being registered first, which is not well defined. + if (MainConsole.Instance.Commands.Resolve(new string[] { "show", "regions" }).Length == 0) + MainConsole.Instance.Commands.AddCommand("Regions", true, + "show regions", + "show all regions", + "Show details on all regions", + String.Empty, + HandleShowRegions); + MainConsole.Instance.Commands.AddCommand("Regions", true, "show region name", "show region name ", @@ -547,6 +559,20 @@ namespace OpenSim.Services.GridService return; } + private void HandleShowRegions(string module, string[] cmd) + { + if (cmd.Length != 2) + { + MainConsole.Instance.Output("Syntax: show regions"); + return; + } + + List regions = m_Database.Get(int.MinValue, int.MinValue, int.MaxValue, int.MaxValue, UUID.Zero); + + OutputRegionsToConsoleSummary(regions); + } + + private void HandleShowRegion(string module, string[] cmd) { if (cmd.Length != 4) @@ -619,6 +645,24 @@ namespace OpenSim.Services.GridService OutputRegionToConsole(r); } + private void OutputRegionsToConsoleSummary(List regions) + { + ConsoleDisplayTable dispTable = new ConsoleDisplayTable(); + dispTable.Columns.Add(new ConsoleDisplayTableColumn("Name", 16)); + dispTable.Columns.Add(new ConsoleDisplayTableColumn("ID", 36)); + dispTable.Columns.Add(new ConsoleDisplayTableColumn("Owner ID", 36)); + dispTable.Columns.Add(new ConsoleDisplayTableColumn("Flags", 60)); + + foreach (RegionData r in regions) + { + OpenSim.Data.RegionFlags flags = (OpenSim.Data.RegionFlags)Convert.ToInt32(r.Data["flags"]); + dispTable.Rows.Add( + new ConsoleDisplayTableRow(new List { r.RegionName, r.RegionID.ToString(), r.Data["owner_uuid"].ToString(), flags.ToString() })); + } + + MainConsole.Instance.Output(dispTable.ToString()); + } + private int ParseFlags(int prev, string flags) { OpenSim.Data.RegionFlags f = (OpenSim.Data.RegionFlags)prev; -- cgit v1.1 From 1f22b29ca3d172624087185a4e9056a931f19703 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 26 Jun 2012 00:40:46 +0100 Subject: Add much easier ConsoleDisplayTable AddColumn() and AddRow() methods. Use these for new "show regions" command rather than old cumbersome stuff. --- OpenSim/Framework/Console/ConsoleDisplayTable.cs | 15 +++++++++++++++ OpenSim/Services/GridService/GridService.cs | 11 +++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/OpenSim/Framework/Console/ConsoleDisplayTable.cs b/OpenSim/Framework/Console/ConsoleDisplayTable.cs index e9d1628..c620dfe 100644 --- a/OpenSim/Framework/Console/ConsoleDisplayTable.cs +++ b/OpenSim/Framework/Console/ConsoleDisplayTable.cs @@ -79,6 +79,16 @@ namespace OpenSim.Framework.Console return sb.ToString(); } + public void AddColumn(string name, int width) + { + Columns.Add(new ConsoleDisplayTableColumn(name, width)); + } + + public void AddRow(params string[] cells) + { + Rows.Add(new ConsoleDisplayTableRow(cells)); + } + public void AddToStringBuilder(StringBuilder sb) { string formatString = GetFormatString(); @@ -135,5 +145,10 @@ namespace OpenSim.Framework.Console { Cells = cells; } + + public ConsoleDisplayTableRow(params string[] cells) : this() + { + Cells = new List(cells); + } } } \ No newline at end of file diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index e4c3246..842a697 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -648,16 +648,15 @@ namespace OpenSim.Services.GridService private void OutputRegionsToConsoleSummary(List regions) { ConsoleDisplayTable dispTable = new ConsoleDisplayTable(); - dispTable.Columns.Add(new ConsoleDisplayTableColumn("Name", 16)); - dispTable.Columns.Add(new ConsoleDisplayTableColumn("ID", 36)); - dispTable.Columns.Add(new ConsoleDisplayTableColumn("Owner ID", 36)); - dispTable.Columns.Add(new ConsoleDisplayTableColumn("Flags", 60)); + dispTable.AddColumn("Name", 16); + dispTable.AddColumn("ID", 36); + dispTable.AddColumn("Owner ID", 36); + dispTable.AddColumn("Flags", 60); foreach (RegionData r in regions) { OpenSim.Data.RegionFlags flags = (OpenSim.Data.RegionFlags)Convert.ToInt32(r.Data["flags"]); - dispTable.Rows.Add( - new ConsoleDisplayTableRow(new List { r.RegionName, r.RegionID.ToString(), r.Data["owner_uuid"].ToString(), flags.ToString() })); + dispTable.AddRow(r.RegionName, r.RegionID.ToString(), r.Data["owner_uuid"].ToString(), flags.ToString()); } MainConsole.Instance.Output(dispTable.ToString()); -- cgit v1.1 From 988112d4460adb2c6621027145f4fe60b079c7e5 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Tue, 26 Jun 2012 15:14:25 -0400 Subject: Add stub for llCastRay --- OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index 06f5617..a0b3bc8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -954,6 +954,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_LSL_Functions.llRequestDisplayName(id); } + public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) + { + return m_LSL_Functions.llCastRay(start, end, options); + } + public void llLinkParticleSystem(int linknum, LSL_List rules) { m_LSL_Functions.llLinkParticleSystem(linknum, rules); -- cgit v1.1 From 4b6c3fd4bb8e4c989a7f0b4c0687379ea4bc63c1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 26 Jun 2012 21:06:47 +0100 Subject: If crossing attachments into another region pre-fatpack, clone objects before changing properties to avoid hud display race condition with update threads. This matches behaviour in fatpack crossing, where attachments are cloned before their properties are changed. This only applies to crossings to simulators running code released before April 2011. --- .../EntityTransfer/EntityTransferModule.cs | 43 +++++++++++++--------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 7d82060..f5ebe97 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1666,6 +1666,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion #region Object Transfers + /// /// Move the given scene object into a new region depending on which region its absolute position has moved /// into. @@ -1967,35 +1968,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return successYN; } - protected bool CrossAttachmentsIntoNewRegion(GridRegion destination, ScenePresence sp, bool silent) + /// + /// Cross the attachments for an avatar into the destination region. + /// + /// + /// This is only invoked for simulators released prior to April 2011. Versions of OpenSimulator since then + /// transfer attachments in one go as part of the ChildAgentDataUpdate data passed in the update agent call. + /// + /// + /// + /// + protected void CrossAttachmentsIntoNewRegion(GridRegion destination, ScenePresence sp, bool silent) { - List m_attachments = sp.GetAttachments(); + List attachments = sp.GetAttachments(); - // Validate -// foreach (SceneObjectGroup gobj in m_attachments) -// { -// if (gobj == null || gobj.IsDeleted) -// return false; -// } +// m_log.DebugFormat( +// "[ENTITY TRANSFER MODULE]: Crossing {0} attachments into {1} for {2}", +// m_attachments.Count, destination.RegionName, sp.Name); - foreach (SceneObjectGroup gobj in m_attachments) + foreach (SceneObjectGroup gobj in attachments) { // If the prim group is null then something must have happened to it! if (gobj != null && !gobj.IsDeleted) { - // Set the parent localID to 0 so it transfers over properly. - gobj.RootPart.SetParentLocalId(0); - gobj.AbsolutePosition = gobj.RootPart.AttachedPos; - gobj.IsAttachment = false; + SceneObjectGroup clone = (SceneObjectGroup)gobj.CloneForNewScene(); + clone.RootPart.GroupPosition = gobj.RootPart.AttachedPos; + clone.IsAttachment = false; + //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName); - CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, gobj, silent); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", + clone.UUID, destination.RegionName); + + CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, clone, silent); } } sp.ClearAttachments(); - - return true; } #endregion -- cgit v1.1 From 32a4ce94f0b896eff0ca5b91b30714e776132acf Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 26 Jun 2012 22:16:44 +0100 Subject: Add regression test to check that attachments in source region are deleting when an agent teleports to a neighbouring region --- .../Attachments/Tests/AttachmentsModuleTests.cs | 133 ++++++++++++++++++--- .../EntityTransfer/EntityTransferModule.cs | 5 + 2 files changed, 120 insertions(+), 18 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 8f4a807..695994f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -38,6 +38,8 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications; using OpenSim.Region.CoreModules.Avatar.Attachments; +using OpenSim.Region.CoreModules.Framework; +using OpenSim.Region.CoreModules.Framework.EntityTransfer; using OpenSim.Region.CoreModules.Framework.InventoryAccess; using OpenSim.Region.CoreModules.World.Serialiser; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; @@ -54,7 +56,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests [TestFixture] public class AttachmentsModuleTests { - private Scene scene; private AttachmentsModule m_attMod; private ScenePresence m_presence; @@ -80,24 +81,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Util.FireAndForgetMethod = FireAndForgetMethod.None; } - [SetUp] - public void Init() + [TestFixtureTearDown] + public void TearDown() + { + // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple + // threads. Possibly, later tests should be rewritten not to worry about such things. + Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; + } + + private Scene CreateDefaultTestScene() { IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); - scene = new SceneHelpers().SetupScene(); + Scene scene = new SceneHelpers().SetupScene(); m_attMod = new AttachmentsModule(); SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule()); - } - [TestFixtureTearDown] - public void TearDown() - { - // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple - // threads. Possibly, later tests should be rewritten not to worry about such things. - Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; + return scene; } /// @@ -109,11 +111,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests /// /// The attachment item. /// + /// /// /// /// /// - private InventoryItemBase CreateAttachmentItem(UUID userId, string attName, int rawItemId, int rawAssetId) + private InventoryItemBase CreateAttachmentItem( + Scene scene, UUID userId, string attName, int rawItemId, int rawAssetId) { return UserInventoryHelpers.CreateInventoryItem( scene, @@ -130,6 +134,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); + Scene scene = CreateDefaultTestScene(); UserAccountHelpers.CreateUserWithInventory(scene, m_userId); m_presence = SceneHelpers.AddScenePresence(scene, m_userId); @@ -171,10 +176,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); + Scene scene = CreateDefaultTestScene(); UserAccountHelpers.CreateUserWithInventory(scene, m_userId); m_presence = SceneHelpers.AddScenePresence(scene, m_userId); - InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); + InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); m_attMod.RezSingleAttachmentFromInventory( m_presence, attItem.ID, (uint)AttachmentPoint.Chest); @@ -201,10 +207,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); + Scene scene = CreateDefaultTestScene(); UserAccountHelpers.CreateUserWithInventory(scene, m_userId); m_presence = SceneHelpers.AddScenePresence(scene, m_userId); - InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); + InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory( @@ -232,10 +239,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); + Scene scene = CreateDefaultTestScene(); UserAccountHelpers.CreateUserWithInventory(scene, m_userId); m_presence = SceneHelpers.AddScenePresence(scene, m_userId); - InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); + InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); m_attMod.RezSingleAttachmentFromInventory( m_presence, attItem.ID, (uint)AttachmentPoint.Chest); @@ -259,8 +267,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); + Scene scene = CreateDefaultTestScene(); UserAccountHelpers.CreateUserWithInventory(scene, m_userId); - InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); + InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); AgentCircuitData acd = SceneHelpers.GenerateAgentData(m_userId); acd.Appearance = new AvatarAppearance(); @@ -281,8 +290,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); + Scene scene = CreateDefaultTestScene(); UserAccountHelpers.CreateUserWithInventory(scene, m_userId); - InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); + InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); AgentCircuitData acd = SceneHelpers.GenerateAgentData(m_userId); acd.Appearance = new AvatarAppearance(); @@ -314,8 +324,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests { TestHelpers.InMethod(); + Scene scene = CreateDefaultTestScene(); UserAccountHelpers.CreateUserWithInventory(scene, m_userId); - InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); + InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); AgentCircuitData acd = SceneHelpers.GenerateAgentData(m_userId); acd.Appearance = new AvatarAppearance(); @@ -332,6 +343,92 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attSo.RootPart.AttachedPos, Is.EqualTo(newPosition)); } + [Test] + public void TestSameSimulatorNeighbouringRegionsTeleport() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + AttachmentsModule attModA = new AttachmentsModule(); + AttachmentsModule attModB = new AttachmentsModule(); + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); + LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); + + IConfigSource config = new IniConfigSource(); + IConfig modulesConfig = config.AddConfig("Modules"); + modulesConfig.Set("EntityTransferModule", etmA.Name); + modulesConfig.Set("SimulationServices", lscm.Name); + IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); + + // In order to run a single threaded regression test we do not want the entity transfer module waiting + // for a callback from the destination scene before removing its avatar data. + entityTransferConfig.Set("wait_for_callback", false); + + SceneHelpers sh = new SceneHelpers(); + TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); + TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000); + + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); + SceneHelpers.SetupSceneModules( + sceneA, config, new CapabilitiesModule(), etmA, attModA, new BasicInventoryAccessModule()); + SceneHelpers.SetupSceneModules( + sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); + + UserAccountHelpers.CreateUserWithInventory(sceneA, m_userId); + ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, m_userId, sh.SceneManager); + beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); + + InventoryItemBase attItem = CreateAttachmentItem(sceneA, m_userId, "att", 0x10, 0x20); + + m_attMod.RezSingleAttachmentFromInventory( + beforeTeleportSp, attItem.ID, (uint)AttachmentPoint.Chest); + + Vector3 teleportPosition = new Vector3(10, 11, 12); + Vector3 teleportLookAt = new Vector3(20, 21, 22); + + sceneA.RequestTeleportLocation( + beforeTeleportSp.ControllingClient, + sceneB.RegionInfo.RegionHandle, + teleportPosition, + teleportLookAt, + (uint)TeleportFlags.ViaLocation); + + ((TestClient)beforeTeleportSp.ControllingClient).CompleteTeleportClientSide(); + + // Check attachments have made it into sceneB + ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(m_userId); + + // This is appearance data, as opposed to actually rezzed attachments + List sceneBAttachments = afterTeleportSceneBSp.Appearance.GetAttachments(); + Assert.That(sceneBAttachments.Count, Is.EqualTo(1)); + Assert.That(sceneBAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest)); + Assert.That(sceneBAttachments[0].ItemID, Is.EqualTo(attItem.ID)); + Assert.That(sceneBAttachments[0].AssetID, Is.EqualTo(attItem.AssetID)); + Assert.That(afterTeleportSceneBSp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); + + // This is the actual attachment + List actualSceneBAttachments = afterTeleportSceneBSp.GetAttachments(); + Assert.That(actualSceneBAttachments.Count, Is.EqualTo(1)); + SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0]; + Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name)); + Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest)); + + // Check attachments have been removed from sceneA + ScenePresence afterTeleportSceneASp = sceneA.GetScenePresence(m_userId); + + // Since this is appearance data, it is still present on the child avatar! + List sceneAAttachments = afterTeleportSceneASp.Appearance.GetAttachments(); + Assert.That(sceneAAttachments.Count, Is.EqualTo(1)); + Assert.That(afterTeleportSceneASp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); + + // This is the actual attachment, which should no longer exist + List actualSceneAAttachments = afterTeleportSceneASp.GetAttachments(); + Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0)); + +// TestHelpers.DisableLogging(); + } + // I'm commenting this test because scene setup NEEDS InventoryService to // be non-null //[Test] diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index f5ebe97..46738f6 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -709,6 +709,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.CallbackURI, region.RegionName); } + /// + /// Clean up operations once an agent has moved away through cross or teleport. + /// + /// + /// protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) { if (sp.Scene.AttachmentsModule != null) -- cgit v1.1 From 4329cc7b8a698acc6154f3e195c6261c61014916 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 26 Jun 2012 22:21:54 +0100 Subject: refactor: make m_presence a local variable in all AttachmentsModuleTests since it doesn't need to be global and some tests set up more than one sp --- .../Attachments/Tests/AttachmentsModuleTests.cs | 51 +++++++++++----------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 695994f..4c750bc 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -57,7 +57,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests public class AttachmentsModuleTests { private AttachmentsModule m_attMod; - private ScenePresence m_presence; /// /// Standard user ID @@ -136,17 +135,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Scene scene = CreateDefaultTestScene(); UserAccountHelpers.CreateUserWithInventory(scene, m_userId); - m_presence = SceneHelpers.AddScenePresence(scene, m_userId); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, m_userId); string attName = "att"; - SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, m_presence.UUID).ParentGroup; + SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID).ParentGroup; - m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false); + m_attMod.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false); // Check status on scene presence - Assert.That(m_presence.HasAttachments(), Is.True); - List attachments = m_presence.GetAttachments(); + Assert.That(sp.HasAttachments(), Is.True); + List attachments = sp.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attName)); @@ -157,14 +156,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Check item status Assert.That( - m_presence.Appearance.GetAttachpoint(attSo.FromItemID), + sp.Appearance.GetAttachpoint(attSo.FromItemID), Is.EqualTo((int)AttachmentPoint.Chest)); InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); Assert.That(attachmentItem, Is.Not.Null); Assert.That(attachmentItem.Name, Is.EqualTo(attName)); - InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(m_presence.UUID, AssetType.Object); + InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); // TestHelpers.DisableLogging(); @@ -178,16 +177,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Scene scene = CreateDefaultTestScene(); UserAccountHelpers.CreateUserWithInventory(scene, m_userId); - m_presence = SceneHelpers.AddScenePresence(scene, m_userId); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, m_userId); InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); m_attMod.RezSingleAttachmentFromInventory( - m_presence, attItem.ID, (uint)AttachmentPoint.Chest); + sp, attItem.ID, (uint)AttachmentPoint.Chest); // Check scene presence status - Assert.That(m_presence.HasAttachments(), Is.True); - List attachments = m_presence.GetAttachments(); + Assert.That(sp.HasAttachments(), Is.True); + List attachments = sp.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); @@ -197,8 +196,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attSo.IsTemporary, Is.False); // Check appearance status - Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(1)); - Assert.That(m_presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); + Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); + Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); } [Test] @@ -209,22 +208,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Scene scene = CreateDefaultTestScene(); UserAccountHelpers.CreateUserWithInventory(scene, m_userId); - m_presence = SceneHelpers.AddScenePresence(scene, m_userId); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, m_userId); InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory( - m_presence, attItem.ID, (uint)AttachmentPoint.Chest); - m_attMod.DetachSingleAttachmentToGround(m_presence, so.LocalId); + sp, attItem.ID, (uint)AttachmentPoint.Chest); + m_attMod.DetachSingleAttachmentToGround(sp, so.LocalId); // Check scene presence status - Assert.That(m_presence.HasAttachments(), Is.False); - List attachments = m_presence.GetAttachments(); + Assert.That(sp.HasAttachments(), Is.False); + List attachments = sp.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(0)); // Check appearance status - Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(0)); + Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(0)); // Check item status Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItem.ID)), Is.Null); @@ -241,21 +240,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Scene scene = CreateDefaultTestScene(); UserAccountHelpers.CreateUserWithInventory(scene, m_userId); - m_presence = SceneHelpers.AddScenePresence(scene, m_userId); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, m_userId); InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); m_attMod.RezSingleAttachmentFromInventory( - m_presence, attItem.ID, (uint)AttachmentPoint.Chest); - m_attMod.DetachSingleAttachmentToInv(m_presence, attItem.ID); + sp, attItem.ID, (uint)AttachmentPoint.Chest); + m_attMod.DetachSingleAttachmentToInv(sp, attItem.ID); // Check status on scene presence - Assert.That(m_presence.HasAttachments(), Is.False); - List attachments = m_presence.GetAttachments(); + Assert.That(sp.HasAttachments(), Is.False); + List attachments = sp.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(0)); // Check item status - Assert.That(m_presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo(0)); + Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo(0)); } /// -- cgit v1.1 From 2b82c421adf23cc47e1dc4f6da941b7cd2a407b6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 26 Jun 2012 22:31:25 +0100 Subject: refactor: Use local attachment module variables instead of global m_attMod. This also avoids confusion between tests where one sets up m_attMod and another accidentally uses it after failing to set one up itself. --- .../Attachments/Tests/AttachmentsModuleTests.cs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 4c750bc..d233faf 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -56,8 +56,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests [TestFixture] public class AttachmentsModuleTests { - private AttachmentsModule m_attMod; - /// /// Standard user ID /// @@ -95,8 +93,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); Scene scene = new SceneHelpers().SetupScene(); - m_attMod = new AttachmentsModule(); - SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule()); + SceneHelpers.SetupSceneModules(scene, config, new AttachmentsModule(), new BasicInventoryAccessModule()); return scene; } @@ -141,7 +138,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID).ParentGroup; - m_attMod.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false); + scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.True); @@ -181,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); - m_attMod.RezSingleAttachmentFromInventory( + scene.AttachmentsModule.RezSingleAttachmentFromInventory( sp, attItem.ID, (uint)AttachmentPoint.Chest); // Check scene presence status @@ -213,9 +210,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); ISceneEntity so - = m_attMod.RezSingleAttachmentFromInventory( + = scene.AttachmentsModule.RezSingleAttachmentFromInventory( sp, attItem.ID, (uint)AttachmentPoint.Chest); - m_attMod.DetachSingleAttachmentToGround(sp, so.LocalId); + scene.AttachmentsModule.DetachSingleAttachmentToGround(sp, so.LocalId); // Check scene presence status Assert.That(sp.HasAttachments(), Is.False); @@ -244,9 +241,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); - m_attMod.RezSingleAttachmentFromInventory( + scene.AttachmentsModule.RezSingleAttachmentFromInventory( sp, attItem.ID, (uint)AttachmentPoint.Chest); - m_attMod.DetachSingleAttachmentToInv(sp, attItem.ID); + scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, attItem.ID); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.False); @@ -364,6 +361,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // for a callback from the destination scene before removing its avatar data. entityTransferConfig.Set("wait_for_callback", false); + modulesConfig.Set("InventoryAccessModule", "BasicInventoryAccessModule"); + SceneHelpers sh = new SceneHelpers(); TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000); @@ -380,7 +379,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests InventoryItemBase attItem = CreateAttachmentItem(sceneA, m_userId, "att", 0x10, 0x20); - m_attMod.RezSingleAttachmentFromInventory( + sceneA.AttachmentsModule.RezSingleAttachmentFromInventory( beforeTeleportSp, attItem.ID, (uint)AttachmentPoint.Chest); Vector3 teleportPosition = new Vector3(10, 11, 12); -- cgit v1.1 From 99954c14980817adae427ab8ac4cdf07cbad0d7d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 26 Jun 2012 22:53:08 +0100 Subject: refactor: Remove unnecessary AttachmentModuleTests.m_userId in favour of local variables --- .../Attachments/Tests/AttachmentsModuleTests.cs | 66 +++++++++------------- OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs | 5 ++ 2 files changed, 31 insertions(+), 40 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index d233faf..ddfc6cb 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -45,6 +45,7 @@ using OpenSim.Region.CoreModules.World.Serialiser; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Interfaces; +using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; @@ -56,21 +57,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests [TestFixture] public class AttachmentsModuleTests { - /// - /// Standard user ID - /// - private UUID m_userId = TestHelpers.ParseTail(0x1); - -// /// -// /// Standard attachment item ID -// /// -// private UUID m_attItemId = TestHelpers.ParseTail(0x10); -// -// /// -// /// Standard attachment asset ID -// /// -// private UUID m_attAssetId = TestHelpers.ParseTail(0x11); - [TestFixtureSetUp] public void FixtureInit() { @@ -131,8 +117,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // TestHelpers.EnableLogging(); Scene scene = CreateDefaultTestScene(); - UserAccountHelpers.CreateUserWithInventory(scene, m_userId); - ScenePresence sp = SceneHelpers.AddScenePresence(scene, m_userId); + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); string attName = "att"; @@ -173,10 +159,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // log4net.Config.XmlConfigurator.Configure(); Scene scene = CreateDefaultTestScene(); - UserAccountHelpers.CreateUserWithInventory(scene, m_userId); - ScenePresence sp = SceneHelpers.AddScenePresence(scene, m_userId); + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); - InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); + InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); scene.AttachmentsModule.RezSingleAttachmentFromInventory( sp, attItem.ID, (uint)AttachmentPoint.Chest); @@ -204,10 +190,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // log4net.Config.XmlConfigurator.Configure(); Scene scene = CreateDefaultTestScene(); - UserAccountHelpers.CreateUserWithInventory(scene, m_userId); - ScenePresence sp = SceneHelpers.AddScenePresence(scene, m_userId); + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); - InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); + InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); ISceneEntity so = scene.AttachmentsModule.RezSingleAttachmentFromInventory( @@ -236,10 +222,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // log4net.Config.XmlConfigurator.Configure(); Scene scene = CreateDefaultTestScene(); - UserAccountHelpers.CreateUserWithInventory(scene, m_userId); - ScenePresence sp = SceneHelpers.AddScenePresence(scene, m_userId); + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); - InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); + InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); scene.AttachmentsModule.RezSingleAttachmentFromInventory( sp, attItem.ID, (uint)AttachmentPoint.Chest); @@ -264,10 +250,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // log4net.Config.XmlConfigurator.Configure(); Scene scene = CreateDefaultTestScene(); - UserAccountHelpers.CreateUserWithInventory(scene, m_userId); - InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); + InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); - AgentCircuitData acd = SceneHelpers.GenerateAgentData(m_userId); + AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); acd.Appearance = new AvatarAppearance(); acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); @@ -287,10 +273,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // log4net.Config.XmlConfigurator.Configure(); Scene scene = CreateDefaultTestScene(); - UserAccountHelpers.CreateUserWithInventory(scene, m_userId); - InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); + InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); - AgentCircuitData acd = SceneHelpers.GenerateAgentData(m_userId); + AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); acd.Appearance = new AvatarAppearance(); acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); @@ -321,10 +307,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); Scene scene = CreateDefaultTestScene(); - UserAccountHelpers.CreateUserWithInventory(scene, m_userId); - InventoryItemBase attItem = CreateAttachmentItem(scene, m_userId, "att", 0x10, 0x20); + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); + InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); - AgentCircuitData acd = SceneHelpers.GenerateAgentData(m_userId); + AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); acd.Appearance = new AvatarAppearance(); acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); ScenePresence sp = SceneHelpers.AddScenePresence(scene, acd); @@ -373,11 +359,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests SceneHelpers.SetupSceneModules( sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); - UserAccountHelpers.CreateUserWithInventory(sceneA, m_userId); - ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, m_userId, sh.SceneManager); + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); + ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, ua1.PrincipalID, sh.SceneManager); beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); - InventoryItemBase attItem = CreateAttachmentItem(sceneA, m_userId, "att", 0x10, 0x20); + InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20); sceneA.AttachmentsModule.RezSingleAttachmentFromInventory( beforeTeleportSp, attItem.ID, (uint)AttachmentPoint.Chest); @@ -395,7 +381,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests ((TestClient)beforeTeleportSp.ControllingClient).CompleteTeleportClientSide(); // Check attachments have made it into sceneB - ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(m_userId); + ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID); // This is appearance data, as opposed to actually rezzed attachments List sceneBAttachments = afterTeleportSceneBSp.Appearance.GetAttachments(); @@ -413,7 +399,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest)); // Check attachments have been removed from sceneA - ScenePresence afterTeleportSceneASp = sceneA.GetScenePresence(m_userId); + ScenePresence afterTeleportSceneASp = sceneA.GetScenePresence(ua1.PrincipalID); // Since this is appearance data, it is still present on the child avatar! List sceneAAttachments = afterTeleportSceneASp.Appearance.GetAttachments(); diff --git a/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs b/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs index b73df2c..3d3e65c 100644 --- a/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs @@ -126,6 +126,11 @@ namespace OpenSim.Tests.Common return CreateUserWithInventory(scene, "Bill", "Bailey", userId, "troll"); } + public static UserAccount CreateUserWithInventory(Scene scene, int userId) + { + return CreateUserWithInventory(scene, "Bill", "Bailey", TestHelpers.ParseTail(userId), "troll"); + } + public static UserAccount CreateUserWithInventory( Scene scene, string firstName, string lastName, UUID userId, string pw) { -- cgit v1.1 From 25245179868990b07d4431e2dc2e800a4de372e5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 26 Jun 2012 22:54:41 +0100 Subject: minor: correct GridService "show regions" cibsike cinnabd usage statement --- OpenSim/Services/GridService/GridService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index 842a697..36cd573 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -98,7 +98,7 @@ namespace OpenSim.Services.GridService if (MainConsole.Instance.Commands.Resolve(new string[] { "show", "regions" }).Length == 0) MainConsole.Instance.Commands.AddCommand("Regions", true, "show regions", - "show all regions", + "show regions", "Show details on all regions", String.Empty, HandleShowRegions); -- cgit v1.1 From 97437feb06060fa58f8209e32c362bfe91c279f5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 26 Jun 2012 23:05:10 +0100 Subject: Show region positions in "show regions" robust console command --- OpenSim/Services/GridService/GridService.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index 36cd573..aab403a 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -650,13 +650,19 @@ namespace OpenSim.Services.GridService ConsoleDisplayTable dispTable = new ConsoleDisplayTable(); dispTable.AddColumn("Name", 16); dispTable.AddColumn("ID", 36); + dispTable.AddColumn("Position", 11); dispTable.AddColumn("Owner ID", 36); dispTable.AddColumn("Flags", 60); foreach (RegionData r in regions) { OpenSim.Data.RegionFlags flags = (OpenSim.Data.RegionFlags)Convert.ToInt32(r.Data["flags"]); - dispTable.AddRow(r.RegionName, r.RegionID.ToString(), r.Data["owner_uuid"].ToString(), flags.ToString()); + dispTable.AddRow( + r.RegionName, + r.RegionID.ToString(), + string.Format("{0},{1}", r.coordX, r.coordY), + r.Data["owner_uuid"].ToString(), + flags.ToString()); } MainConsole.Instance.Output(dispTable.ToString()); -- cgit v1.1 From 0b298777907d29027336813d84e589f0cb78419b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 26 Jun 2012 23:15:15 +0100 Subject: Fix output for help on some object region console commands --- .../CoreModules/World/Objects/Commands/ObjectCommandsModule.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index 830d9cb..e5cd3e2 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -98,7 +98,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands m_console.Commands.AddCommand( "Objects", false, "delete object name", "delete object name [--regex] ", - "Delete a scene object by name.\nIf --regex is specified then the name is treatead as a regular expression", + "Delete a scene object by name.", + "If --regex is specified then the name is treatead as a regular expression", HandleDeleteObject); m_console.Commands.AddCommand( @@ -118,7 +119,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands false, "show object name", "show object name [--regex] ", - "Show details of scene objects with the given name.\nIf --regex is specified then the name is treatead as a regular expression", + "Show details of scene objects with the given name.", + "If --regex is specified then the name is treatead as a regular expression", HandleShowObjectByName); m_console.Commands.AddCommand( @@ -133,7 +135,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands false, "show part name", "show part name [--regex] ", - "Show details of scene object parts with the given name.\nIf --regex is specified then the name is treatead as a regular expression", + "Show details of scene object parts with the given name.", + "If --regex is specified then the name is treatead as a regular expression", HandleShowPartByName); } -- cgit v1.1 From 87ca820f9bc19fc1f8c7b88a87bdef59e0a5bd0b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 26 Jun 2012 23:28:48 +0100 Subject: Replace "kill uuid" console command with the more consistent "delete object uuid", which was present in the last opensim release. --- OpenSim/Region/Application/OpenSim.cs | 56 ----------------------------------- 1 file changed, 56 deletions(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 04ff4e6..56ad5c9 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -409,10 +409,6 @@ namespace OpenSim m_console.Commands.AddCommand("General", false, "modules unload", "modules unload ", "Unload a module", HandleModules); - - m_console.Commands.AddCommand("Objects", false, "kill uuid", - "kill uuid ", - "Kill an object by UUID", KillUUID); } public override void ShutdownSpecific() @@ -1309,58 +1305,6 @@ namespace OpenSim return result; } - /// - /// Kill an object given its UUID. - /// - /// - protected void KillUUID(string module, string[] cmdparams) - { - if (cmdparams.Length > 2) - { - UUID id = UUID.Zero; - SceneObjectGroup grp = null; - Scene sc = null; - - if (!UUID.TryParse(cmdparams[2], out id)) - { - MainConsole.Instance.Output("[KillUUID]: Error bad UUID format!"); - return; - } - - m_sceneManager.ForEachScene( - delegate(Scene scene) - { - SceneObjectPart part = scene.GetSceneObjectPart(id); - if (part == null) - return; - - grp = part.ParentGroup; - sc = scene; - }); - - if (grp == null) - { - MainConsole.Instance.Output(String.Format("[KillUUID]: Given UUID {0} not found!", id)); - } - else - { - MainConsole.Instance.Output(String.Format("[KillUUID]: Found UUID {0} in scene {1}", id, sc.RegionInfo.RegionName)); - try - { - sc.DeleteSceneObject(grp, false); - } - catch (Exception e) - { - m_log.ErrorFormat("[KillUUID]: Error while removing objects from scene: " + e); - } - } - } - else - { - MainConsole.Instance.Output("[KillUUID]: Usage: kill uuid "); - } - } - #endregion } } -- cgit v1.1 From 5bec5bcf714a94129070cf1b6219984496cbd6c2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 27 Jun 2012 00:00:49 +0100 Subject: Automatically disable log4net before each regression test so that logging is confined to a single test if it's turned on. This involves making test classes inherit from a common OpenSimTestCase. This will be applied to more classes as required. --- .../Attachments/Tests/AttachmentsModuleTests.cs | 4 +- .../Archiver/Tests/InventoryArchiveTestCase.cs | 2 +- OpenSim/Tests/Common/OpenSimTestCase.cs | 46 ++++++++++++++++++++++ OpenSim/Tests/Common/TestHelpers.cs | 3 +- 4 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 OpenSim/Tests/Common/OpenSimTestCase.cs diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index ddfc6cb..65722fe 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -55,7 +55,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests /// Attachment tests /// [TestFixture] - public class AttachmentsModuleTests + public class AttachmentsModuleTests : OpenSimTestCase { [TestFixtureSetUp] public void FixtureInit() @@ -409,8 +409,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // This is the actual attachment, which should no longer exist List actualSceneAAttachments = afterTeleportSceneASp.GetAttachments(); Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0)); - -// TestHelpers.DisableLogging(); } // I'm commenting this test because scene setup NEEDS InventoryService to diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs index 90ae69d..f9d4b78 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs @@ -48,7 +48,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests { [TestFixture] - public class InventoryArchiveTestCase + public class InventoryArchiveTestCase : OpenSimTestCase { protected ManualResetEvent mre = new ManualResetEvent(false); diff --git a/OpenSim/Tests/Common/OpenSimTestCase.cs b/OpenSim/Tests/Common/OpenSimTestCase.cs new file mode 100644 index 0000000..8c40923 --- /dev/null +++ b/OpenSim/Tests/Common/OpenSimTestCase.cs @@ -0,0 +1,46 @@ +/* + * 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 NUnit.Framework; + +namespace OpenSim.Tests.Common +{ + [TestFixture] + public class OpenSimTestCase + { + [SetUp] + public virtual void SetUp() + { +// TestHelpers.InMethod(); + // Disable logging for each test so that one where logging is enabled doesn't cause all subsequent tests + // to have logging on if it failed with an exception. + TestHelpers.DisableLogging(); + } + } +} + diff --git a/OpenSim/Tests/Common/TestHelpers.cs b/OpenSim/Tests/Common/TestHelpers.cs index d38d692..30121fe 100644 --- a/OpenSim/Tests/Common/TestHelpers.cs +++ b/OpenSim/Tests/Common/TestHelpers.cs @@ -58,7 +58,7 @@ namespace OpenSim.Tests.Common ")); - private static Stream DisableLoggingConfigStream + private static MemoryStream DisableLoggingConfigStream = new MemoryStream( Encoding.UTF8.GetBytes( // "")); @@ -109,6 +109,7 @@ namespace OpenSim.Tests.Common public static void DisableLogging() { log4net.Config.XmlConfigurator.Configure(DisableLoggingConfigStream); + DisableLoggingConfigStream.Position = 0; } /// -- cgit v1.1 From d0432133172f4147f7401f214c703611978423cd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 27 Jun 2012 00:41:46 +0100 Subject: refactor: Move ScenePresence <-> AgentData attachments copying code into AttachmentsModule. --- .../Avatar/Attachments/AttachmentsModule.cs | 50 ++++++++++++++++++++++ .../Framework/Interfaces/IAttachmentsModule.cs | 14 ++++++ .../Region/Framework/Interfaces/IScenePresence.cs | 6 +++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 41 ++---------------- 4 files changed, 74 insertions(+), 37 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 2b0e4ab..4a7fbce 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -100,6 +100,56 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments #region IAttachmentsModule + public void CopyAttachments(IScenePresence sp, AgentData ad) + { + lock (sp.AttachmentsSyncLock) + { + // Attachment objects + List attachments = sp.GetAttachments(); + if (attachments.Count > 0) + { + ad.AttachmentObjects = new List(); + ad.AttachmentObjectStates = new List(); + // IScriptModule se = m_scene.RequestModuleInterface(); + sp.InTransitScriptStates.Clear(); + + foreach (SceneObjectGroup sog in attachments) + { + // We need to make a copy and pass that copy + // because of transfers withn the same sim + ISceneObject clone = sog.CloneForNewScene(); + // Attachment module assumes that GroupPosition holds the offsets...! + ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; + ((SceneObjectGroup)clone).IsAttachment = false; + ad.AttachmentObjects.Add(clone); + string state = sog.GetStateSnapshot(); + ad.AttachmentObjectStates.Add(state); + sp.InTransitScriptStates.Add(state); + // Let's remove the scripts of the original object here + sog.RemoveScriptInstances(true); + } + } + } + } + + public void CopyAttachments(AgentData ad, IScenePresence sp) + { + if (ad.AttachmentObjects != null && ad.AttachmentObjects.Count > 0) + { + lock (sp.AttachmentsSyncLock) + sp.ClearAttachments(); + + int i = 0; + foreach (ISceneObject so in ad.AttachmentObjects) + { + ((SceneObjectGroup)so).LocalId = 0; + ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule(); + so.SetState(ad.AttachmentObjectStates[i++], m_scene); + m_scene.IncomingCreateObject(Vector3.Zero, so); + } + } + } + /// /// RezAttachments. This should only be called upon login on the first region. /// Attachment rezzings on crossings and TPs are done in a different way. diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index fde5de1..375d334 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -36,6 +36,20 @@ namespace OpenSim.Region.Framework.Interfaces public interface IAttachmentsModule { /// + /// Copy attachment data from a ScenePresence into the AgentData structure for transmission to another simulator + /// + /// + /// + void CopyAttachments(IScenePresence sp, AgentData ad); + + /// + /// Copy attachment data from an AgentData structure into a ScenePresence. + /// + /// + /// + void CopyAttachments(AgentData ad, IScenePresence sp); + + /// /// RezAttachments. This should only be called upon login on the first region. /// Attachment rezzings on crossings and TPs are done in a different way. /// diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs index 5e43843..19a8236 100644 --- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs +++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs @@ -41,6 +41,12 @@ namespace OpenSim.Region.Framework.Interfaces public interface IScenePresence : ISceneAgent { /// + /// Copy of the script states while the agent is in transit. This state may + /// need to be placed back in case of transfer fail. + /// + List InTransitScriptStates { get; } + + /// /// The AttachmentsModule synchronizes on this to avoid race conditions between commands to add and remove attachments. /// /// diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 909c7c8..c7a670f 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3084,31 +3084,8 @@ namespace OpenSim.Region.Framework.Scenes } catch { } - // Attachment objects - List attachments = GetAttachments(); - if (attachments.Count > 0) - { - cAgent.AttachmentObjects = new List(); - cAgent.AttachmentObjectStates = new List(); -// IScriptModule se = m_scene.RequestModuleInterface(); - InTransitScriptStates.Clear(); - - foreach (SceneObjectGroup sog in attachments) - { - // We need to make a copy and pass that copy - // because of transfers withn the same sim - ISceneObject clone = sog.CloneForNewScene(); - // Attachment module assumes that GroupPosition holds the offsets...! - ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; - ((SceneObjectGroup)clone).IsAttachment = false; - cAgent.AttachmentObjects.Add(clone); - string state = sog.GetStateSnapshot(); - cAgent.AttachmentObjectStates.Add(state); - InTransitScriptStates.Add(state); - // Let's remove the scripts of the original object here - sog.RemoveScriptInstances(true); - } - } + if (Scene.AttachmentsModule != null) + Scene.AttachmentsModule.CopyAttachments(this, cAgent); } private void CopyFrom(AgentData cAgent) @@ -3178,18 +3155,8 @@ namespace OpenSim.Region.Framework.Scenes if (cAgent.Anims != null) Animator.Animations.FromArray(cAgent.Anims); - if (cAgent.AttachmentObjects != null && cAgent.AttachmentObjects.Count > 0) - { - m_attachments = new List(); - int i = 0; - foreach (ISceneObject so in cAgent.AttachmentObjects) - { - ((SceneObjectGroup)so).LocalId = 0; - ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule(); - so.SetState(cAgent.AttachmentObjectStates[i++], m_scene); - m_scene.IncomingCreateObject(Vector3.Zero, so); - } - } + if (Scene.AttachmentsModule != null) + Scene.AttachmentsModule.CopyAttachments(cAgent, this); } public bool CopyAgent(out IAgentData agent) -- cgit v1.1 From bb48060b447a1b9c85f8652cd4bd177558d3bb0d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 27 Jun 2012 00:50:36 +0100 Subject: Fix issue in InventoryArchiveTestCase where it didn't call down to OpenSimTestCase.SetUp() --- .../Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs index f9d4b78..1056865 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs @@ -84,8 +84,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests protected string m_coaItemName = "Coalesced Item"; [SetUp] - public virtual void SetUp() + public override void SetUp() { + base.SetUp(); m_iarStream = new MemoryStream(m_iarStreamBytes); } -- cgit v1.1 From f9769a9fcb84a68622abe23160274796937ae0d4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Jun 2012 00:37:23 +0100 Subject: minor: reuse colon index calculation in XEngine.OnRezScript. The index if a colon is found on the first line will always be the same as for the whole script. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 06ed9d6..73d384d 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -768,12 +768,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine int colon = firstline.IndexOf(':'); if (firstline.Length > 2 && firstline.Substring(0, 2) == "//" && colon != -1) { - string engineName = firstline.Substring(2, colon-2); + string engineName = firstline.Substring(2, colon - 2); if (names.Contains(engineName)) { engine = engineName; - script = "//" + script.Substring(script.IndexOf(':')+1); + script = "//" + script.Substring(colon + 1); } else { -- cgit v1.1 From 25baa2d894e9bbbb173eb4e6ebe1478d2e3c1265 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Jun 2012 00:58:36 +0100 Subject: Avoid reporting false positives when a colon is in a comment in the first line of a script where the user was not trying to select a different script engine. This works by only posting the "Selected engine unavailable" message if we're falling back on XEngine and the language is one handled by XEngine. In cases where the language is not handled or not allowed, the user will still be notified by the later compiler error. This avoids the overwhelming majority of false positives where the first line contains a : for other reasons (e.g. source control systems, vim settings, etc.) Ultimately, I think it would be better to detect script language/engine with a mechanism that didn't just rely on : detection (e.g like #! in unix scripts). --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 58 ++++++++++++++++++-------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 73d384d..a709be3 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -779,24 +779,48 @@ namespace OpenSim.Region.ScriptEngine.XEngine { if (engine == ScriptEngineName) { - SceneObjectPart part = - m_Scene.GetSceneObjectPart( - localID); - - TaskInventoryItem item = - part.Inventory.GetInventoryItem(itemID); - - ScenePresence presence = - m_Scene.GetScenePresence( - item.OwnerID); - - if (presence != null) + // If we are falling back on XEngine as the default engine, then only complain to the user + // if a script language has been explicitly set and it's one that we recognize. If it's + // explicitly not allowed or the script is not in LSL then the user will be informed by a later compiler message. + // + // This avoids the overwhelming number of false positives where we're in this code because + // there's a colon in a comment in the first line of a script for entirely + // unrelated reasons (e.g. vim settings). + // + // TODO: A better fix would be to deprecate simple : detection and look for some less likely + // string to begin the comment (like #! in unix shell scripts). + bool scriptExplicitlyInXEngineLanguage = false; + string restOfScript = script.Substring(colon + 1); + + // FIXME: These are hardcoded because they are currently hardcoded in Compiler.cs + if (restOfScript.StartsWith("c#") + || restOfScript.StartsWith("vb") + || restOfScript.StartsWith("lsl") + || restOfScript.StartsWith("js") + || restOfScript.StartsWith("yp")) + scriptExplicitlyInXEngineLanguage = true; + + if (scriptExplicitlyInXEngineLanguage) { - presence.ControllingClient.SendAgentAlertMessage( - "Selected engine unavailable. "+ - "Running script on "+ - ScriptEngineName, - false); + SceneObjectPart part = + m_Scene.GetSceneObjectPart( + localID); + + TaskInventoryItem item = + part.Inventory.GetInventoryItem(itemID); + + ScenePresence presence = + m_Scene.GetScenePresence( + item.OwnerID); + + if (presence != null) + { + presence.ControllingClient.SendAgentAlertMessage( + "Selected engine unavailable. "+ + "Running script on "+ + ScriptEngineName, + false); + } } } } -- cgit v1.1 From 972b0b52f9acedf13114fbed2ec35bb63adeea79 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Jun 2012 21:30:36 +0100 Subject: If rest of first line after colon is blank then still warn about running in XEngine if engine specified does not exist. This is to take account of situations where the user was intending to specify a script engine using colon using its default language. This probably generates few false positive as scripts are less likely to end a first line colon with a comment for other purposes. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 29 ++++++++++++++++---------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index a709be3..35fac4e 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -780,27 +780,34 @@ namespace OpenSim.Region.ScriptEngine.XEngine if (engine == ScriptEngineName) { // If we are falling back on XEngine as the default engine, then only complain to the user - // if a script language has been explicitly set and it's one that we recognize. If it's + // if a script language has been explicitly set and it's one that we recognize or there are + // no non-whitespace characters after the colon. + // + // If the script is // explicitly not allowed or the script is not in LSL then the user will be informed by a later compiler message. // + // If the colon ends the line then we'll risk the false positive as this is more likely + // to signal a real scriptengine line where the user wants to use the default compile language. + // // This avoids the overwhelming number of false positives where we're in this code because // there's a colon in a comment in the first line of a script for entirely // unrelated reasons (e.g. vim settings). // // TODO: A better fix would be to deprecate simple : detection and look for some less likely // string to begin the comment (like #! in unix shell scripts). - bool scriptExplicitlyInXEngineLanguage = false; - string restOfScript = script.Substring(colon + 1); + bool warnRunningInXEngine = false; + string restOfFirstLine = firstline.Substring(colon + 1); // FIXME: These are hardcoded because they are currently hardcoded in Compiler.cs - if (restOfScript.StartsWith("c#") - || restOfScript.StartsWith("vb") - || restOfScript.StartsWith("lsl") - || restOfScript.StartsWith("js") - || restOfScript.StartsWith("yp")) - scriptExplicitlyInXEngineLanguage = true; - - if (scriptExplicitlyInXEngineLanguage) + if (restOfFirstLine.StartsWith("c#") + || restOfFirstLine.StartsWith("vb") + || restOfFirstLine.StartsWith("lsl") + || restOfFirstLine.StartsWith("js") + || restOfFirstLine.StartsWith("yp") + || restOfFirstLine.Length == 0) + warnRunningInXEngine = true; + + if (warnRunningInXEngine) { SceneObjectPart part = m_Scene.GetSceneObjectPart( -- cgit v1.1 From a1a22a2f1034a1feb67b141abf4b138248cdb356 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 28 Jun 2012 22:02:20 +0100 Subject: Revert "Mantis 5977 Corrections to llRegionSayTo" This reverts commit 679da63da617d031e5e7ae3f2d2a29db1a23ace3. Conflicts: OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs --- OpenSim/Framework/OSChatMessage.cs | 20 ------- .../Region/CoreModules/Avatar/Chat/ChatModule.cs | 50 +++++----------- .../Scripting/WorldComm/WorldCommModule.cs | 70 +++++++++++----------- OpenSim/Region/Framework/Interfaces/IWorldComm.cs | 2 +- .../Framework/Scenes/Scene.PacketHandlers.cs | 26 +------- .../Shared/Api/Implementation/LSL_Api.cs | 10 ++-- 6 files changed, 59 insertions(+), 119 deletions(-) diff --git a/OpenSim/Framework/OSChatMessage.cs b/OpenSim/Framework/OSChatMessage.cs index 455756d..54fa275 100644 --- a/OpenSim/Framework/OSChatMessage.cs +++ b/OpenSim/Framework/OSChatMessage.cs @@ -51,12 +51,10 @@ namespace OpenSim.Framework protected object m_senderObject; protected ChatTypeEnum m_type; protected UUID m_fromID; - protected UUID m_toID; public OSChatMessage() { m_position = new Vector3(); - m_toID = UUID.Zero; } /// @@ -104,15 +102,6 @@ namespace OpenSim.Framework set { m_from = value; } } - /// - /// The name of the sender (needed for scripts) - /// - public string To - { - get { return m_from; } - set { m_from = value; } - } - #region IEventArgs Members /// TODO: Sender and SenderObject should just be Sender and of @@ -143,15 +132,6 @@ namespace OpenSim.Framework } /// - /// The single recipient or all if not set. - /// - public UUID TargetUUID - { - get { return m_toID; } - set { m_toID = value; } - } - - /// /// /// public IScene Scene diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 6ffc7e6..5649855 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs @@ -197,7 +197,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat string fromName = c.From; string fromNamePrefix = ""; UUID fromID = UUID.Zero; - UUID targetID = c.TargetUUID; string message = c.Message; IScene scene = c.Scene; Vector3 fromPos = c.Position; @@ -236,31 +235,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat message = message.Substring(0, 1000); // m_log.DebugFormat( -// "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}, targetID {5}", -// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType, targetID); +// "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}", +// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType); HashSet receiverIDs = new HashSet(); - + foreach (Scene s in m_scenes) { - if (targetID == UUID.Zero) - { - // This should use ForEachClient, but clients don't have a position. - // If camera is moved into client, then camera position can be used - s.ForEachRootScenePresence( - delegate(ScenePresence presence) - { - if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType, false)) - receiverIDs.Add(presence.UUID); - } - ); - } - else - { - // This is a send to a specific client eg from llRegionSayTo - // no need to check distance etc, jand send is as say - ScenePresence presence = s.GetScenePresence(targetID); - if (presence != null && !presence.IsChildAgent) + // This should use ForEachClient, but clients don't have a position. + // If camera is moved into client, then camera position can be used + s.ForEachRootScenePresence( + delegate(ScenePresence presence) { ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y); if (Presencecheck != null) @@ -271,14 +256,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat // objects on a parcel with access restrictions if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true) { - if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix + fromName, c.Type, message, sourceType, false)) + if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix + fromName, c.Type, message, sourceType)) receiverIDs.Add(presence.UUID); } } } - } + ); } - + (scene as Scene).EventManager.TriggerOnChatToClients( fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully); } @@ -358,7 +343,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat /// precondition protected virtual bool TrySendChatMessage(ScenePresence presence, Vector3 fromPos, Vector3 regionPos, UUID fromAgentID, string fromName, ChatTypeEnum type, - string message, ChatSourceType src, bool ignoreDistance) + string message, ChatSourceType src) { // don't send stuff to child agents if (presence.IsChildAgent) return false; @@ -369,15 +354,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); - - if (!ignoreDistance) + + if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || + type == ChatTypeEnum.Say && dis > m_saydistance || + type == ChatTypeEnum.Shout && dis > m_shoutdistance) { - if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || - type == ChatTypeEnum.Say && dis > m_saydistance || - type == ChatTypeEnum.Shout && dis > m_shoutdistance) - { - return false; - } + return false; } // TODO: should change so the message is sent through the avatar rather than direct to the ClientView diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index 8358bc0..176c86d 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -308,56 +308,56 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm /// /// Message. /// - public void DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg) + public bool DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg, out string error) { + error = null; // Is id an avatar? ScenePresence sp = m_scene.GetScenePresence(target); if (sp != null) { - // ignore if a child agent this is restricted to inside one region - if (sp.IsChildAgent) - return; - - // Send message to the avatar. - // Channel zero only goes to the avatar - // non zero channel messages only go to the attachments + // Send message to avatar if (channel == 0) { - m_scene.SimChatToAgent(target, Utils.StringToBytes(msg), pos, name, id, false); - } - else - { - List attachments = sp.GetAttachments(); - if (attachments.Count == 0) - return; + m_scene.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, false); + } - // Get uuid of attachments - List targets = new List(); - foreach (SceneObjectGroup sog in attachments) - { - if (!sog.IsDeleted) - targets.Add(sog.UUID); - } + List attachments = sp.GetAttachments(); - // Need to check each attachment - foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) - { - if (li.GetHostID().Equals(id)) - continue; + if (attachments.Count == 0) + return true; - if (m_scene.GetSceneObjectPart(li.GetHostID()) == null) - continue; + // Get uuid of attachments + List targets = new List(); + foreach (SceneObjectGroup sog in attachments) + { + if (!sog.IsDeleted) + targets.Add(sog.UUID); + } - if (targets.Contains(li.GetHostID())) - QueueMessage(new ListenerInfo(li, name, id, msg)); - } + // Need to check each attachment + foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) + { + if (li.GetHostID().Equals(id)) + continue; + + if (m_scene.GetSceneObjectPart(li.GetHostID()) == null) + continue; + + if (targets.Contains(li.GetHostID())) + QueueMessage(new ListenerInfo(li, name, id, msg)); } - return; + return true; + } + + // Need to toss an error here + if (channel == 0) + { + error = "Cannot use llRegionSayTo to message objects on channel 0"; + return false; } - // No avatar found so look for an object foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) { // Dont process if this message is from yourself! @@ -375,7 +375,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm } } - return; + return true; } protected void QueueMessage(ListenerInfo li) diff --git a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs index 4e74781..e8e375e 100644 --- a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs +++ b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs @@ -103,7 +103,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Message. /// - void DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg); + bool DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg, out string error); /// /// Are there any listen events ready to be dispatched? diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index cf68ff4..3ef1e29 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -38,9 +38,8 @@ namespace OpenSim.Region.Framework.Scenes { public partial class Scene { - protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, - UUID fromID, UUID targetID, bool fromAgent, bool broadcast) + UUID fromID, bool fromAgent, bool broadcast) { OSChatMessage args = new OSChatMessage(); @@ -64,20 +63,14 @@ namespace OpenSim.Region.Framework.Scenes } args.From = fromName; - args.TargetUUID = targetID; + //args. if (broadcast) EventManager.TriggerOnChatBroadcast(this, args); else EventManager.TriggerOnChatFromWorld(this, args); } - - protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, - UUID fromID, bool fromAgent, bool broadcast) - { - SimChat(message, type, channel, fromPos, fromName, fromID, UUID.Zero, fromAgent, broadcast); - } - + /// /// /// @@ -115,19 +108,6 @@ namespace OpenSim.Region.Framework.Scenes { SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, true); } - /// - /// - /// - /// - /// - /// - /// - /// - /// - public void SimChatToAgent(UUID targetID, byte[] message, Vector3 fromPos, string fromName, UUID fromID, bool fromAgent) - { - SimChat(message, ChatTypeEnum.Say, 0, fromPos, fromName, fromID, targetID, fromAgent, false); - } /// /// Invoked when the client requests a prim. diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 41de257..ffa19d9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -921,22 +921,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llRegionSayTo(string target, int channel, string msg) { + string error = String.Empty; + if (msg.Length > 1023) msg = msg.Substring(0, 1023); m_host.AddScriptLPS(1); - if (channel == ScriptBaseClass.DEBUG_CHANNEL) - { - return; - } - UUID TargetID; UUID.TryParse(target, out TargetID); IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); if (wComm != null) - wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); + if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error)) + LSLError(error); } public LSL_Integer llListen(int channelID, string name, string ID, string msg) -- cgit v1.1 From f263d6a910f5c382756da04dd423db4a46b1eeb7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Jun 2012 22:48:49 +0100 Subject: Remove code that tried to delete an attachment back to inventory if RezSingleAttachmentFromInventoryInternal() returned null. null would only ever be returned if the item couldn't be located within inventory and this would happen immediately. In this case, derezzing wouldn't work anyway since there is no item to derez. --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 4a7fbce..e3ee2fc 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -365,12 +365,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return null; } - SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); - - if (att == null) - DetachSingleAttachmentToInv(sp, itemID); - - return att; + return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); } public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List> rezlist) -- cgit v1.1 From 571fd966cbcb4e718703bc194384f6bf84c211df Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Jun 2012 23:01:12 +0100 Subject: Rather than iterating through all SOGs in the scene looking for the one that matches out fromItemID on detach, go through the agent's attachment sog list instead. --- .../Avatar/Attachments/AttachmentsModule.cs | 41 +++++++++------------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index e3ee2fc..e9f0488 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -666,34 +666,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (itemID == UUID.Zero) // If this happened, someone made a mistake.... return; - // We can NOT use the dictionries here, as we are looking - // for an entity by the fromAssetID, which is NOT the prim UUID - EntityBase[] detachEntities = m_scene.GetEntities(); - SceneObjectGroup group; - lock (sp.AttachmentsSyncLock) { - foreach (EntityBase entity in detachEntities) + List attachments = sp.GetAttachments(); + + foreach (SceneObjectGroup group in attachments) { - if (entity is SceneObjectGroup) + if (group.FromItemID == itemID) { - group = (SceneObjectGroup)entity; - if (group.FromItemID == itemID) - { - m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); - sp.RemoveAttachment(group); - m_scene.DeleteSceneObject(group, false); - - // Prepare sog for storage - group.AttachedAvatar = UUID.Zero; - group.RootPart.SetParentLocalId(0); - group.IsAttachment = false; - group.AbsolutePosition = group.RootPart.AttachedPos; - - UpdateKnownItem(sp, group, true); - - return; - } + m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); + sp.RemoveAttachment(group); + m_scene.DeleteSceneObject(group, false); + + // Prepare sog for storage + group.AttachedAvatar = UUID.Zero; + group.RootPart.SetParentLocalId(0); + group.IsAttachment = false; + group.AbsolutePosition = group.RootPart.AttachedPos; + + UpdateKnownItem(sp, group, true); + + return; } } } -- cgit v1.1 From bfa6896678872a4e796ec4de22e83b6cead3ba17 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Jun 2012 23:31:23 +0100 Subject: Change AttachmentsModule.DetachSingleAttachmentToInv() to accept a SOG directly instead of an item ID to then shuffle through attachments, saving CPU busywork. Almost all callers already had the sog to hand. Still checking that it's really an attachment, but now by inspecting SOG.AttachedAvatar --- .../Avatar/Attachments/AttachmentsModule.cs | 78 ++++++++++++---------- .../Attachments/Tests/AttachmentsModuleTests.cs | 7 +- .../Framework/Interfaces/IAttachmentsModule.cs | 6 +- .../Region/Framework/Interfaces/IScenePresence.cs | 4 ++ .../Shared/Api/Implementation/LSL_Api.cs | 15 ++--- 5 files changed, 58 insertions(+), 52 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index e9f0488..af30a8e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -302,10 +302,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // At the moment we can only deal with a single attachment if (attachments.Count != 0) { - UUID oldAttachmentItemID = attachments[0].FromItemID; - - if (oldAttachmentItemID != UUID.Zero) - DetachSingleAttachmentToInvInternal(sp, oldAttachmentItemID); + if (attachments[0].FromItemID != UUID.Zero) + DetachSingleAttachmentToInvInternal(sp, attachments[0]); else m_log.WarnFormat( "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!", @@ -442,18 +440,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); } - public void DetachSingleAttachmentToInv(IScenePresence sp, UUID itemID) + public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so) { lock (sp.AttachmentsSyncLock) { // Save avatar attachment information // m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); - bool changed = sp.Appearance.DetachAttachment(itemID); + if (so.AttachedAvatar != sp.UUID) + { + m_log.WarnFormat( + "[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}", + so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName); + + return; + } + + bool changed = sp.Appearance.DetachAttachment(so.FromItemID); if (changed && m_scene.AvatarFactory != null) m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); - DetachSingleAttachmentToInvInternal(sp, itemID); + DetachSingleAttachmentToInvInternal(sp, so); } } @@ -657,39 +664,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return newItem; } - // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. - // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? - private void DetachSingleAttachmentToInvInternal(IScenePresence sp, UUID itemID) + private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so) { // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); - if (itemID == UUID.Zero) // If this happened, someone made a mistake.... - return; - - lock (sp.AttachmentsSyncLock) - { - List attachments = sp.GetAttachments(); - - foreach (SceneObjectGroup group in attachments) - { - if (group.FromItemID == itemID) - { - m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); - sp.RemoveAttachment(group); - m_scene.DeleteSceneObject(group, false); - - // Prepare sog for storage - group.AttachedAvatar = UUID.Zero; - group.RootPart.SetParentLocalId(0); - group.IsAttachment = false; - group.AbsolutePosition = group.RootPart.AttachedPos; + m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero); + sp.RemoveAttachment(so); + m_scene.DeleteSceneObject(so, false); - UpdateKnownItem(sp, group, true); + // Prepare sog for storage + so.AttachedAvatar = UUID.Zero; + so.RootPart.SetParentLocalId(0); + so.IsAttachment = false; + so.AbsolutePosition = so.RootPart.AttachedPos; - return; - } - } - } + UpdateKnownItem(sp, so, true); } private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( @@ -897,8 +886,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); + if (sp != null && group != null) - DetachSingleAttachmentToInv(sp, group.FromItemID); + DetachSingleAttachmentToInv(sp, group); } private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient) @@ -908,7 +898,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); if (sp != null) - DetachSingleAttachmentToInv(sp, itemID); + { + lock (sp.AttachmentsSyncLock) + { + List attachments = sp.GetAttachments(); + + foreach (SceneObjectGroup group in attachments) + { + if (group.FromItemID == itemID) + { + DetachSingleAttachmentToInv(sp, group); + return; + } + } + } + } } private void Client_OnObjectDrop(uint soLocalId, IClientAPI remoteClient) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 65722fe..b0c087f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -227,9 +227,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); - scene.AttachmentsModule.RezSingleAttachmentFromInventory( - sp, attItem.ID, (uint)AttachmentPoint.Chest); - scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, attItem.ID); + SceneObjectGroup so + = (SceneObjectGroup)scene.AttachmentsModule.RezSingleAttachmentFromInventory( + sp, attItem.ID, (uint)AttachmentPoint.Chest); + scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, so); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.False); diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 375d334..ba35a41 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -109,11 +109,11 @@ namespace OpenSim.Region.Framework.Interfaces void DetachSingleAttachmentToGround(IScenePresence sp, uint objectLocalID); /// - /// Detach the given item so that it remains in the user's inventory. + /// Detach the given attachment so that it remains in the user's inventory. /// /// /param> - /// - void DetachSingleAttachmentToInv(IScenePresence sp, UUID itemID); + /// The attachment to detach. + void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup grp); /// /// Update the position of an attachment. diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs index 19a8236..e6b926c 100644 --- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs +++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs @@ -72,6 +72,10 @@ namespace OpenSim.Region.Framework.Interfaces /// List GetAttachments(uint attachmentPoint); + /// + /// Does this avatar have any attachments? + /// + /// bool HasAttachments(); // Don't use these methods directly. Instead, use the AttachmentsModule diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a8679e2..12eb098 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2990,15 +2990,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api private void DetachWrapper(object o) { - SceneObjectPart host = (SceneObjectPart)o; - - SceneObjectGroup grp = host.ParentGroup; - UUID itemID = grp.FromItemID; - ScenePresence presence = World.GetScenePresence(host.OwnerID); - - IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; - if (attachmentsModule != null) - attachmentsModule.DetachSingleAttachmentToInv(presence, itemID); + if (World.AttachmentsModule != null) + { + SceneObjectPart host = (SceneObjectPart)o; + ScenePresence presence = World.GetScenePresence(host.OwnerID); + World.AttachmentsModule.DetachSingleAttachmentToInv(presence, host.ParentGroup); + } } public void llAttachToAvatar(int attachmentPoint) -- cgit v1.1 From f202c36106815949e56c58612770a00c65ab80a3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Jun 2012 00:03:22 +0100 Subject: Add IScene.Name for code clarity to replace the RegionInfo.RegionName used in many, many log messages. --- OpenSim/Framework/IScene.cs | 5 +++ .../ClientStack/Linden/UDP/Tests/MockScene.cs | 3 +- OpenSim/Region/Framework/Scenes/Scene.cs | 50 +++++++++++----------- OpenSim/Region/Framework/Scenes/SceneBase.cs | 12 ++++-- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs index b2604f4..a9432c2 100644 --- a/OpenSim/Framework/IScene.cs +++ b/OpenSim/Framework/IScene.cs @@ -56,6 +56,11 @@ namespace OpenSim.Framework public interface IScene { + /// + /// The name of this scene. + /// + string Name { get; } + RegionInfo RegionInfo { get; } RegionStatus RegionStatus { get; set; } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs index d76927b..119a677 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs @@ -44,9 +44,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests } protected int m_objectNameCallsReceived; - public MockScene() + public MockScene() : base(new RegionInfo(1000, 1000, null, null)) { - m_regInfo = new RegionInfo(1000, 1000, null, null); m_regStatus = RegionStatus.Up; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d449116..c28979e 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -614,8 +614,7 @@ namespace OpenSim.Region.Framework.Scenes m_sceneGridService = sceneGridService; m_SimulationDataService = simDataService; m_EstateDataService = estateDataService; - m_regionHandle = m_regInfo.RegionHandle; - m_regionName = m_regInfo.RegionName; + m_regionHandle = RegionInfo.RegionHandle; m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); m_asyncSceneObjectDeleter.Enabled = true; @@ -630,7 +629,7 @@ namespace OpenSim.Region.Framework.Scenes // resave. // FIXME: It shouldn't be up to the database plugins to create this data - we should do it when a new // region is set up and avoid these gyrations. - RegionSettings rs = simDataService.LoadRegionSettings(m_regInfo.RegionID); + RegionSettings rs = simDataService.LoadRegionSettings(RegionInfo.RegionID); bool updatedTerrainTextures = false; if (rs.TerrainTexture1 == UUID.Zero) { @@ -659,10 +658,10 @@ namespace OpenSim.Region.Framework.Scenes if (updatedTerrainTextures) rs.Save(); - m_regInfo.RegionSettings = rs; + RegionInfo.RegionSettings = rs; if (estateDataService != null) - m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false); + RegionInfo.EstateSettings = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false); #endregion Region Settings @@ -828,7 +827,7 @@ namespace OpenSim.Region.Framework.Scenes StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; } - public Scene(RegionInfo regInfo) + public Scene(RegionInfo regInfo) : base(regInfo) { PhysicalPrims = true; CollidablePrims = true; @@ -855,7 +854,6 @@ namespace OpenSim.Region.Framework.Scenes WestBorders.Add(westBorder); BordersLocked = false; - m_regInfo = regInfo; m_eventManager = new EventManager(); m_permissions = new ScenePermissions(this); @@ -1199,8 +1197,8 @@ namespace OpenSim.Region.Framework.Scenes m_sceneGraph.Close(); - if (!GridService.DeregisterRegion(m_regInfo.RegionID)) - m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", m_regInfo.RegionName); + if (!GridService.DeregisterRegion(RegionInfo.RegionID)) + m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name); // call the base class Close method. base.Close(); @@ -1720,14 +1718,14 @@ namespace OpenSim.Region.Framework.Scenes public void StoreWindlightProfile(RegionLightShareData wl) { - m_regInfo.WindlightSettings = wl; + RegionInfo.WindlightSettings = wl; SimulationDataService.StoreRegionWindlightSettings(wl); m_eventManager.TriggerOnSaveNewWindlightProfile(); } public void LoadWindlightProfile() { - m_regInfo.WindlightSettings = SimulationDataService.LoadRegionWindlightSettings(RegionInfo.RegionID); + RegionInfo.WindlightSettings = SimulationDataService.LoadRegionWindlightSettings(RegionInfo.RegionID); m_eventManager.TriggerOnSaveNewWindlightProfile(); } @@ -2218,7 +2216,7 @@ namespace OpenSim.Region.Framework.Scenes ForceSceneObjectBackup(so); so.DetachFromBackup(); - SimulationDataService.RemoveObject(so.UUID, m_regInfo.RegionID); + SimulationDataService.RemoveObject(so.UUID, RegionInfo.RegionID); } // We need to keep track of this state in case this group is still queued for further backup. @@ -2553,7 +2551,7 @@ namespace OpenSim.Region.Framework.Scenes // If the user is banned, we won't let any of their objects // enter. Period. // - if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID)) + if (RegionInfo.EstateSettings.IsBanned(sceneObject.OwnerID)) { m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", sceneObject.OwnerID); @@ -3734,9 +3732,9 @@ namespace OpenSim.Region.Framework.Scenes } } - if (m_regInfo.EstateSettings != null) + if (RegionInfo.EstateSettings != null) { - if (m_regInfo.EstateSettings.IsBanned(agent.AgentID)) + if (RegionInfo.EstateSettings.IsBanned(agent.AgentID)) { m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); @@ -3768,7 +3766,7 @@ namespace OpenSim.Region.Framework.Scenes } bool groupAccess = false; - UUID[] estateGroups = m_regInfo.EstateSettings.EstateGroups; + UUID[] estateGroups = RegionInfo.EstateSettings.EstateGroups; if (estateGroups != null) { @@ -3786,8 +3784,8 @@ namespace OpenSim.Region.Framework.Scenes m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!"); } - if (!m_regInfo.EstateSettings.PublicAccess && - !m_regInfo.EstateSettings.HasAccess(agent.AgentID) && + if (!RegionInfo.EstateSettings.PublicAccess && + !RegionInfo.EstateSettings.HasAccess(agent.AgentID) && !groupAccess) { m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate", @@ -3860,7 +3858,7 @@ namespace OpenSim.Region.Framework.Scenes // if (loggingOffUser != null) // { // UUID localRegionSecret = UUID.Zero; -// bool parsedsecret = UUID.TryParse(m_regInfo.regionSecret, out localRegionSecret); +// bool parsedsecret = UUID.TryParse(RegionInfo.regionSecret, out localRegionSecret); // // // Region Secret is used here in case a new sessionid overwrites an old one on the user server. // // Will update the user server in a few revisions to use it. @@ -4079,13 +4077,13 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence sp = GetScenePresence(remoteClient.AgentId); if (sp != null) { - uint regionX = m_regInfo.RegionLocX; - uint regionY = m_regInfo.RegionLocY; + uint regionX = RegionInfo.RegionLocX; + uint regionY = RegionInfo.RegionLocY; Utils.LongToUInts(regionHandle, out regionX, out regionY); - int shiftx = (int) regionX - (int) m_regInfo.RegionLocX * (int)Constants.RegionSize; - int shifty = (int) regionY - (int) m_regInfo.RegionLocY * (int)Constants.RegionSize; + int shiftx = (int) regionX - (int) RegionInfo.RegionLocX * (int)Constants.RegionSize; + int shifty = (int) regionY - (int) RegionInfo.RegionLocY * (int)Constants.RegionSize; position.X += shiftx; position.Y += shifty; @@ -4108,7 +4106,7 @@ namespace OpenSim.Region.Framework.Scenes if (!result) { - regionHandle = m_regInfo.RegionHandle; + regionHandle = RegionInfo.RegionHandle; } else { @@ -4614,7 +4612,7 @@ namespace OpenSim.Region.Framework.Scenes public void DeleteFromStorage(UUID uuid) { - SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID); + SimulationDataService.RemoveObject(uuid, RegionInfo.RegionID); } public int GetHealth() @@ -5039,7 +5037,7 @@ namespace OpenSim.Region.Framework.Scenes IEstateDataService estateDataService = EstateDataService; if (estateDataService != null) { - m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false); + RegionInfo.EstateSettings = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false); TriggerEstateSunUpdate(); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index 9c6b884..f50fbfc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs @@ -51,6 +51,8 @@ namespace OpenSim.Region.Framework.Scenes #endregion #region Fields + + public string Name { get { return RegionInfo.RegionName; } } public IConfigSource Config { @@ -146,6 +148,11 @@ namespace OpenSim.Region.Framework.Scenes #endregion + public SceneBase(RegionInfo regInfo) + { + RegionInfo = regInfo; + } + #region Update Methods /// @@ -209,10 +216,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - public virtual RegionInfo RegionInfo - { - get { return m_regInfo; } - } + public virtual RegionInfo RegionInfo { get; private set; } #region admin stuff -- cgit v1.1 From 0f6b7b6a41ef40e8798638b79c4c62f00556a093 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Jun 2012 00:11:44 +0100 Subject: If a link points to a non-existing item in FetchInventory caps, then don't try to add it to the return data rather than suffering an exception later on --- .../Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs index 515637e..9a6ca86 100644 --- a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs +++ b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs @@ -301,7 +301,8 @@ namespace OpenSim.Capabilities.Handlers InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(link.AssetID)); - itemsToReturn.Insert(0, linkedItem); + if (linkedItem != null) + itemsToReturn.Insert(0, linkedItem); } } } -- cgit v1.1 From 1a7be7b00eaef0140f2dc13f3e14d8150c393b08 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Jun 2012 00:36:50 +0100 Subject: Fix a regression where we stopped removing avatars from collision event reporting on logout, rather than stopping clearing their collision events. This occurred in b18c8c8 (Thu May 17 2012). This was a cause of very occasional race conditions and likely memory leakage as clients came and went from the region. --- OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 54b69a2..f3b0630 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -1270,7 +1270,7 @@ namespace OpenSim.Region.Physics.OdePlugin public override void UnSubscribeEvents() { - CollisionEventsThisFrame.Clear(); + _parent_scene.RemoveCollisionEventReporting(this); // Don't clear collision event reporting here. This is called directly from scene code and so can lead // to a race condition with the simulate loop -- cgit v1.1 From e420f815dc9be9c7fc93cb94c86517d97abbed86 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Jun 2012 00:54:40 +0100 Subject: refactor: rename _collisionEventPrim to m_collisionEventActors and _collisionEventPrimChanges to m_collisionEventActorsChanges to reflect their actual contents. These dictionaries handle all actor types, not just physical prims. --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index c6ecc68..79de99e 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -387,12 +387,12 @@ namespace OpenSim.Region.Physics.OdePlugin /// /// A dictionary of actors that should receive collision events. /// - private readonly Dictionary _collisionEventPrim = new Dictionary(); + private readonly Dictionary m_collisionEventActors = new Dictionary(); /// /// A dictionary of collision event changes that are waiting to be processed. /// - private readonly Dictionary _collisionEventPrimChanges = new Dictionary(); + private readonly Dictionary m_collisionEventActorsChanges = new Dictionary(); /// /// Maps a unique geometry id (a memory location) to a physics actor name. @@ -1908,8 +1908,8 @@ namespace OpenSim.Region.Physics.OdePlugin { // m_log.DebugFormat("[PHYSICS]: Adding {0} {1} to collision event reporting", obj.SOPName, obj.LocalID); - lock (_collisionEventPrimChanges) - _collisionEventPrimChanges[obj.LocalID] = obj; + lock (m_collisionEventActorsChanges) + m_collisionEventActorsChanges[obj.LocalID] = obj; } /// @@ -1920,8 +1920,8 @@ namespace OpenSim.Region.Physics.OdePlugin { // m_log.DebugFormat("[PHYSICS]: Removing {0} {1} from collision event reporting", obj.SOPName, obj.LocalID); - lock (_collisionEventPrimChanges) - _collisionEventPrimChanges[obj.LocalID] = null; + lock (m_collisionEventActorsChanges) + m_collisionEventActorsChanges[obj.LocalID] = null; } #region Add/Remove Entities @@ -2930,17 +2930,17 @@ namespace OpenSim.Region.Physics.OdePlugin // We change _collisionEventPrimChanges to avoid locking _collisionEventPrim itself and causing potential // deadlock if the collision event tries to lock something else later on which is already locked by a // caller that is adding or removing the collision event. - lock (_collisionEventPrimChanges) + lock (m_collisionEventActorsChanges) { - foreach (KeyValuePair kvp in _collisionEventPrimChanges) + foreach (KeyValuePair kvp in m_collisionEventActorsChanges) { if (kvp.Value == null) - _collisionEventPrim.Remove(kvp.Key); + m_collisionEventActors.Remove(kvp.Key); else - _collisionEventPrim[kvp.Key] = kvp.Value; + m_collisionEventActors[kvp.Key] = kvp.Value; } - _collisionEventPrimChanges.Clear(); + m_collisionEventActorsChanges.Clear(); } if (SupportsNINJAJoints) @@ -3092,7 +3092,7 @@ namespace OpenSim.Region.Physics.OdePlugin tempTick = tempTick2; } - foreach (PhysicsActor obj in _collisionEventPrim.Values) + foreach (PhysicsActor obj in m_collisionEventActors.Values) { // m_log.DebugFormat("[PHYSICS]: Assessing {0} {1} for collision events", obj.SOPName, obj.LocalID); -- cgit v1.1 From 0229e90dcc579cee8fe3321a78f6d75b5d70486e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Jun 2012 01:02:35 +0100 Subject: Move update of the final optional ODE total frame stat inside the OdeLock rather than outside to avoid a very occasional race condition with the stat collection thread --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 79de99e..32e81e2 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -3227,10 +3227,10 @@ namespace OpenSim.Region.Physics.OdePlugin } tickCountFrameRun = Util.EnvironmentTickCount(); - } - if (CollectStats) - m_stats[ODETotalFrameMsStatName] += Util.EnvironmentTickCountSubtract(startFrameTick); + if (CollectStats) + m_stats[ODETotalFrameMsStatName] += Util.EnvironmentTickCountSubtract(startFrameTick); + } return fps; } -- cgit v1.1 From 56c776066c71a6ed88d6cd2455f27860d1136530 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 30 Jun 2012 01:05:57 +0100 Subject: Remove code listed for removal in 0.7.3 that handled script restart for incoming attachments from pre-fatpack regions (versions of OpenSimulator more than a year old) --- OpenSim/Region/Framework/Scenes/Scene.cs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index c28979e..0f23cc7 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2494,22 +2494,6 @@ namespace OpenSim.Region.Framework.Scenes newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); newObject.ResumeScripts(); } - else - { - ScenePresence sp; - if (TryGetScenePresence(newObject.OwnerID, out sp)) - { - // If the scene presence is here and already a root - // agent, we came from a ;egacy region. Start the scripts - // here as they used to start. - // TODO: Remove in 0.7.3 - if (!sp.IsChildAgent) - { - newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); - newObject.ResumeScripts(); - } - } - } // Do this as late as possible so that listeners have full access to the incoming object EventManager.TriggerOnIncomingSceneObject(newObject); -- cgit v1.1 From a4551b027bc3f9dfcf79f74210a1156abfb7bb2f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 30 Jun 2012 01:14:49 +0100 Subject: Removing unused handling of incoming create object by userID and itemID only. It appears this was never actually used since attachments were rezzed in other code. This was never available on remote simulator comms, only local. --- .../Simulation/LocalSimulationConnector.cs | 18 -------- .../Simulation/RemoteSimulationConnector.cs | 9 +--- OpenSim/Region/Framework/Scenes/Scene.cs | 22 ---------- .../Server/Handlers/Simulation/ObjectHandlers.cs | 48 ---------------------- OpenSim/Services/Interfaces/ISimulationService.cs | 10 ----- 5 files changed, 1 insertion(+), 106 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 026c6c8..09a3bd6 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs @@ -354,24 +354,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return false; } - public bool CreateObject(GridRegion destination, UUID userID, UUID itemID) - { - if (destination == null) - return false; - - if (m_scenes.ContainsKey(destination.RegionID)) - { -// m_log.DebugFormat( -// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", -// s.RegionInfo.RegionName, destination.RegionHandle); - - return m_scenes[destination.RegionID].IncomingCreateObject(userID, itemID); - } - - return false; - } - - #endregion /* IInterregionComms */ #region Misc diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index f980f68..bd4a23b 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs @@ -300,13 +300,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return false; } - public bool CreateObject(GridRegion destination, UUID userID, UUID itemID) - { - // Not Implemented - return false; - } - #endregion /* IInterregionComms */ - } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 0f23cc7..293c72a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2502,28 +2502,6 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Attachment rezzing - /// - /// Agent Unique ID - /// Object ID - /// False - public virtual bool IncomingCreateObject(UUID userID, UUID itemID) - { - m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID); - - // Commented out since this is as yet unused and is arguably not the appropriate place to do this, as - // attachments are being rezzed elsewhere in AddNewClient() -// ScenePresence sp = GetScenePresence(userID); -// if (sp != null && AttachmentsModule != null) -// { -// uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID); -// AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt); -// } - - return false; - } - - /// /// Adds a Scene Object group to the Scene. /// Verifies that the creator of the object is not banned from the simulator. /// Checks if the item is an Attachment diff --git a/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs b/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs index a4d03ba..dbb1a15 100644 --- a/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs @@ -93,11 +93,6 @@ namespace OpenSim.Server.Handlers.Simulation DoObjectPost(request, responsedata, regionID); return responsedata; } - else if (method.Equals("PUT")) - { - DoObjectPut(request, responsedata, regionID); - return responsedata; - } //else if (method.Equals("DELETE")) //{ // DoObjectDelete(request, responsedata, agentID, action, regionHandle); @@ -219,48 +214,5 @@ namespace OpenSim.Server.Handlers.Simulation { return m_SimulationService.CreateObject(destination, newPosition, sog, false); } - - protected virtual void DoObjectPut(Hashtable request, Hashtable responsedata, UUID regionID) - { - OSDMap args = Utils.GetOSDMap((string)request["body"]); - if (args == null) - { - responsedata["int_response_code"] = 400; - responsedata["str_response_string"] = "false"; - return; - } - - // retrieve the input arguments - int x = 0, y = 0; - UUID uuid = UUID.Zero; - string regionname = string.Empty; - if (args.ContainsKey("destination_x") && args["destination_x"] != null) - Int32.TryParse(args["destination_x"].AsString(), out x); - if (args.ContainsKey("destination_y") && args["destination_y"] != null) - Int32.TryParse(args["destination_y"].AsString(), out y); - if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null) - UUID.TryParse(args["destination_uuid"].AsString(), out uuid); - if (args.ContainsKey("destination_name") && args["destination_name"] != null) - regionname = args["destination_name"].ToString(); - - GridRegion destination = new GridRegion(); - destination.RegionID = uuid; - destination.RegionLocX = x; - destination.RegionLocY = y; - destination.RegionName = regionname; - - UUID userID = UUID.Zero, itemID = UUID.Zero; - if (args.ContainsKey("userid") && args["userid"] != null) - userID = args["userid"].AsUUID(); - if (args.ContainsKey("itemid") && args["itemid"] != null) - itemID = args["itemid"].AsUUID(); - - // This is the meaning of PUT object - bool result = m_SimulationService.CreateObject(destination, userID, itemID); - - responsedata["int_response_code"] = 200; - responsedata["str_response_string"] = result.ToString(); - } - } } diff --git a/OpenSim/Services/Interfaces/ISimulationService.cs b/OpenSim/Services/Interfaces/ISimulationService.cs index 4e52532..b10a85c 100644 --- a/OpenSim/Services/Interfaces/ISimulationService.cs +++ b/OpenSim/Services/Interfaces/ISimulationService.cs @@ -110,16 +110,6 @@ namespace OpenSim.Services.Interfaces /// bool CreateObject(GridRegion destination, Vector3 newPosition, ISceneObject sog, bool isLocalCall); - /// - /// Create an object from the user's inventory in the destination region. - /// This message is used primarily by clients. - /// - /// - /// - /// - /// - bool CreateObject(GridRegion destination, UUID userID, UUID itemID); - #endregion Objects } -- cgit v1.1 From 1926de5a0599051c27c065fb06da3dc536e6784a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 30 Jun 2012 01:25:27 +0100 Subject: Remove some mono compiler warnings --- .../Serialization/External/LandDataSerializer.cs | 2 +- .../External/UserInventoryItemSerializer.cs | 2 +- .../Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs | 5 +++-- OpenSim/Server/Base/HttpServerBase.cs | 4 +--- .../Services/HypergridService/GatekeeperService.cs | 2 -- .../Services/HypergridService/HGFriendsService.cs | 26 +++++++++++----------- .../HypergridService/HGSuitcaseInventoryService.cs | 4 ++-- 7 files changed, 21 insertions(+), 24 deletions(-) diff --git a/OpenSim/Framework/Serialization/External/LandDataSerializer.cs b/OpenSim/Framework/Serialization/External/LandDataSerializer.cs index a12877a..e8d82d3 100644 --- a/OpenSim/Framework/Serialization/External/LandDataSerializer.cs +++ b/OpenSim/Framework/Serialization/External/LandDataSerializer.cs @@ -42,7 +42,7 @@ namespace OpenSim.Framework.Serialization.External /// public class LandDataSerializer { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected static UTF8Encoding m_utf8Encoding = new UTF8Encoding(); diff --git a/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs b/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs index 57da7ca..88f9581 100644 --- a/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs +++ b/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs @@ -44,7 +44,7 @@ namespace OpenSim.Framework.Serialization.External /// public class UserInventoryItemSerializer { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static Dictionary> m_InventoryItemXmlProcessors = new Dictionary>(); diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs index b89eeed..47d7df3 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs @@ -37,7 +37,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin public class BasicPhysicsPrim : PhysicsActor { private Vector3 _size; - private PrimitiveBaseShape _shape; +// private PrimitiveBaseShape _shape; public BasicPhysicsPrim( string name, uint localId, Vector3 position, Vector3 size, Quaternion orientation, PrimitiveBaseShape shape) @@ -136,7 +136,8 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin public override PrimitiveBaseShape Shape { - set { _shape = value; } +// set { _shape = value; } + set {} } public override float Mass diff --git a/OpenSim/Server/Base/HttpServerBase.cs b/OpenSim/Server/Base/HttpServerBase.cs index 7ba0ca8..29b1c00 100644 --- a/OpenSim/Server/Base/HttpServerBase.cs +++ b/OpenSim/Server/Base/HttpServerBase.cs @@ -40,9 +40,7 @@ namespace OpenSim.Server.Base { public class HttpServerBase : ServicesServerBase { - // Logger - // - private static readonly ILog m_Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private uint m_consolePort; diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs index 149a0ab..47d22b9 100644 --- a/OpenSim/Services/HypergridService/GatekeeperService.cs +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs @@ -370,8 +370,6 @@ namespace OpenSim.Services.HypergridService return false; } } - - return false; } // Check that the service token was generated for *this* grid. diff --git a/OpenSim/Services/HypergridService/HGFriendsService.cs b/OpenSim/Services/HypergridService/HGFriendsService.cs index 39524ab..98423d7 100644 --- a/OpenSim/Services/HypergridService/HGFriendsService.cs +++ b/OpenSim/Services/HypergridService/HGFriendsService.cs @@ -276,19 +276,19 @@ namespace OpenSim.Services.HypergridService } } - // Lastly, let's notify the rest who may be online somewhere else - foreach (string user in usersToBeNotified) - { - UUID id = new UUID(user); - //m_UserAgentService.LocateUser(id); - //etc... - //if (m_TravelingAgents.ContainsKey(id) && m_TravelingAgents[id].GridExternalName != m_GridName) - //{ - // string url = m_TravelingAgents[id].GridExternalName; - // // forward - //} - //m_log.WarnFormat("[HGFRIENDS SERVICE]: User {0} is visiting another grid. HG Status notifications still not implemented.", user); - } +// // Lastly, let's notify the rest who may be online somewhere else +// foreach (string user in usersToBeNotified) +// { +// UUID id = new UUID(user); +// //m_UserAgentService.LocateUser(id); +// //etc... +// //if (m_TravelingAgents.ContainsKey(id) && m_TravelingAgents[id].GridExternalName != m_GridName) +// //{ +// // string url = m_TravelingAgents[id].GridExternalName; +// // // forward +// //} +// //m_log.WarnFormat("[HGFRIENDS SERVICE]: User {0} is visiting another grid. HG Status notifications still not implemented.", user); +// } // and finally, let's send the online friends if (online) diff --git a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs index 53fbea6..6e4b68c 100644 --- a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs +++ b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs @@ -57,7 +57,7 @@ namespace OpenSim.Services.HypergridService private string m_HomeURL; private IUserAccountService m_UserAccountService; - private UserAccountCache m_Cache; +// private UserAccountCache m_Cache; private ExpiringCache> m_SuitcaseTrees = new ExpiringCache>(); @@ -92,7 +92,7 @@ namespace OpenSim.Services.HypergridService // Preferred m_HomeURL = invConfig.GetString("HomeURI", m_HomeURL); - m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService); +// m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService); } m_log.Debug("[HG SUITCASE INVENTORY SERVICE]: Starting..."); -- cgit v1.1 From d32cf2157670889c571a34f1a4473d672e29627d Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 1 Jul 2012 18:30:59 +0100 Subject: Add preservation of running state of scripts when drag-copying. --- OpenSim/Framework/TaskInventoryItem.cs | 12 ++++++++ .../Region/Framework/Interfaces/IScriptModule.cs | 4 ++- .../Framework/Scenes/SceneObjectPartInventory.cs | 36 +++++++++++++++++++++- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 12 ++++++++ 4 files changed, 62 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/TaskInventoryItem.cs b/OpenSim/Framework/TaskInventoryItem.cs index 362d365..3b40381 100644 --- a/OpenSim/Framework/TaskInventoryItem.cs +++ b/OpenSim/Framework/TaskInventoryItem.cs @@ -73,6 +73,9 @@ namespace OpenSim.Framework private bool _ownerChanged = false; + // This used ONLY during copy. It can't be relied on at other times! + private bool _scriptRunning = true; + public UUID AssetID { get { return _assetID; @@ -350,6 +353,15 @@ namespace OpenSim.Framework } } + public bool ScriptRunning { + get { + return _scriptRunning; + } + set { + _scriptRunning = value; + } + } + // See ICloneable #region ICloneable Members diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs index cbaf241..42dbedc 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs @@ -69,6 +69,8 @@ namespace OpenSim.Region.Framework.Interfaces ArrayList GetScriptErrors(UUID itemID); + bool HasScript(UUID itemID, out bool running); + /// /// Returns true if a script is running. /// @@ -101,4 +103,4 @@ namespace OpenSim.Region.Framework.Interfaces /// Dictionary GetObjectScriptsExecutionTimes(); } -} \ No newline at end of file +} diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index c223474..6427014 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -89,6 +89,7 @@ namespace OpenSim.Region.Framework.Scenes { m_items = value; m_inventorySerial++; + QueryScriptStates(); } } @@ -217,6 +218,36 @@ namespace OpenSim.Region.Framework.Scenes } } + private void QueryScriptStates() + { + if (m_part == null || m_part.ParentGroup == null) + return; + + IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces(); + if (engines == null) // No engine at all + return; + + lock (Items) + { + foreach (TaskInventoryItem item in Items.Values) + { + if (item.InvType == (int)InventoryType.LSL) + { + foreach (IScriptModule e in engines) + { + bool running; + + if (e.HasScript(item.ItemID, out running)) + { + item.ScriptRunning = running; + break; + } + } + } + } + } + } + public int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) { int scriptsValidForStarting = 0; @@ -321,6 +352,9 @@ namespace OpenSim.Region.Framework.Scenes string script = Utils.BytesToString(asset.Data); m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); + if (!item.ScriptRunning) + m_part.ParentGroup.Scene.EventManager.TriggerStopScript( + m_part.LocalId, item.ItemID); m_part.ParentGroup.AddActiveScriptCount(1); m_part.ScheduleFullUpdate(); @@ -1251,4 +1285,4 @@ namespace OpenSim.Region.Framework.Scenes } } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 35fac4e..7f3bd76 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -2081,5 +2081,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine // else // m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); } + + public bool HasScript(UUID itemID, out bool running) + { + running = true; + + IScriptInstance instance = GetInstance(itemID); + if (instance == null) + return false; + + running = instance.Running; + return true; + } } } -- cgit v1.1 From 3399596e0e2df2d0e260ba88ce8a0166de8cbff2 Mon Sep 17 00:00:00 2001 From: Michelle Argus Date: Mon, 2 Jul 2012 19:12:10 +0200 Subject: Adds a list of viewers that are allowed or banned from the region. Signed-off-by: Melanie --- OpenSim/Region/Framework/Scenes/Scene.cs | 65 ++++++++++++++++++++++++++++++++ bin/OpenSim.ini.example | 17 +++++++++ 2 files changed, 82 insertions(+) mode change 100755 => 100644 bin/OpenSim.ini.example diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 293c72a..2493df1 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -120,6 +120,9 @@ namespace OpenSim.Region.Framework.Scenes { get { return m_defaultDrawDistance; } } + + private List m_AllowedViewers = new List(); + private List m_BanedViewers = new List(); // TODO: need to figure out how allow client agents but deny // root agents when ACL denies access to root agent @@ -779,6 +782,24 @@ namespace OpenSim.Region.Framework.Scenes } } + string grant = startupConfig.GetString("AllowedViewerList", String.Empty); + if (grant.Length > 0) + { + foreach (string viewer in grant.Split(',')) + { + m_AllowedViewers.Add(viewer.Trim().ToLower()); + } + } + + grant = startupConfig.GetString("BannedViewerList", String.Empty); + if (grant.Length > 0) + { + foreach (string viewer in grant.Split(',')) + { + m_BanedViewers.Add(viewer.Trim().ToLower()); + } + } + MinFrameTime = startupConfig.GetFloat( "MinFrameTime", MinFrameTime); m_update_backup = startupConfig.GetInt( "UpdateStorageEveryNFrames", m_update_backup); m_update_coarse_locations = startupConfig.GetInt( "UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations); @@ -3417,6 +3438,50 @@ namespace OpenSim.Region.Framework.Scenes return false; } + //Check if the viewer is banned or in the viewer access list + //We check if the substring is listed for higher flexebility + bool ViewerDenied = true; + + //Check if the specific viewer is listed in the allowed viewer list + if (m_AllowedViewers.Count > 0) + { + foreach (string viewer in m_AllowedViewers) + { + if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower()) + { + ViewerDenied = false; + break; + } + } + } + else + { + ViewerDenied = false; + } + + //Check if the viewer is in the banned list + if (m_BanedViewers.Count > 0) + { + foreach (string viewer in m_BanedViewers) + { + if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower()) + { + ViewerDenied = true; + break; + } + } + } + + if (ViewerDenied) + { + m_log.DebugFormat( + "[SCENE]: Access denied for {0} {1} using {2}", + agent.firstname, agent.lastname, agent.Viewer); + reason = "Access denied, your viewer is banned by the region owner"; + return false; + } + + ScenePresence sp = GetScenePresence(agent.AgentID); if (sp != null && !sp.IsChildAgent) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example old mode 100755 new mode 100644 index aa29c07..741877e --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -254,6 +254,23 @@ ;; default is false ; TelehubAllowLandmark = false + ;# Comma separated list of viewers which may gain access to the regions. + ;; One can use a Substring of the viewer name to enable only certain subversions + ;; Example: Agent uses the viewer "Imprudence 1.3.2.0" + ;; - "Imprudence" has access + ;; - "Imprudence 1.3" has access + ;; - "Imprudence 1.3.1" has no access + ;; AllowedViewerList = + + ;# Comma separated list of viewers which may not gain access to the regions. + ;; One can use a Substring of the viewer name to disable only certain subversions + ;; Example: Agent uses the viewer "Imprudence 1.3.2.0" + ;; - "Imprudence" has no access + ;; - "Imprudence 1.3" has no access + ;; - "Imprudence 1.3.1" has access + ; BannedViewerList = + + [Estates] ; If these values are commented out then the user will be asked for estate details when required (this is the normal case). ; If these values are uncommented then they will be used to create a default estate as necessary. -- cgit v1.1 From 3c9b9a848f6c9723a3cc46f0de8ad802ece7e2a7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Jul 2012 22:58:58 +0100 Subject: Fix issue in database tests where sogs being stored are not in a scene. This puts an extra m_part.ParentGroup.Scene == null check at the top of SceneObjectPartInventory.QueryScriptStates() --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 6427014..866311a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -220,7 +220,7 @@ namespace OpenSim.Region.Framework.Scenes private void QueryScriptStates() { - if (m_part == null || m_part.ParentGroup == null) + if (m_part == null || m_part.ParentGroup == null || m_part.ParentGroup.Scene == null) return; IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces(); -- cgit v1.1 From 8183c2926d563aa15cfc53f624353e1779061721 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Jul 2012 23:19:11 +0100 Subject: minor: Add some method doc to HasGroupChanged and Schedule GroupForFull/PartUpdate() to indicate when region modules need to invoke them --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 23 ++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 1e900a0..96cc376 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -108,6 +108,15 @@ namespace OpenSim.Region.Framework.Scenes private long timeFirstChanged; private long timeLastChanged; + /// + /// This indicates whether the object has changed such that it needs to be repersisted to permenant storage + /// (the database). + /// + /// + /// Ultimately, this should be managed such that region modules can change it at the end of a set of operations + /// so that either all changes are preserved or none at all. However, currently, a large amount of internal + /// code will set this anyway when some object properties are changed. + /// public bool HasGroupChanged { set @@ -1817,8 +1826,13 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Schedule a full update for this scene object + /// Schedule a full update for this scene object to all interested viewers. /// + /// + /// Ultimately, this should be managed such that region modules can invoke it at the end of a set of operations + /// so that either all changes are sent at once. However, currently, a large amount of internal + /// code will set this anyway when some object properties are changed. + /// public void ScheduleGroupForFullUpdate() { // if (IsAttachment) @@ -1837,8 +1851,13 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Schedule a terse update for this scene object + /// Schedule a terse update for this scene object to all interested viewers. /// + /// + /// Ultimately, this should be managed such that region modules can invoke it at the end of a set of operations + /// so that either all changes are sent at once. However, currently, a large amount of internal + /// code will set this anyway when some object properties are changed. + /// public void ScheduleGroupForTerseUpdate() { // m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID); -- cgit v1.1 From f7b48025777a653589b7860e94aaa3230497ffa3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Jul 2012 23:26:02 +0100 Subject: Correct spelling mistake m_BanedViewers to m_BannedViewers --- OpenSim/Region/Framework/Scenes/Scene.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2493df1..36d39ea 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -122,7 +122,7 @@ namespace OpenSim.Region.Framework.Scenes } private List m_AllowedViewers = new List(); - private List m_BanedViewers = new List(); + private List m_BannedViewers = new List(); // TODO: need to figure out how allow client agents but deny // root agents when ACL denies access to root agent @@ -796,7 +796,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (string viewer in grant.Split(',')) { - m_BanedViewers.Add(viewer.Trim().ToLower()); + m_BannedViewers.Add(viewer.Trim().ToLower()); } } @@ -3460,9 +3460,9 @@ namespace OpenSim.Region.Framework.Scenes } //Check if the viewer is in the banned list - if (m_BanedViewers.Count > 0) + if (m_BannedViewers.Count > 0) { - foreach (string viewer in m_BanedViewers) + foreach (string viewer in m_BannedViewers) { if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower()) { -- cgit v1.1 From 5691a8b860b22939e2b608d6d8400b5260b25cf3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 00:15:03 +0100 Subject: refactor: rename Watchdog.WATCHDOG_TIMEOUT_MS to DEFAULT_WATCHDOG_TIMEOUT_MS to reflect what it actually is --- OpenSim/Framework/Watchdog.cs | 6 +++--- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs index 7552cd1..2b3a719 100644 --- a/OpenSim/Framework/Watchdog.cs +++ b/OpenSim/Framework/Watchdog.cs @@ -41,8 +41,8 @@ namespace OpenSim.Framework /// Timer interval in milliseconds for the watchdog timer const double WATCHDOG_INTERVAL_MS = 2500.0d; - /// Maximum timeout in milliseconds before a thread is considered dead - public const int WATCHDOG_TIMEOUT_MS = 5000; + /// Default timeout in milliseconds before a thread is considered dead + public const int DEFAULT_WATCHDOG_TIMEOUT_MS = 5000; [System.Diagnostics.DebuggerDisplay("{Thread.Name}")] public class ThreadWatchdogInfo @@ -122,7 +122,7 @@ namespace OpenSim.Framework public static Thread StartThread( ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout) { - return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, WATCHDOG_TIMEOUT_MS); + return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS); } /// diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 44c65e0..468d524 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -270,7 +270,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP false, true, GetWatchdogIncomingAlarmData, - Watchdog.WATCHDOG_TIMEOUT_MS); + Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); Watchdog.StartThread( OutgoingPacketHandler, @@ -279,7 +279,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP false, true, GetWatchdogOutgoingAlarmData, - Watchdog.WATCHDOG_TIMEOUT_MS); + Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); m_elapsedMSSinceLastStatReport = Environment.TickCount; } -- cgit v1.1 From 58b13d51a7eddb442e38e6dc6790a9e7cf68bad7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 20:57:48 +0100 Subject: refactor: make llGiveInventory() use existing GetInventoryItem() method rather than iterate through TaskInventory itself. --- .../Shared/Api/Implementation/LSL_Api.cs | 35 +++++++--------------- 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 12eb098..8a3efa7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3860,11 +3860,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llGiveInventory(string destination, string inventory) { m_host.AddScriptLPS(1); - bool found = false; + UUID destId = UUID.Zero; - UUID objId = UUID.Zero; - int assetType = 0; - string objName = String.Empty; if (!UUID.TryParse(destination, out destId)) { @@ -3872,28 +3869,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; } - // move the first object found with this inventory name - lock (m_host.TaskInventory) - { - foreach (KeyValuePair inv in m_host.TaskInventory) - { - if (inv.Value.Name == inventory) - { - found = true; - objId = inv.Key; - assetType = inv.Value.Type; - objName = inv.Value.Name; - break; - } - } - } + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory); - if (!found) + if (item == null) { llSay(0, String.Format("Could not find object '{0}'", inventory)); throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); } + UUID objId = item.ItemID; + // check if destination is an object if (World.GetSceneObjectPart(destId) != null) { @@ -3924,21 +3909,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; byte[] bucket = new byte[17]; - bucket[0] = (byte)assetType; + bucket[0] = (byte)item.Type; byte[] objBytes = agentItem.ID.GetBytes(); Array.Copy(objBytes, 0, bucket, 1, 16); GridInstantMessage msg = new GridInstantMessage(World, - m_host.UUID, m_host.Name+", an object owned by "+ - resolveName(m_host.OwnerID)+",", destId, + m_host.UUID, m_host.Name + ", an object owned by " + + resolveName(m_host.OwnerID) + ",", destId, (byte)InstantMessageDialog.TaskInventoryOffered, - false, objName+"\n"+m_host.Name+" is located at "+ + false, item.Name + "\n" + m_host.Name + " is located at " + World.RegionInfo.RegionName+" "+ m_host.AbsolutePosition.ToString(), agentItem.ID, true, m_host.AbsolutePosition, bucket); + if (m_TransferModule != null) m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); + ScriptSleep(3000); } } -- cgit v1.1 From ae64d089c669a9f953fc0992ca4de3a700395def Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 21:05:51 +0100 Subject: refactor: In llRemoveInventory() use existing GetInventoryItem() method rather than have it iterate through TaskInventory itself. --- .../Shared/Api/Implementation/LSL_Api.cs | 23 +++++++++------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8a3efa7..b52ebac 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3934,20 +3934,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) - { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) - { - if (item.Name == name) - { - if (item.ItemID == m_item.ItemID) - throw new ScriptDeleteException(); - else - m_host.Inventory.RemoveInventoryItem(item.ItemID); - return; - } - } - } + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); + + if (item == null) + return; + + if (item.ItemID == m_item.ItemID) + throw new ScriptDeleteException(); + else + m_host.Inventory.RemoveInventoryItem(item.ItemID); } public void llSetText(string text, LSL_Vector color, double alpha) -- cgit v1.1 From 3717812ce090cae850449ed82463545c079df68d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 21:15:00 +0100 Subject: refactor: In llCollisionSound() use existing GetInventoryItem() method rather than have it iterate through TaskInventory itself. --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b52ebac..ff4b690 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4290,18 +4290,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID soundId = UUID.Zero; if (!UUID.TryParse(impact_sound, out soundId)) { - lock (m_host.TaskInventory) - { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) - { - if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) - { - soundId = item.AssetID; - break; - } - } - } + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(impact_sound); + + if (item != null && item.Type == (int)AssetType.Sound) + soundId = item.AssetID; } + m_host.CollisionSound = soundId; m_host.CollisionSoundVolume = (float)impact_volume; } -- cgit v1.1 From 3769739ca75bd28a126034a74848012164db31b6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 21:19:16 +0100 Subject: In llRequestInventoryData() use GetInventoryItems() rather than cloning TaskInventory directory GetInventoryItems() returns a new list and so is equivalent, and creates this list under lock whereas Clone() is not thread-safe --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 5 ++--- 1 file changed, 2 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 ff4b690..66d99a2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4084,9 +4084,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); - - foreach (TaskInventoryItem item in itemDictionary.Values) + foreach (TaskInventoryItem item in m_host.Inventory.GetInventoryItems()) { if (item.Type == 3 && item.Name == name) { @@ -4118,6 +4116,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return tid.ToString(); } } + ScriptSleep(1000); return String.Empty; } -- cgit v1.1 From 4b2b14dad12d5a8f64609e7eeb3da62a5ca2f8b1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 21:22:43 +0100 Subject: In llMessageLinked() use GetInventoryItems() rather than cloning TaskInventory directory GetInventoryItems() returns a new list and so is equivalent, and creates this list under lock whereas Clone() is not thread-safe --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 66d99a2..f57f752 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4116,7 +4116,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return tid.ToString(); } } - + ScriptSleep(1000); return String.Empty; } @@ -4333,9 +4333,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID partItemID; foreach (SceneObjectPart part in parts) { - TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); - - foreach (TaskInventoryItem item in itemsDictionary.Values) + foreach (TaskInventoryItem item in part.Inventory.GetInventoryItems()) { if (item.Type == ScriptBaseClass.INVENTORY_SCRIPT) { -- cgit v1.1 From 0e3fce9b5c26ee21dee64f8667e7b47b71dbdb3a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 21:25:58 +0100 Subject: refactor: In llGetInventoryKey() use existing GetInventoryItem() --- .../Shared/Api/Implementation/LSL_Api.cs | 24 ++++++++-------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index f57f752..b0602fc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4703,22 +4703,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); + + if (item == null) + return UUID.Zero.ToString(); + + if ((item.CurrentPermissions + & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) + == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) { - foreach (KeyValuePair inv in m_host.TaskInventory) - { - if (inv.Value.Name == name) - { - if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) - { - return inv.Value.AssetID.ToString(); - } - else - { - return UUID.Zero.ToString(); - } - } - } + return item.AssetID.ToString(); } return UUID.Zero.ToString(); -- cgit v1.1 From dff7cae2ee78942d97f8481b16e0f682dfcce038 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 21:33:35 +0100 Subject: refactor: replace use of LSL_Api.GetTaskInventoryItem() with existing GetInventoryItem() --- .../Shared/Api/Implementation/LSL_Api.cs | 33 ++++++++-------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b0602fc..813fffd 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6296,20 +6296,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - protected UUID GetTaskInventoryItem(string name) - { - lock (m_host.TaskInventory) - { - foreach (KeyValuePair inv in m_host.TaskInventory) - { - if (inv.Value.Name == name) - return inv.Key; - } - } - - return UUID.Zero; - } - public void llGiveInventoryList(string destination, string category, LSL_List inventory) { m_host.AddScriptLPS(1); @@ -6322,16 +6308,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api foreach (Object item in inventory.Data) { + string rawItemString = item.ToString(); + UUID itemID; - if (UUID.TryParse(item.ToString(), out itemID)) + if (UUID.TryParse(rawItemString, out itemID)) { itemList.Add(itemID); } else { - itemID = GetTaskInventoryItem(item.ToString()); - if (itemID != UUID.Zero) - itemList.Add(itemID); + TaskInventoryItem taskItem = m_host.Inventory.GetInventoryItem(rawItemString); + + if (taskItem != null) + itemList.Add(taskItem.ItemID); } } @@ -6349,11 +6338,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api Array.Copy(objBytes, 0, bucket, 1, 16); GridInstantMessage msg = new GridInstantMessage(World, - m_host.UUID, m_host.Name+", an object owned by "+ - resolveName(m_host.OwnerID)+",", destID, + m_host.UUID, m_host.Name + ", an object owned by " + + resolveName(m_host.OwnerID) + ",", destID, (byte)InstantMessageDialog.InventoryOffered, - false, category+"\n"+m_host.Name+" is located at "+ - World.RegionInfo.RegionName+" "+ + false, category + "\n" + m_host.Name + " is located at " + + World.RegionInfo.RegionName + " " + m_host.AbsolutePosition.ToString(), folderID, true, m_host.AbsolutePosition, bucket); -- cgit v1.1 From 857494f6bdef5aef8cfcbee84ca668c2371bfdf0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 21:36:44 +0100 Subject: refactor: In llRemoteLoadScriptPin() use existing GetInventoryItem() --- .../Shared/Api/Implementation/LSL_Api.cs | 25 +++++----------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 813fffd..a1620e7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6644,9 +6644,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llRemoteLoadScriptPin(string target, string name, int pin, int running, int start_param) { m_host.AddScriptLPS(1); - bool found = false; + UUID destId = UUID.Zero; - UUID srcId = UUID.Zero; if (!UUID.TryParse(target, out destId)) { @@ -6661,31 +6660,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } // copy the first script found with this inventory name - lock (m_host.TaskInventory) - { - foreach (KeyValuePair inv in m_host.TaskInventory) - { - if (inv.Value.Name == name) - { - // make sure the object is a script - if (10 == inv.Value.Type) - { - found = true; - srcId = inv.Key; - break; - } - } - } - } + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); - if (!found) + // make sure the object is a script + if (item == null || item.Type != 10) { llSay(0, "Could not find script " + name); return; } // the rest of the permission checks are done in RezScript, so check the pin there as well - World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param); + World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); // this will cause the delay even if the script pin or permissions were wrong - seems ok ScriptSleep(3000); -- cgit v1.1 From f9fa34408dd178eb202e0cc1336da67cc0a494f0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 21:42:04 +0100 Subject: refactor: in llGetInventoryPermMask use existing GetInventoryItem() --- .../Shared/Api/Implementation/LSL_Api.cs | 42 ++++++++++------------ 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a1620e7..a173d64 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6644,7 +6644,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llRemoteLoadScriptPin(string target, string name, int pin, int running, int start_param) { m_host.AddScriptLPS(1); - + UUID destId = UUID.Zero; if (!UUID.TryParse(target, out destId)) @@ -9032,31 +9032,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - public LSL_Integer llGetInventoryPermMask(string item, int mask) + public LSL_Integer llGetInventoryPermMask(string itemName, int mask) { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) - { - foreach (KeyValuePair inv in m_host.TaskInventory) - { - if (inv.Value.Name == item) - { - switch (mask) - { - case 0: - return (int)inv.Value.BasePermissions; - case 1: - return (int)inv.Value.CurrentPermissions; - case 2: - return (int)inv.Value.GroupPermissions; - case 3: - return (int)inv.Value.EveryonePermissions; - case 4: - return (int)inv.Value.NextPermissions; - } - } - } + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); + + if (item == null) + return -1; + + switch (mask) + { + case 0: + return (int)item.BasePermissions; + case 1: + return (int)item.CurrentPermissions; + case 2: + return (int)item.GroupPermissions; + case 3: + return (int)item.EveryonePermissions; + case 4: + return (int)item.NextPermissions; } return -1; -- cgit v1.1 From d933bdbd59da50e2c335b65870416ac8e5035d3a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 21:47:20 +0100 Subject: refactor: In llGetInventoryPermMask() use existing GetInventoryItem() --- .../Shared/Api/Implementation/LSL_Api.cs | 45 ++++++++++------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a173d64..fce09bf 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9058,38 +9058,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return -1; } - public void llSetInventoryPermMask(string item, int mask, int value) + public void llSetInventoryPermMask(string itemName, int mask, int value) { m_host.AddScriptLPS(1); + if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false)) { if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) { - lock (m_host.TaskInventory) + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); + + if (item != null) { - foreach (KeyValuePair inv in m_host.TaskInventory) + switch (mask) { - if (inv.Value.Name == item) - { - switch (mask) - { - case 0: - inv.Value.BasePermissions = (uint)value; - break; - case 1: - inv.Value.CurrentPermissions = (uint)value; - break; - case 2: - inv.Value.GroupPermissions = (uint)value; - break; - case 3: - inv.Value.EveryonePermissions = (uint)value; - break; - case 4: - inv.Value.NextPermissions = (uint)value; - break; - } - } + case 0: + item.BasePermissions = (uint)value; + break; + case 1: + item.CurrentPermissions = (uint)value; + break; + case 2: + item.GroupPermissions = (uint)value; + break; + case 3: + item.EveryonePermissions = (uint)value; + break; + case 4: + item.NextPermissions = (uint)value; + break; } } } -- cgit v1.1 From f2b0377c28623ee915387fef37c88ab3b7694ba8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 21:49:21 +0100 Subject: refactor: In llGetInventoryCreator() use existing GetInventoryItem() --- .../Shared/Api/Implementation/LSL_Api.cs | 20 ++++++++------------ 1 file changed, 8 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 fce09bf..338ae88 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9093,24 +9093,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - public LSL_String llGetInventoryCreator(string item) + public LSL_String llGetInventoryCreator(string itemName) { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); + + if (item == null) { - foreach (KeyValuePair inv in m_host.TaskInventory) - { - if (inv.Value.Name == item) - { - return inv.Value.CreatorID.ToString(); - } - } - } + llSay(0, "No item name '" + item + "'"); - llSay(0, "No item name '" + item + "'"); + return String.Empty; + } - return String.Empty; + return item.CreatorID.ToString(); } public void llOwnerSay(string msg) -- cgit v1.1 From 9fac7fd932aa929e350fb4795f5036f7dd0cf78f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 21:50:52 +0100 Subject: refactor: In llGetInventoryType() use existing GetInventoryItem() --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 338ae88..a8a2a50 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9656,18 +9656,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) - { - foreach (KeyValuePair inv in m_host.TaskInventory) - { - if (inv.Value.Name == name) - { - return inv.Value.Type; - } - } - } + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); - return -1; + if (item == null) + return -1; + + return item.Type; } public void llSetPayPrice(int price, LSL_List quick_pay_buttons) -- cgit v1.1 From eacba4fc0b1e3a34f8bae140c402eacb68ecbb94 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 21:54:30 +0100 Subject: refactor: use existing GetInventoryItem() in GetScriptByName(), itself renamed from ScriptByName() --- .../Shared/Api/Implementation/LSL_Api.cs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a8a2a50..38f146f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -192,7 +192,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); - if ((item = ScriptByName(name)) != UUID.Zero) + if ((item = GetScriptByName(name)) != UUID.Zero) m_ScriptEngine.ResetScript(item); else ShoutError("llResetOtherScript: script "+name+" not found"); @@ -204,7 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); - if ((item = ScriptByName(name)) != UUID.Zero) + if ((item = GetScriptByName(name)) != UUID.Zero) { return m_ScriptEngine.GetScriptState(item) ?1:0; } @@ -226,7 +226,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // These functions are supposed to be robust, // so get the state one step at a time. - if ((item = ScriptByName(name)) != UUID.Zero) + if ((item = GetScriptByName(name)) != UUID.Zero) { m_ScriptEngine.SetScriptState(item, run == 0 ? false : true); } @@ -10455,18 +10455,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return new LSL_List(); } - internal UUID ScriptByName(string name) + internal UUID GetScriptByName(string name) { - lock (m_host.TaskInventory) - { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) - { - if (item.Type == 10 && item.Name == name) - return item.ItemID; - } - } + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); + + if (item == null || item.Type != 10) + return UUID.Zero; - return UUID.Zero; + return item.ItemID; } internal void ShoutError(string msg) -- cgit v1.1 From 1816ecb747708fea73eec08d3e51a8a2b8c7bd06 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 21:57:57 +0100 Subject: refactor: In llGetNumberOfNotecardLines() use existing GetInventoryItem() rather than inspecting a clone of the TaskInventory dictionary that was not cloned thread-safe --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 38f146f..2b8c4c1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10502,20 +10502,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); - UUID assetID = UUID.Zero; if (!UUID.TryParse(name, out assetID)) { - foreach (TaskInventoryItem item in itemsDictionary.Values) - { - if (item.Type == 7 && item.Name == name) - { - assetID = item.AssetID; - break; - } - } + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); + + if (item != null && item.Type == 7) + assetID = item.AssetID; } if (assetID == UUID.Zero) -- cgit v1.1 From 2f998fce1f51e9991852144c940281fedffbbbca Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 22:00:39 +0100 Subject: refactor: In llGetNotecardLine() use existing GetInventoryItem() rather than inspecting a clone of the TaskInventory dictionary that was not cloned thread-safe --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 2b8c4c1..cf65abb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10558,20 +10558,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); - UUID assetID = UUID.Zero; if (!UUID.TryParse(name, out assetID)) { - foreach (TaskInventoryItem item in itemsDictionary.Values) - { - if (item.Type == 7 && item.Name == name) - { - assetID = item.AssetID; - break; - } - } + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); + + if (item != null && item.Type == 7) + assetID = item.AssetID; } if (assetID == UUID.Zero) -- cgit v1.1 From 7b327848d0a74296e0180bb8d27544e6c5570215 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jul 2012 22:21:47 +0100 Subject: Use GetInventoryItem() in llRezAtRoot rather than iterating through a cloned dictionary --- .../Shared/Api/Implementation/LSL_Api.cs | 76 ++++++++++------------ 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index cf65abb..0a25454 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2738,67 +2738,63 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - Util.FireAndForget(delegate (object x) + Util.FireAndForget(x => { if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s)) return; + float dist = (float)llVecDist(llGetPos(), pos); if (dist > m_ScriptDistanceFactor * 10.0f) return; - //Clone is thread-safe - TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory); - foreach (KeyValuePair inv in partInventory) + if (item == null) { - if (inv.Value.Name == inventory) - { - // make sure we're an object. - if (inv.Value.InvType != (int)InventoryType.Object) - { - llSay(0, "Unable to create requested object. Object is missing from database."); - return; - } + llSay(0, "Could not find object " + inventory); + return; + } - Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z); - Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z); + if (item.InvType != (int)InventoryType.Object) + { + llSay(0, "Unable to create requested object. Object is missing from database."); + return; + } - // need the magnitude later - // float velmag = (float)Util.GetMagnitude(llvel); + Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z); + Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z); - SceneObjectGroup new_group = World.RezObject(m_host, inv.Value, llpos, Rot2Quaternion(rot), llvel, param); + // need the magnitude later + // float velmag = (float)Util.GetMagnitude(llvel); - // If either of these are null, then there was an unknown error. - if (new_group == null) - continue; + SceneObjectGroup new_group = World.RezObject(m_host, item, llpos, Rot2Quaternion(rot), llvel, param); - // objects rezzed with this method are die_at_edge by default. - new_group.RootPart.SetDieAtEdge(true); + // If either of these are null, then there was an unknown error. + if (new_group == null) + return; - new_group.ResumeScripts(); + // objects rezzed with this method are die_at_edge by default. + new_group.RootPart.SetDieAtEdge(true); - m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams( - "object_rez", new Object[] { - new LSL_String( - new_group.RootPart.UUID.ToString()) }, - new DetectParams[0])); + new_group.ResumeScripts(); - float groupmass = new_group.GetMass(); + m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams( + "object_rez", new Object[] { + new LSL_String( + new_group.RootPart.UUID.ToString()) }, + new DetectParams[0])); - PhysicsActor pa = new_group.RootPart.PhysActor; + float groupmass = new_group.GetMass(); - if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) - { - //Recoil. - llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); - } - // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) - return; - } - } + PhysicsActor pa = new_group.RootPart.PhysActor; - llSay(0, "Could not find object " + inventory); + if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) + { + //Recoil. + llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); + } + // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) }); //ScriptSleep((int)((groupmass * velmag) / 10)); -- cgit v1.1 From 951b45b80fd504b4874b9ec3e0fbff49a25cb46f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 5 Jul 2012 00:05:06 +0100 Subject: Add OSSL function osForceAttachToAvatarFromInventory() This works like osForceAttachToAvatar() but allows an object to be directly specified from the script object's inventory rather than forcing it to be rezzed in the scene first. Still only attaches objects to the owner of the script. This allows one to bypass the complicated co-ordination of first rezzing objects in the scene before attaching them. Threat level high. --- .../Attachments/Tests/AttachmentsModuleTests.cs | 2 +- .../World/Media/Moap/Tests/MoapTests.cs | 4 +- .../Scenes/Tests/SceneObjectBasicTests.cs | 22 +-- .../Scenes/Tests/SceneObjectLinkingTests.cs | 24 +-- .../Scenes/Tests/SceneObjectResizeTests.cs | 2 +- .../Scenes/Tests/ScenePresenceSitTests.cs | 8 +- .../Framework/Scenes/Tests/TaskInventoryTests.cs | 9 +- .../World/NPC/Tests/NPCModuleTests.cs | 4 +- .../Shared/Api/Implementation/OSSL_Api.cs | 54 ++++++- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 7 + .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 5 + .../Shared/Tests/LSL_ApiLinkingTests.cs | 7 +- .../ScriptEngine/Shared/Tests/LSL_ApiTest.cs | 2 +- .../Shared/Tests/OSSL_ApiAttachmentTests.cs | 178 +++++++++++++++++++++ .../ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs | 6 +- OpenSim/Tests/Common/Helpers/SceneHelpers.cs | 10 +- .../Tests/Common/Helpers/TaskInventoryHelpers.cs | 47 +++++- 17 files changed, 340 insertions(+), 51 deletions(-) create mode 100644 OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index b0c087f..7856953 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -122,7 +122,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests string attName = "att"; - SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID).ParentGroup; + SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false); diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs index 0545250..396095a 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs @@ -63,7 +63,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); + SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart; MediaEntry me = new MediaEntry(); m_module.SetMediaEntry(part, 1, me); @@ -88,7 +88,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests string homeUrl = "opensimulator.org"; - SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); + SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart; MediaEntry me = new MediaEntry() { HomeURL = homeUrl }; m_module.SetMediaEntry(part, 1, me); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs index 81add43..3398a53 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs @@ -186,15 +186,15 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestHelpers.InMethod(); TestScene scene = new SceneHelpers().SetupScene(); - SceneObjectPart part = SceneHelpers.AddSceneObject(scene); + SceneObjectGroup so = SceneHelpers.AddSceneObject(scene); - Assert.That(part.ParentGroup.IsDeleted, Is.False); + Assert.That(so.IsDeleted, Is.False); - scene.DeleteSceneObject(part.ParentGroup, false); + scene.DeleteSceneObject(so, false); - Assert.That(part.ParentGroup.IsDeleted, Is.True); + Assert.That(so.IsDeleted, Is.True); - SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); + SceneObjectPart retrievedPart = scene.GetSceneObjectPart(so.LocalId); Assert.That(retrievedPart, Is.Null); } @@ -215,22 +215,22 @@ namespace OpenSim.Region.Framework.Scenes.Tests AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; sogd.Enabled = false; - SceneObjectPart part = SceneHelpers.AddSceneObject(scene); + SceneObjectGroup so = SceneHelpers.AddSceneObject(scene); IClientAPI client = SceneHelpers.AddScenePresence(scene, agentId).ControllingClient; - scene.DeRezObjects(client, new System.Collections.Generic.List() { part.LocalId }, UUID.Zero, DeRezAction.Delete, UUID.Zero); + scene.DeRezObjects(client, new System.Collections.Generic.List() { so.LocalId }, UUID.Zero, DeRezAction.Delete, UUID.Zero); - SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); + SceneObjectPart retrievedPart = scene.GetSceneObjectPart(so.LocalId); Assert.That(retrievedPart, Is.Not.Null); - Assert.That(part.ParentGroup.IsDeleted, Is.False); + Assert.That(so.IsDeleted, Is.False); sogd.InventoryDeQueueAndDelete(); - Assert.That(part.ParentGroup.IsDeleted, Is.True); + Assert.That(so.IsDeleted, Is.True); - SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(part.LocalId); + SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(so.LocalId); Assert.That(retrievedPart2, Is.Null); } diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs index 1add3dd..0e525c9 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs @@ -72,10 +72,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests bool debugtest = false; Scene scene = new SceneHelpers().SetupScene(); - SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene); - SceneObjectGroup grp1 = part1.ParentGroup; - SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene); - SceneObjectGroup grp2 = part2.ParentGroup; + SceneObjectGroup grp1 = SceneHelpers.AddSceneObject(scene); + SceneObjectPart part1 = grp1.RootPart; + SceneObjectGroup grp2 = SceneHelpers.AddSceneObject(scene); + SceneObjectPart part2 = grp2.RootPart; grp1.AbsolutePosition = new Vector3(10, 10, 10); grp2.AbsolutePosition = Vector3.Zero; @@ -154,14 +154,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests bool debugtest = false; Scene scene = new SceneHelpers().SetupScene(); - SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene); - SceneObjectGroup grp1 = part1.ParentGroup; - SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene); - SceneObjectGroup grp2 = part2.ParentGroup; - SceneObjectPart part3 = SceneHelpers.AddSceneObject(scene); - SceneObjectGroup grp3 = part3.ParentGroup; - SceneObjectPart part4 = SceneHelpers.AddSceneObject(scene); - SceneObjectGroup grp4 = part4.ParentGroup; + SceneObjectGroup grp1 = SceneHelpers.AddSceneObject(scene); + SceneObjectPart part1 = grp1.RootPart; + SceneObjectGroup grp2 = SceneHelpers.AddSceneObject(scene); + SceneObjectPart part2 = grp2.RootPart; + SceneObjectGroup grp3 = SceneHelpers.AddSceneObject(scene); + SceneObjectPart part3 = grp3.RootPart; + SceneObjectGroup grp4 = SceneHelpers.AddSceneObject(scene); + SceneObjectPart part4 = grp4.RootPart; grp1.AbsolutePosition = new Vector3(10, 10, 10); grp2.AbsolutePosition = Vector3.Zero; diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs index 0a94c19..e931859 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs @@ -53,7 +53,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests // log4net.Config.XmlConfigurator.Configure(); Scene scene = new SceneHelpers().SetupScene(); - SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene).ParentGroup; + SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene); g1.GroupResize(new Vector3(2, 3, 4)); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs index 313e350..ed39be1 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs @@ -64,7 +64,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Vector3 startPos = new Vector3(10.1f, 0, 0); m_sp.AbsolutePosition = startPos; - SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); + SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart; m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); @@ -82,7 +82,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Vector3 startPos = new Vector3(9.9f, 0, 0); m_sp.AbsolutePosition = startPos; - SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); + SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart; m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); @@ -100,7 +100,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Vector3 startPos = new Vector3(1, 1, 1); m_sp.AbsolutePosition = startPos; - SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); + SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart; m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); @@ -133,7 +133,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Vector3 startPos = new Vector3(128, 128, 30); m_sp.AbsolutePosition = startPos; - SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); + SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart; part.SitTargetPosition = new Vector3(0, 0, 1); m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs index d15141b..a51e4e3 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs @@ -128,7 +128,9 @@ namespace OpenSim.Region.Framework.Tests UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); SceneObjectPart sop1 = sog1.RootPart; - TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard(scene, sop1); + TaskInventoryItem sopItem1 + = TaskInventoryHelpers.AddNotecard( + scene, sop1, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900)); InventoryFolderBase folder = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, user1.PrincipalID, "Objects")[0]; @@ -156,8 +158,11 @@ namespace OpenSim.Region.Framework.Tests Scene scene = new SceneHelpers().SetupScene(); UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); + SceneObjectPart sop1 = sog1.RootPart; - TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard(scene, sop1); + TaskInventoryItem sopItem1 + = TaskInventoryHelpers.AddNotecard( + scene, sop1, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900)); // Perform test scene.MoveTaskInventoryItem(user1.PrincipalID, UUID.Zero, sop1, sopItem1.ItemID); diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 65dad2d..9179966 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -301,7 +301,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests UUID npcId = m_npcMod.CreateNPC("John", "Smith", startPos, UUID.Zero, true, m_scene, sp.Appearance); ScenePresence npc = m_scene.GetScenePresence(npcId); - SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); + SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart; part.SitTargetPosition = new Vector3(0, 0, 1); m_npcMod.Sit(npc.UUID, part.UUID, m_scene); @@ -333,7 +333,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests UUID npcId = m_npcMod.CreateNPC("John", "Smith", startPos, UUID.Zero, true, m_scene, sp.Appearance); ScenePresence npc = m_scene.GetScenePresence(npcId); - SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); + SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart; m_npcMod.Sit(npc.UUID, part.UUID, m_scene); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 7fa25f5..fa9364d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -126,7 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api [Serializable] public class OSSL_Api : MarshalByRefObject, IOSSL_Api, IScriptApi { -// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public const string GridInfoServiceConfigSectionName = "GridInfoService"; @@ -3151,6 +3151,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ((LSL_Api)m_LSL_Api).AttachToAvatar(attachmentPoint); } + public void osForceAttachToAvatarFromInventory(string itemName, int attachmentPoint) + { + CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatarFromInventory"); + + IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; + + if (attachmentsModule == null) + return; + + m_host.AddScriptLPS(1); + + InitLSL(); + + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); + + if (item == null) + { + ((LSL_Api)m_LSL_Api).llSay(0, string.Format("Could not find object '{0}'", itemName)); + throw new Exception(String.Format("The inventory item '{0}' could not be found", itemName)); + } + + if (item.InvType != (int)InventoryType.Object) + { + // FIXME: Temporary null check for regression tests since they dont' have the infrastructure to set + // up the api reference. + if (m_LSL_Api != null) + ((LSL_Api)m_LSL_Api).llSay(0, string.Format("Unable to attach, item '{0}' is not an object.", itemName)); + + throw new Exception(String.Format("The inventory item '{0}' is not an object", itemName)); + + return; + } + + ScenePresence sp = World.GetScenePresence(m_host.OwnerID); + + if (sp == null) + return; + + InventoryItemBase newItem = World.MoveTaskInventoryItem(sp.UUID, UUID.Zero, m_host, item.ItemID); + + if (newItem == null) + { + m_log.ErrorFormat( + "[OSSL API]: Could not create user inventory item {0} for {1}, attach point {2} in {3}", + itemName, m_host.Name, attachmentPoint, World.Name); + + return; + } + + attachmentsModule.RezSingleAttachmentFromInventory(sp, newItem.ID, (uint)attachmentPoint); + } + public void osForceDetachFromAvatar() { CheckThreatLevel(ThreatLevel.High, "osForceDetachFromAvatar"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index e92518d..a8335aa 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -107,6 +107,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osForceAttachToAvatar(int attachment); /// + /// Attach the inventory item in the object containing this script to the avatar that owns it without checking for PERMISSION_ATTACH + /// + /// Tha name of the item. If this is not found then a warning is said to the owner + /// The attachment point. For example, ATTACH_CHEST + void osForceAttachToAvatarFromInventory(string itemName, int attachment); + + /// /// Detach the object containing this script from the avatar it is attached to without checking for PERMISSION_ATTACH /// /// Nothing happens if the object is not attached. diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index d230662..500ed96 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -296,6 +296,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osForceAttachToAvatar(attachmentPoint); } + public void osForceAttachToAvatarFromInventory(string itemName, int attachmentPoint) + { + m_OSSL_Functions.osForceAttachToAvatarFromInventory(itemName, attachmentPoint); + } + public void osForceDetachFromAvatar() { m_OSSL_Functions.osForceDetachFromAvatar(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs index bc3b790..2565ae7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs @@ -89,7 +89,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests // FIXME: This should really be a script item (with accompanying script) TaskInventoryItem grp1Item - = TaskInventoryHelpers.AddNotecard(m_scene, grp1.RootPart); + = TaskInventoryHelpers.AddNotecard( + m_scene, grp1.RootPart, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900)); grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; SceneObjectGroup grp2 = SceneHelpers.CreateSceneObject(2, ownerId, "grp2-", 0x20); @@ -122,7 +123,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests // FIXME: This should really be a script item (with accompanying script) TaskInventoryItem grp1Item - = TaskInventoryHelpers.AddNotecard(m_scene, grp1.RootPart); + = TaskInventoryHelpers.AddNotecard( + m_scene, grp1.RootPart, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900)); + grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; LSL_Api apiGrp1 = new LSL_Api(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs index f96a156..c41d1e7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs @@ -59,7 +59,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests config.Set("Enabled", "true"); Scene scene = new SceneHelpers().SetupScene(); - SceneObjectPart part = SceneHelpers.AddSceneObject(scene); + SceneObjectPart part = SceneHelpers.AddSceneObject(scene).RootPart; XEngine.XEngine engine = new XEngine.XEngine(); engine.Initialise(initConfigSource); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs new file mode 100644 index 0000000..537b8aa --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs @@ -0,0 +1,178 @@ +/* + * 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 System.Text; +using log4net; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenMetaverse.Assets; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Avatar.Attachments; +using OpenSim.Region.CoreModules.Framework.InventoryAccess; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Services.Interfaces; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.ScriptEngine.Shared.Tests +{ + /// + /// Tests for OSSL attachment functions + /// + /// + /// TODO: Add tests for all functions + /// + [TestFixture] + public class OSSL_ApiAttachmentTests : OpenSimTestCase + { + protected Scene m_scene; + protected XEngine.XEngine m_engine; + + [SetUp] + public override void SetUp() + { + base.SetUp(); + + IConfigSource initConfigSource = new IniConfigSource(); + + IConfig xengineConfig = initConfigSource.AddConfig("XEngine"); + xengineConfig.Set("Enabled", "true"); + xengineConfig.Set("AllowOSFunctions", "true"); + xengineConfig.Set("OSFunctionThreatLevel", "Severe"); + + IConfig modulesConfig = initConfigSource.AddConfig("Modules"); + modulesConfig.Set("InventoryAccessModule", "BasicInventoryAccessModule"); + + m_scene = new SceneHelpers().SetupScene(); + SceneHelpers.SetupSceneModules( + m_scene, initConfigSource, new AttachmentsModule(), new BasicInventoryAccessModule()); + + m_engine = new XEngine.XEngine(); + m_engine.Initialise(initConfigSource); + m_engine.AddRegion(m_scene); + } + + [Test] + public void TestOsForceAttachToAvatarFromInventory() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string taskInvObjItemName = "sphere"; + UUID taskInvObjItemId = UUID.Parse("00000000-0000-0000-0000-100000000000"); + AttachmentPoint attachPoint = AttachmentPoint.Chin; + + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(m_scene, 0x1); + ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, ua1.PrincipalID); + SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); + TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); + + new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem); + OSSL_Api osslApi = new OSSL_Api(); + osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem); + +// SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ua1.PrincipalID); + + // Create an object embedded inside the first + TaskInventoryHelpers.AddSceneObject(m_scene, inWorldObj.RootPart, taskInvObjItemName, taskInvObjItemId, ua1.PrincipalID); + + osslApi.osForceAttachToAvatarFromInventory(taskInvObjItemName, (int)attachPoint); + + // Check scene presence status + Assert.That(sp.HasAttachments(), Is.True); + List attachments = sp.GetAttachments(); + Assert.That(attachments.Count, Is.EqualTo(1)); + SceneObjectGroup attSo = attachments[0]; + Assert.That(attSo.Name, Is.EqualTo(taskInvObjItemName)); + Assert.That(attSo.AttachmentPoint, Is.EqualTo((uint)attachPoint)); + Assert.That(attSo.IsAttachment); + Assert.That(attSo.UsesPhysics, Is.False); + Assert.That(attSo.IsTemporary, Is.False); + + // Check appearance status + List attachmentsInAppearance = sp.Appearance.GetAttachments(); + Assert.That(attachmentsInAppearance.Count, Is.EqualTo(1)); + Assert.That(sp.Appearance.GetAttachpoint(attachmentsInAppearance[0].ItemID), Is.EqualTo((uint)attachPoint)); + } + + /// + /// Make sure we can't force attach anything other than objects. + /// + [Test] + public void TestOsForceAttachToAvatarFromInventoryNotObject() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string taskInvObjItemName = "sphere"; + UUID taskInvObjItemId = UUID.Parse("00000000-0000-0000-0000-100000000000"); + AttachmentPoint attachPoint = AttachmentPoint.Chin; + + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(m_scene, 0x1); + ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, ua1.PrincipalID); + SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); + TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); + + new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem); + OSSL_Api osslApi = new OSSL_Api(); + osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem); + + // Create an object embedded inside the first + TaskInventoryHelpers.AddNotecard( + m_scene, inWorldObj.RootPart, taskInvObjItemName, taskInvObjItemId, TestHelpers.ParseTail(0x900)); + + bool exceptionCaught = false; + + try + { + osslApi.osForceAttachToAvatarFromInventory(taskInvObjItemName, (int)attachPoint); + } + catch (Exception e) + { + exceptionCaught = true; + } + + Assert.That(exceptionCaught, Is.True); + + // Check scene presence status + Assert.That(sp.HasAttachments(), Is.False); + List attachments = sp.GetAttachments(); + Assert.That(attachments.Count, Is.EqualTo(0)); + + // Check appearance status + List attachmentsInAppearance = sp.Appearance.GetAttachments(); + Assert.That(attachmentsInAppearance.Count, Is.EqualTo(0)); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs index 0ccd889..813e53b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs @@ -52,14 +52,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests /// Tests for OSSL NPC API /// [TestFixture] - public class OSSL_NpcApiAppearanceTest + public class OSSL_NpcApiAppearanceTest : OpenSimTestCase { protected Scene m_scene; protected XEngine.XEngine m_engine; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + IConfigSource initConfigSource = new IniConfigSource(); IConfig config = initConfigSource.AddConfig("XEngine"); config.Set("Enabled", "true"); diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index 239afc0..3a2e420 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs @@ -564,7 +564,7 @@ namespace OpenSim.Tests.Common /// /// /// - public static SceneObjectPart AddSceneObject(Scene scene) + public static SceneObjectGroup AddSceneObject(Scene scene) { return AddSceneObject(scene, "Test Object", UUID.Zero); } @@ -576,16 +576,16 @@ namespace OpenSim.Tests.Common /// /// /// - public static SceneObjectPart AddSceneObject(Scene scene, string name, UUID ownerId) + public static SceneObjectGroup AddSceneObject(Scene scene, string name, UUID ownerId) { - SceneObjectPart part = CreateSceneObjectPart(name, UUID.Random(), ownerId); + SceneObjectGroup so = new SceneObjectGroup(CreateSceneObjectPart(name, UUID.Random(), ownerId)); //part.UpdatePrimFlags(false, false, true); //part.ObjectFlags |= (uint)PrimFlags.Phantom; - scene.AddNewSceneObject(new SceneObjectGroup(part), false); + scene.AddNewSceneObject(so, false); - return part; + return so; } /// diff --git a/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs index 7058d1e..9607f1f 100644 --- a/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs @@ -45,20 +45,23 @@ namespace OpenSim.Tests.Common /// /// /// + /// + /// + /// /// The item that was added - public static TaskInventoryItem AddNotecard(Scene scene, SceneObjectPart part) + public static TaskInventoryItem AddNotecard(Scene scene, SceneObjectPart part, string itemName, UUID itemID, UUID assetID) { AssetNotecard nc = new AssetNotecard(); nc.BodyText = "Hello World!"; nc.Encode(); - UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000"); - UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000"); + AssetBase ncAsset - = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero); + = AssetHelpers.CreateAsset(assetID, AssetType.Notecard, nc.AssetData, UUID.Zero); scene.AssetService.Store(ncAsset); + TaskInventoryItem ncItem = new TaskInventoryItem - { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid, + { Name = itemName, AssetID = assetID, ItemID = itemID, Type = (int)AssetType.Notecard, InvType = (int)InventoryType.Notecard }; part.Inventory.AddInventoryItem(ncItem, true); @@ -66,8 +69,42 @@ namespace OpenSim.Tests.Common } /// + /// Add a blank script to the given part. + /// + /// + /// TODO: Accept input for item and asset IDs to avoid mysterious script failures that try to use any of these + /// functions more than once in a test. + /// + /// + /// + /// The item that was added + public static TaskInventoryItem AddScript(Scene scene, SceneObjectPart part) + { + AssetScriptText ast = new AssetScriptText(); + ast.Encode(); + + UUID assetUuid = new UUID("00000000-0000-0000-1000-000000000000"); + UUID itemUuid = new UUID("00000000-0000-0000-1100-000000000000"); + AssetBase asset + = AssetHelpers.CreateAsset(assetUuid, AssetType.LSLText, ast.AssetData, UUID.Zero); + scene.AssetService.Store(asset); + TaskInventoryItem item + = new TaskInventoryItem + { Name = "scriptItem", AssetID = assetUuid, ItemID = itemUuid, + Type = (int)AssetType.LSLText, InvType = (int)InventoryType.LSL }; + part.Inventory.AddInventoryItem(item, true); + + return item; + } + + /// /// Add a scene object item to the given part. /// + /// + /// TODO: Accept input for item and asset IDs to avoid mysterious script failures that try to use any of these + /// functions more than once in a test. + /// + /// /// /// /// -- cgit v1.1 From 510e809abae3c126d68ffe2b0645b4697f5b56b2 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Wed, 4 Jul 2012 00:53:16 +0100 Subject: porting console commands from raw2sculpt 3.2 --- .../CoreModules/World/Terrain/TerrainModule.cs | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 2eac0fa..3f848ed 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -1108,6 +1108,32 @@ namespace OpenSim.Region.CoreModules.World.Terrain CheckForTerrainUpdates(); } + private void InterfaceMinTerrain(Object[] args) + { + int x, y; + for (x = 0; x < m_channel.Width; x++) + { + for (y = 0; y < m_channel.Height; y++) + { + m_channel[x, y] = Math.Max((double)args[0], m_channel[x, y]); + } + } + CheckForTerrainUpdates(); + } + + private void InterfaceMaxTerrain(Object[] args) + { + int x, y; + for (x = 0; x < m_channel.Width; x++) + { + for (y = 0; y < m_channel.Height; y++) + { + m_channel[x, y] = Math.Min((double)args[0], m_channel[x, y]); + } + } + CheckForTerrainUpdates(); + } + private void InterfaceShowDebugStats(Object[] args) { double max = Double.MinValue; @@ -1248,6 +1274,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain rescaleCommand.AddArgument("min", "min terrain height after rescaling", "Double"); rescaleCommand.AddArgument("max", "max terrain height after rescaling", "Double"); + Command minCommand = new Command("min", CommandIntentions.COMMAND_HAZARDOUS, InterfaceMinTerrain, "Sets the minimum terrain height to the specified value."); + minCommand.AddArgument("min", "terrain height to use as minimum", "Double"); + + Command maxCommand = new Command("max", CommandIntentions.COMMAND_HAZARDOUS, InterfaceMaxTerrain, "Sets the maximum terrain height to the specified value."); + maxCommand.AddArgument("min", "terrain height to use as maximum", "Double"); + // Debug Command showDebugStatsCommand = @@ -1279,6 +1311,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain m_commander.RegisterCommand("effect", pluginRunCommand); m_commander.RegisterCommand("flip", flipCommand); m_commander.RegisterCommand("rescale", rescaleCommand); + m_commander.RegisterCommand("min", minCommand); + m_commander.RegisterCommand("max", maxCommand); // Add this to our scene so scripts can call these functions m_scene.RegisterModuleCommander(m_commander); -- cgit v1.1 From 462f7bccf93d3c4ceb1619fd92f048a87204f417 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 5 Jul 2012 20:58:20 +0100 Subject: minor: Add more information to OSFunctionThreatLevel and clarify some text in using PARCEL_OWNER, PARCEL_GROUP_MEMBER, ESTATE_MANAGER, ESTATE_OWNER permission categories --- bin/OpenSim.ini.example | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 741877e..c07e1ab 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -673,8 +673,11 @@ ; AllowLightShareFunctions = false ;# {OSFunctionThreatLevel} {Enabled:true AllowOSFunctions:true} {OSFunction threat level? (DANGEROUS!)} {None VeryLow Low Moderate High VeryHigh Severe} VeryLow - ;; Threat level to allow, one of None, VeryLow, Low, Moderate, High, - ;; VeryHigh, Severe + ;; Threat level to allow, one of None, VeryLow, Low, Moderate, High, VeryHigh, Severe + ;; See http://opensimulator.org/wiki/Threat_level for more information on these levels. + ;; We do not recommend that use set a general level above Low unless you have a high level of trust + ;; in all the users that can run scripts in your simulator. It is safer to explicitly + ;; allow certain types of user to run higher threat level OSSL functions, as detailed later on. OSFunctionThreatLevel = VeryLow ; OS Functions enable/disable @@ -691,10 +694,10 @@ ; Allow_osSetRegionWaterHeight = 888760cb-a3cf-43ac-8ea4-8732fd3ee2bb ; Comma separated list of owner classes that allow the function for a particular class of owners. Choices are - ; - PARCEL_GROUP_MEMBER: allow if objectgroup is the same group as the parcel - ; - PARCEL_OWNER: allow if the objectowner is parcelowner - ; - ESTATE_MANAGER: allow if the object owner is a estate manager - ; - ESTATE_OWNER: allow if objectowner is estateowner + ; - PARCEL_GROUP_MEMBER: allow if the object group is the same group as the parcel + ; - PARCEL_OWNER: allow if the object owner is the parcel owner + ; - ESTATE_MANAGER: allow if the object owner is an estate manager + ; - ESTATE_OWNER: allow if the object owner is the estate owner ; Allow_osSetRegionWaterHeight = 888760cb-a3cf-43ac-8ea4-8732fd3ee2bb, PARCEL_OWNER, ESTATE_OWNER>, ... ; You can also use script creators as the uuid -- cgit v1.1 From 8674604ff5760335f08fa910381608757e89ad21 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 5 Jul 2012 21:10:59 +0100 Subject: regrade osFormatString, osMatchString and osReplaceString to VeryLow. I can't see that these present any real hazard to sim functioning. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index fa9364d..7385dd9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2125,7 +2125,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String osFormatString(string str, LSL_List strings) { - CheckThreatLevel(ThreatLevel.Low, "osFormatString"); + CheckThreatLevel(ThreatLevel.VeryLow, "osFormatString"); m_host.AddScriptLPS(1); return String.Format(str, strings.Data); @@ -2133,7 +2133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_List osMatchString(string src, string pattern, int start) { - CheckThreatLevel(ThreatLevel.High, "osMatchString"); + CheckThreatLevel(ThreatLevel.VeryLow, "osMatchString"); m_host.AddScriptLPS(1); LSL_List result = new LSL_List(); @@ -2175,7 +2175,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String osReplaceString(string src, string pattern, string replace, int count, int start) { - CheckThreatLevel(ThreatLevel.High, "osReplaceString"); + CheckThreatLevel(ThreatLevel.VeryLow, "osReplaceString"); m_host.AddScriptLPS(1); // Normalize indices (if negative). -- cgit v1.1 From db9616f7baa45fc15a9afded024655d4ad442556 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 5 Jul 2012 21:30:20 +0100 Subject: minor: add client name to various login service log messages to disambiguate messages from concurrent logins. Also adds destination resolution debug log message showing region endpoint. Adding endpoint to the log helps to find issues where the region external host information has been wrongly configured --- OpenSim/Services/LLLoginService/LLLoginService.cs | 56 +++++++++++++++++------ 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 9acba11..495dc52 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -257,7 +257,9 @@ namespace OpenSim.Services.LLLoginService if (!am.Success) { - m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: client {0} is not allowed", clientVersion); + m_log.InfoFormat( + "[LLOGIN SERVICE]: Login failed for {0} {1}, reason: client {2} is not allowed", + firstName, lastName, clientVersion); return LLFailedLoginResponse.LoginBlockedProblem; } } @@ -269,7 +271,9 @@ namespace OpenSim.Services.LLLoginService if (dm.Success) { - m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: client {0} is denied", clientVersion); + m_log.InfoFormat( + "[LLOGIN SERVICE]: Login failed for {0} {1}, reason: client {2} is denied", + firstName, lastName, clientVersion); return LLFailedLoginResponse.LoginBlockedProblem; } } @@ -280,13 +284,16 @@ namespace OpenSim.Services.LLLoginService UserAccount account = m_UserAccountService.GetUserAccount(scopeID, firstName, lastName); if (account == null) { - m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: user not found"); + m_log.InfoFormat( + "[LLOGIN SERVICE]: Login failed for {0} {1}, reason: user not found", firstName, lastName); return LLFailedLoginResponse.UserProblem; } if (account.UserLevel < m_MinLoginLevel) { - m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: login is blocked for user level {0}", account.UserLevel); + m_log.InfoFormat( + "[LLOGIN SERVICE]: Login failed for {0} {1}, reason: user level is {2} but minimum login level is {3}", + firstName, lastName, m_MinLoginLevel, account.UserLevel); return LLFailedLoginResponse.LoginBlockedProblem; } @@ -297,7 +304,8 @@ namespace OpenSim.Services.LLLoginService { if (account.ScopeID != scopeID && account.ScopeID != UUID.Zero) { - m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: user not found"); + m_log.InfoFormat( + "[LLOGIN SERVICE]: Login failed, reason: user {0} {1} not found", firstName, lastName); return LLFailedLoginResponse.UserProblem; } } @@ -316,7 +324,9 @@ namespace OpenSim.Services.LLLoginService UUID secureSession = UUID.Zero; if ((token == string.Empty) || (token != string.Empty && !UUID.TryParse(token, out secureSession))) { - m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: authentication failed"); + m_log.InfoFormat( + "[LLOGIN SERVICE]: Login failed for {0} {1}, reason: authentication failed", + firstName, lastName); return LLFailedLoginResponse.UserProblem; } @@ -325,13 +335,18 @@ namespace OpenSim.Services.LLLoginService // if (m_RequireInventory && m_InventoryService == null) { - m_log.WarnFormat("[LLOGIN SERVICE]: Login failed, reason: inventory service not set up"); + m_log.WarnFormat( + "[LLOGIN SERVICE]: Login failed for {0} {1}, reason: inventory service not set up", + firstName, lastName); return LLFailedLoginResponse.InventoryProblem; } + List inventorySkel = m_InventoryService.GetInventorySkeleton(account.PrincipalID); if (m_RequireInventory && ((inventorySkel == null) || (inventorySkel != null && inventorySkel.Count == 0))) { - m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: unable to retrieve user inventory"); + m_log.InfoFormat( + "[LLOGIN SERVICE]: Login failed, for {0} {1}, reason: unable to retrieve user inventory", + firstName, lastName); return LLFailedLoginResponse.InventoryProblem; } @@ -345,9 +360,12 @@ namespace OpenSim.Services.LLLoginService if (m_PresenceService != null) { success = m_PresenceService.LoginAgent(account.PrincipalID.ToString(), session, secureSession); + if (!success) { - m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: could not login presence"); + m_log.InfoFormat( + "[LLOGIN SERVICE]: Login failed for {0} {1}, reason: could not login presence", + firstName, lastName); return LLFailedLoginResponse.GridProblem; } } @@ -380,9 +398,18 @@ namespace OpenSim.Services.LLLoginService if (destination == null) { m_PresenceService.LogoutAgent(session); - m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: destination not found"); + + m_log.InfoFormat( + "[LLOGIN SERVICE]: Login failed for {0} {1}, reason: destination not found", + firstName, lastName); return LLFailedLoginResponse.GridProblem; } + else + { + m_log.DebugFormat( + "[LLOGIN SERVICE]: Found destination {0}, endpoint {1} for {2} {3}", + destination.RegionName, destination.ExternalEndPoint, firstName, lastName); + } if (account.UserLevel >= 200) flags |= TeleportFlags.Godlike; @@ -406,7 +433,7 @@ namespace OpenSim.Services.LLLoginService if (aCircuit == null) { m_PresenceService.LogoutAgent(session); - m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: {0}", reason); + m_log.InfoFormat("[LLOGIN SERVICE]: Login failed for {0} {1}, reason: {2}", firstName, lastName, reason); return new LLFailedLoginResponse("key", reason, "false"); } @@ -427,7 +454,8 @@ namespace OpenSim.Services.LLLoginService where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP, m_MapTileURL, m_ProfileURL, m_OpenIDURL, m_SearchURL, m_Currency, m_DSTZone); - m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to client."); + m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to {0} {1}", firstName, lastName); + return response; } catch (Exception e) @@ -446,7 +474,9 @@ namespace OpenSim.Services.LLLoginService { flags = TeleportFlags.ViaLogin; - m_log.DebugFormat("[LLOGIN SERVICE]: FindDestination for start location {0}", startLocation); + m_log.DebugFormat( + "[LLOGIN SERVICE]: Finding destination matching start location {0} for {1}", + startLocation, account.Name); gatekeeper = null; where = "home"; -- cgit v1.1 From 7e73f609e5f61040358ec247d371306165945ca1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 5 Jul 2012 23:15:59 +0100 Subject: Log warning if time between invocations of the watchdog thread is twice the timer setting. This is to help detect situations where thread timeout warnings are being generated because of general machine issues rather than deadlock, network or other problems. --- OpenSim/Framework/Watchdog.cs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs index 2b3a719..8a74f53 100644 --- a/OpenSim/Framework/Watchdog.cs +++ b/OpenSim/Framework/Watchdog.cs @@ -101,12 +101,24 @@ namespace OpenSim.Framework private static Dictionary m_threads; private static System.Timers.Timer m_watchdogTimer; + /// + /// Last time the watchdog thread ran. + /// + /// + /// Should run every WATCHDOG_INTERVAL_MS + /// + public static int LastWatchdogThreadTick { get; private set; } + static Watchdog() { m_threads = new Dictionary(); m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS); m_watchdogTimer.AutoReset = false; m_watchdogTimer.Elapsed += WatchdogTimerElapsed; + + // Set now so we don't get alerted on the first run + LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue; + m_watchdogTimer.Start(); } @@ -264,6 +276,16 @@ namespace OpenSim.Framework /// private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) { + int now = Environment.TickCount & Int32.MaxValue; + int msElapsed = now - LastWatchdogThreadTick; + + if (msElapsed > WATCHDOG_INTERVAL_MS * 2) + m_log.WarnFormat( + "[WATCHDOG]: {0} ms since Watchdog last ran. Interval should be approximately {1} ms", + msElapsed, WATCHDOG_INTERVAL_MS); + + LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue; + Action callback = OnWatchdogTimeout; if (callback != null) @@ -272,8 +294,6 @@ namespace OpenSim.Framework lock (m_threads) { - int now = Environment.TickCount & Int32.MaxValue; - foreach (ThreadWatchdogInfo threadInfo in m_threads.Values) { if (threadInfo.Thread.ThreadState == ThreadState.Stopped) -- cgit v1.1 From 843112340e3220e6bef5a05d8607efb478e19013 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 6 Jul 2012 00:37:45 +0100 Subject: Log MONO_THREADS_PER_CPU value on simulator startup, or "unset" if it is not set --- OpenSim/Region/Application/Application.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs index c130038..ebfebc4 100644 --- a/OpenSim/Region/Application/Application.cs +++ b/OpenSim/Region/Application/Application.cs @@ -92,9 +92,14 @@ namespace OpenSim m_log.Info("[OPENSIM MAIN]: configured log4net using default OpenSim.exe.config"); } - m_log.DebugFormat( + m_log.InfoFormat( "[OPENSIM MAIN]: System Locale is {0}", System.Threading.Thread.CurrentThread.CurrentCulture); + string monoThreadsPerCpu = System.Environment.GetEnvironmentVariable("MONO_THREADS_PER_CPU"); + + m_log.InfoFormat( + "[OPENSIM MAIN]: Environment variable MONO_THREADS_PER_CPU is {0}", monoThreadsPerCpu ?? "unset"); + // Increase the number of IOCP threads available. Mono defaults to a tragically low number int workerThreads, iocpThreads; System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads); @@ -109,7 +114,6 @@ namespace OpenSim // Check if the system is compatible with OpenSimulator. // Ensures that the minimum system requirements are met - m_log.Info("Performing compatibility checks... \n"); string supported = String.Empty; if (Util.IsEnvironmentSupported(ref supported)) { -- cgit v1.1 From f6e5791ecd0b75ae4a6a85c66874af7047f6f55b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 6 Jul 2012 22:07:19 +0100 Subject: refactor: extract method UpdateUserInventoryWithAttachment() from AttachObject() for better code comprehension --- .../Avatar/Attachments/AttachmentsModule.cs | 67 ++++++++++++---------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index af30a8e..9eb0e38 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -292,31 +292,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments group.AttachmentPoint = attachmentPt; group.AbsolutePosition = attachPos; - - // We also don't want to do any of the inventory operations for an NPC. + if (sp.PresenceType != PresenceType.Npc) - { - // Remove any previous attachments - List attachments = sp.GetAttachments(attachmentPt); - - // At the moment we can only deal with a single attachment - if (attachments.Count != 0) - { - if (attachments[0].FromItemID != UUID.Zero) - DetachSingleAttachmentToInvInternal(sp, attachments[0]); - else - m_log.WarnFormat( - "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!", - attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name); - } - - // Add the new attachment to inventory if we don't already have it. - UUID newAttachmentItemID = group.FromItemID; - if (newAttachmentItemID == UUID.Zero) - newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; - - ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); - } + UpdateUserInventoryWithAttachment(sp, group, attachmentPt); AttachToAgent(sp, group, attachmentPt, attachPos, silent); } @@ -324,6 +302,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return true; } + private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt) + { + // Remove any previous attachments + List attachments = sp.GetAttachments(attachmentPt); + + // At the moment we can only deal with a single attachment + if (attachments.Count != 0) + { + if (attachments[0].FromItemID != UUID.Zero) + DetachSingleAttachmentToInvInternal(sp, attachments[0]); + else + m_log.WarnFormat( + "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!", + attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name); + } + + // Add the new attachment to inventory if we don't already have it. + UUID newAttachmentItemID = group.FromItemID; + if (newAttachmentItemID == UUID.Zero) + newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; + + ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); + } + public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) { if (!Enabled) @@ -652,11 +654,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", // grp.Name, grp.LocalId, remoteClient.Name); - InventoryItemBase newItem = m_invAccessModule.CopyToInventory( - DeRezAction.TakeCopy, - m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID, - new List { grp }, - sp.ControllingClient, true)[0]; + InventoryItemBase newItem + = m_invAccessModule.CopyToInventory( + DeRezAction.TakeCopy, + m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID, + new List { grp }, + sp.ControllingClient, true)[0]; // sets itemID so client can show item as 'attached' in inventory grp.FromItemID = newItem.ID; @@ -782,7 +785,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments item = m_scene.InventoryService.GetItem(item); bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); if (changed && m_scene.AvatarFactory != null) + { +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()", +// sp.Name, att.Name, AttachmentPt); + m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); + } } #endregion -- cgit v1.1 From 43a2da9edb9a234ee10735a234d2ad253a33cb7a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 6 Jul 2012 22:33:16 +0100 Subject: Pull prim crossing/teleport checks up into Scene.IncomingCreateObject() from Scene.AddObject() Only IncomingCreateObject() needs these checks. General object adding does not need to perform crossing perm checks --- OpenSim/Region/Framework/Scenes/Scene.cs | 41 +++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 36d39ea..6239d51 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2495,7 +2495,16 @@ namespace OpenSim.Region.Framework.Scenes } catch (Exception e) { - m_log.WarnFormat("[SCENE]: Problem casting object, exception {0}{1}", e.Message, e.StackTrace); + m_log.WarnFormat("[INTERREGION]: Problem casting object, exception {0}{1}", e.Message, e.StackTrace); + return false; + } + + // If the user is banned, we won't let any of their objects + // enter. Period. + // + if (RegionInfo.EstateSettings.IsBanned(newObject.OwnerID)) + { + m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", newObject.OwnerID); return false; } @@ -2504,14 +2513,28 @@ namespace OpenSim.Region.Framework.Scenes if (!AddSceneObject(newObject)) { - m_log.DebugFormat("[SCENE]: Problem adding scene object {0} in {1} ", sog.UUID, RegionInfo.RegionName); + m_log.DebugFormat( + "[INTERREGION]: Problem adding scene object {0} in {1} ", newObject.UUID, RegionInfo.RegionName); return false; } - // For attachments, we need to wait until the agent is root - // before we restart the scripts, or else some functions won't work. if (!newObject.IsAttachment) { + // FIXME: It would be better to never add the scene object at all rather than add it and then delete + // it + if (!Permissions.CanObjectEntry(newObject.UUID, true, newObject.AbsolutePosition)) + { + // Deny non attachments based on parcel settings + // + m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings"); + + DeleteSceneObject(newObject, false); + + return false; + } + + // For attachments, we need to wait until the agent is root + // before we restart the scripts, or else some functions won't work. newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); newObject.ResumeScripts(); } @@ -2531,16 +2554,6 @@ namespace OpenSim.Region.Framework.Scenes /// True if the SceneObjectGroup was added, False if it was not public bool AddSceneObject(SceneObjectGroup sceneObject) { - // If the user is banned, we won't let any of their objects - // enter. Period. - // - if (RegionInfo.EstateSettings.IsBanned(sceneObject.OwnerID)) - { - m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", sceneObject.OwnerID); - - return false; - } - sceneObject.SetScene(this); // Force allocation of new LocalId -- cgit v1.1 From 1b1f841c6aaf2453b3aca0eade84855ae658e655 Mon Sep 17 00:00:00 2001 From: Talun Date: Tue, 3 Jul 2012 11:10:09 +0100 Subject: Mantis 6063 osNpcTouch. Allow NPCS to touch obects. --- OpenSim/Region/Framework/Interfaces/INPCModule.cs | 8 +++++ .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 39 ++++++++++++++++++++++ .../Region/OptionalModules/World/NPC/NPCModule.cs | 10 ++++++ .../Shared/Api/Implementation/OSSL_Api.cs | 35 +++++++++++++++++++ .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 1 + .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 5 +++ 6 files changed, 98 insertions(+) diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs index 860483d..d582149 100644 --- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs +++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs @@ -184,6 +184,14 @@ namespace OpenSim.Region.Framework.Interfaces bool Stand(UUID agentID, Scene scene); /// + /// Get the NPC to touch an object. + /// + /// + /// + /// true if the touch is actually attempted, false if not + bool Touch(UUID agentID, UUID partID); + + /// /// Delete an NPC. /// /// The UUID of the NPC diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index b3e1069..43a09ec 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -104,6 +104,45 @@ namespace OpenSim.Region.OptionalModules.World.NPC OnMoneyTransferRequest(m_uuid, target, amount, 1, "Payment"); } + public bool Touch(UUID target) + { + SceneObjectPart part = m_scene.GetSceneObjectPart(target); + if (part == null) + return false; + bool objectTouchable = hasTouchEvents(part); // Only touch an object that is scripted to respond + if (!objectTouchable && !part.IsRoot) + objectTouchable = hasTouchEvents(part.ParentGroup.RootPart); + if (!objectTouchable) + return false; + // Set up the surface args as if the touch is from a client that does not support this + SurfaceTouchEventArgs surfaceArgs = new SurfaceTouchEventArgs(); + surfaceArgs.FaceIndex = -1; // TOUCH_INVALID_FACE + surfaceArgs.Binormal = Vector3.Zero; // TOUCH_INVALID_VECTOR + surfaceArgs.Normal = Vector3.Zero; // TOUCH_INVALID_VECTOR + surfaceArgs.STCoord = new Vector3(-1.0f, -1.0f, 0.0f); // TOUCH_INVALID_TEXCOORD + surfaceArgs.UVCoord = surfaceArgs.STCoord; // TOUCH_INVALID_TEXCOORD + List touchArgs = new List(); + touchArgs.Add(surfaceArgs); + Vector3 offset = part.OffsetPosition * -1.0f; + if (OnGrabObject == null) + return false; + OnGrabObject(part.LocalId, offset, this, touchArgs); + if (OnGrabUpdate != null) + OnGrabUpdate(part.UUID, offset, part.ParentGroup.RootPart.GroupPosition, this, touchArgs); + if (OnDeGrabObject != null) + OnDeGrabObject(part.LocalId, this, touchArgs); + return true; + } + + private bool hasTouchEvents(SceneObjectPart part) + { + if ((part.ScriptEvents & scriptEvents.touch) != 0 || + (part.ScriptEvents & scriptEvents.touch_start) != 0 || + (part.ScriptEvents & scriptEvents.touch_end) != 0) + return true; + return false; + } + public void InstantMessage(UUID target, string message) { OnInstantMessage(this, new GridInstantMessage(m_scene, diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index d3456ab..1e85fb4 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -305,6 +305,16 @@ namespace OpenSim.Region.OptionalModules.World.NPC return false; } + public bool Touch(UUID agentID, UUID objectID) + { + lock (m_avatars) + { + if (m_avatars.ContainsKey(agentID)) + return m_avatars[agentID].Touch(objectID); + return false; + } + } + public UUID GetOwner(UUID agentID) { lock (m_avatars) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 7385dd9..61394af 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2677,6 +2677,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + public void osNpcTouch(LSL_Key npcLSL_Key, LSL_Key object_key, LSL_Integer link_num) + { + CheckThreatLevel(ThreatLevel.High, "osNpcTouch"); + m_host.AddScriptLPS(1); + INPCModule module = World.RequestModuleInterface(); + int linkNum = link_num.value; + if (module != null || (linkNum < 0 && linkNum != ScriptBaseClass.LINK_THIS)) + { + UUID npcId; + if (!UUID.TryParse(npcLSL_Key, out npcId) || !module.CheckPermissions(npcId, m_host.OwnerID)) + return; + SceneObjectPart part = null; + UUID objectId; + if (UUID.TryParse(LSL_String.ToString(object_key), out objectId)) + part = World.GetSceneObjectPart(objectId); + if (part == null) + return; + if (linkNum != ScriptBaseClass.LINK_THIS) + { + if (linkNum == 0 || linkNum == ScriptBaseClass.LINK_ROOT) + { // 0 and 1 are treated as root, find the root if the current part isnt it + if (!part.IsRoot) + part = part.ParentGroup.RootPart; + } + else + { // Find the prim with the given link number if not found then fail silently + part = part.ParentGroup.GetLinkNumPart(linkNum); + if (part == null) + return; + } + } + module.Touch(npcId, part.UUID); + } + } + /// /// Save the current appearance of the script owner permanently to the named notecard. /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index a8335aa..d38709e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -231,6 +231,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osNpcRemove(key npc); void osNpcPlayAnimation(LSL_Key npc, string animation); void osNpcStopAnimation(LSL_Key npc, string animation); + void osNpcTouch(LSL_Key npcLSL_Key, LSL_Key object_key, LSL_Integer link_num); void osNpcWhisper(key npc, int channel, string message); LSL_Key osOwnerSaveAppearance(string notecard); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 500ed96..692bb0a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -626,6 +626,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osNpcWhisper(npc, channel, message); } + public void osNpcTouch(LSL_Key npcLSL_Key, LSL_Key object_key, LSL_Integer link_num) + { + m_OSSL_Functions.osNpcTouch(npcLSL_Key, object_key, link_num); + } + public LSL_Key osOwnerSaveAppearance(string notecard) { return m_OSSL_Functions.osOwnerSaveAppearance(notecard); -- cgit v1.1 From ae1f2114f5ccb0422536ec73feb2dbf16c2645fd Mon Sep 17 00:00:00 2001 From: Talun Date: Thu, 5 Jul 2012 23:34:23 +0100 Subject: Mantis 6077 trim NPC chat on channel zero. This patch trims leading and trailing spaces from NPC chat and suppresses the sending of empty chat strings on open chat channel 0. --- OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 43a09ec..9b3400d 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -192,6 +192,14 @@ namespace OpenSim.Region.OptionalModules.World.NPC private void SendOnChatFromClient(int channel, string message, ChatTypeEnum chatType) { + if (channel == 0) + { + message = message.Trim(); + if (string.IsNullOrEmpty(message)) + { + return; + } + } OSChatMessage chatFromClient = new OSChatMessage(); chatFromClient.Channel = channel; chatFromClient.From = Name; -- cgit v1.1 From 056c9a59b2fee1e459915bd1ca908107c7c9695d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 6 Jul 2012 23:07:50 +0100 Subject: Add assert to attachment regression tests to check that number of objects in the scene graph --- .../Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 14 ++++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 11 +++++++++++ OpenSim/Region/Framework/Scenes/SceneGraph.cs | 18 +++++++++++++----- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 7856953..c1ba8a8 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -149,6 +149,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); + Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); + // TestHelpers.DisableLogging(); } @@ -181,6 +183,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Check appearance status Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); + + Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); } [Test] @@ -239,6 +243,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Check item status Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo(0)); + + Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(0)); } /// @@ -300,6 +306,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItem.ID)); Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attItem.AssetID)); Assert.That(presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); + + Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); } [Test] @@ -399,6 +407,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name)); Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest)); + // Teleporting attachments should not end up in the scene graph + Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1)); + // Check attachments have been removed from sceneA ScenePresence afterTeleportSceneASp = sceneA.GetScenePresence(ua1.PrincipalID); @@ -410,6 +421,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // This is the actual attachment, which should no longer exist List actualSceneAAttachments = afterTeleportSceneASp.GetAttachments(); Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0)); + + // Teleporting attachments should not end up in the scene graph + Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0)); } // I'm commenting this test because scene setup NEEDS InventoryService to diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 6239d51..d98c01d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4474,6 +4474,17 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// Get all the scene object groups. + /// + /// + /// The scene object groups. If the scene is empty then an empty list is returned. + /// + public List GetSceneObjectGroups() + { + return m_sceneGraph.GetSceneObjectGroups(); + } + + /// /// Get a group via its UUID /// /// diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index a59758f..bc9a585 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -958,6 +958,18 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// Get all the scene object groups. + /// + /// + /// The scene object groups. If the scene is empty then an empty list is returned. + /// + protected internal List GetSceneObjectGroups() + { + lock (SceneObjectGroupsByFullID) + return new List(SceneObjectGroupsByFullID.Values); + } + + /// /// Get a group in the scene /// /// UUID of the group @@ -1100,11 +1112,7 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void ForEachSOG(Action action) { - List objlist; - lock (SceneObjectGroupsByFullID) - objlist = new List(SceneObjectGroupsByFullID.Values); - - foreach (SceneObjectGroup obj in objlist) + foreach (SceneObjectGroup obj in GetSceneObjectGroups()) { try { -- cgit v1.1 From e4a6611865848ffcfa6adedd813534e0a0e4abf3 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 6 Jul 2012 10:01:47 -0700 Subject: Clean up collision reporting code so they are properly passed to the simulator in batches. More comments. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 102 ++++++++++++--------- OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs | 11 +++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 29 +++--- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 23 ++++- 4 files changed, 107 insertions(+), 58 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index b08d5db..dc0c008 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -74,7 +74,7 @@ public class BSCharacter : PhysicsActor private float _buoyancy; private int _subscribedEventsMs = 0; - private int _lastCollisionTime = 0; + private int _nextCollisionOkTime = 0; private Vector3 _PIDTarget; private bool _usePID; @@ -360,17 +360,22 @@ public class BSCharacter : PhysicsActor } //m_lastUpdateSent = false; } + public override void AddAngularForce(Vector3 force, bool pushforce) { } public override void SetMomentum(Vector3 momentum) { } + + // Turn on collision events at a rate no faster than one every the given milliseconds public override void SubscribeEvents(int ms) { _subscribedEventsMs = ms; - _lastCollisionTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen + _nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen } + // Stop collision events public override void UnSubscribeEvents() { _subscribedEventsMs = 0; } + // Return 'true' if someone has subscribed to events public override bool SubscribedEvents() { return (_subscribedEventsMs > 0); } @@ -386,47 +391,57 @@ public class BSCharacter : PhysicsActor _mass = _density * _avatarVolume; } + // Set to 'true' if the individual changed items should be checked + // (someday RequestPhysicsTerseUpdate() will take a bitmap of changed properties) + const bool SHOULD_CHECK_FOR_INDIVIDUAL_CHANGES = false; + // The physics engine says that properties have updated. Update same and inform // the world that things have changed. public void UpdateProperties(EntityProperties entprop) { bool changed = false; - // we assign to the local variables so the normal set action does not happen - if (_position != entprop.Position) - { - _position = entprop.Position; - changed = true; + if (SHOULD_CHECK_FOR_INDIVIDUAL_CHANGES) { + // we assign to the local variables so the normal set action does not happen + if (_position != entprop.Position) { + _position = entprop.Position; + changed = true; + } + if (_orientation != entprop.Rotation) { + _orientation = entprop.Rotation; + changed = true; + } + if (_velocity != entprop.Velocity) { + _velocity = entprop.Velocity; + changed = true; + } + if (_acceleration != entprop.Acceleration) { + _acceleration = entprop.Acceleration; + changed = true; + } + if (_rotationalVelocity != entprop.RotationalVelocity) { + _rotationalVelocity = entprop.RotationalVelocity; + changed = true; + } + if (changed) { + // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); + // Avatar movement is not done by generating this event. There is code in the heartbeat + // loop that updates avatars. + // base.RequestPhysicsterseUpdate(); + } } - if (_orientation != entprop.Rotation) - { + else { + _position = entprop.Position; _orientation = entprop.Rotation; - changed = true; - } - if (_velocity != entprop.Velocity) - { _velocity = entprop.Velocity; - changed = true; - } - if (_acceleration != entprop.Acceleration) - { _acceleration = entprop.Acceleration; - changed = true; - } - if (_rotationalVelocity != entprop.RotationalVelocity) - { _rotationalVelocity = entprop.RotationalVelocity; - changed = true; - } - if (changed) - { - // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); - // Avatar movement is not done by generating this event. There is a system that - // checks for avatar updates each heartbeat loop. // base.RequestPhysicsterseUpdate(); } } // Called by the scene when a collision with this object is reported + // The collision, if it should be reported to the character, is placed in a collection + // that will later be sent to the simulator when SendCollisions() is called. CollisionEventUpdate collisionCollection = null; public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth) { @@ -440,29 +455,34 @@ public class BSCharacter : PhysicsActor } // throttle collisions to the rate specified in the subscription - if (_subscribedEventsMs == 0) return; // don't want collisions - int nowTime = _scene.SimulationNowTime; - if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return; - _lastCollisionTime = nowTime; + if (_subscribedEventsMs != 0) { + int nowTime = _scene.SimulationNowTime; + if (nowTime >= _nextCollisionOkTime) { + _nextCollisionOkTime = nowTime + _subscribedEventsMs; - if (collisionCollection == null) - collisionCollection = new CollisionEventUpdate(); - collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); + if (collisionCollection == null) + collisionCollection = new CollisionEventUpdate(); + collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); + } + } } public void SendCollisions() { - // if (collisionCollection != null) - // { - // base.SendCollisionUpdate(collisionCollection); - // collisionCollection = null; - // } + /* + if (collisionCollection != null && collisionCollection.Count > 0) + { + base.SendCollisionUpdate(collisionCollection); + collisionCollection = null; + } + */ // Kludge to make a collision call even if there are no collisions. // This causes the avatar animation to get updated. if (collisionCollection == null) collisionCollection = new CollisionEventUpdate(); base.SendCollisionUpdate(collisionCollection); - collisionCollection = null; + collisionCollection.Clear(); + // End kludge } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs index 0730824..0f027b8 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs @@ -32,6 +32,14 @@ using OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin { + /// + /// Entry for a port of Bullet (http://bulletphysics.org/) to OpenSim. + /// This module interfaces to an unmanaged C++ library which makes the + /// actual calls into the Bullet physics engine. + /// The unmanaged library is found in opensim-libs::trunk/unmanaged/BulletSim/. + /// The unmanaged library is compiled and linked statically with Bullet + /// to create BulletSim.dll and libBulletSim.so (for both 32 and 64 bit). + /// public class BSPlugin : IPhysicsPlugin { //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); @@ -53,6 +61,9 @@ public class BSPlugin : IPhysicsPlugin { if (Util.IsWindows()) Util.LoadArchSpecificWindowsDll("BulletSim.dll"); + // If not Windows, loading is performed by the + // Mono loader as specified in + // "bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config". _mScene = new BSScene(sceneIdentifier); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 248d1f2..130f1ca 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -90,7 +90,7 @@ public sealed class BSPrim : PhysicsActor private BSPrim _parentPrim; private int _subscribedEventsMs = 0; - private int _lastCollisionTime = 0; + private int _nextCollisionOkTime = 0; long _collidingStep; long _collidingGroundStep; @@ -597,7 +597,8 @@ public sealed class BSPrim : PhysicsActor } public override void SubscribeEvents(int ms) { _subscribedEventsMs = ms; - _lastCollisionTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen + // make sure first collision happens + _nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs; } public override void UnSubscribeEvents() { _subscribedEventsMs = 0; @@ -1338,23 +1339,27 @@ public sealed class BSPrim : PhysicsActor _collidingGroundStep = _scene.SimulationStep; } - if (_subscribedEventsMs == 0) return; // nothing in the object is waiting for collision events - // throttle the collisions to the number of milliseconds specified in the subscription - int nowTime = _scene.SimulationNowTime; - if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return; - _lastCollisionTime = nowTime; + // if someone is subscribed to collision events.... + if (_subscribedEventsMs != 0) { + // throttle the collisions to the number of milliseconds specified in the subscription + int nowTime = _scene.SimulationNowTime; + if (nowTime >= _nextCollisionOkTime) { + _nextCollisionOkTime = nowTime + _subscribedEventsMs; - if (collisionCollection == null) - collisionCollection = new CollisionEventUpdate(); - collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); + if (collisionCollection == null) + collisionCollection = new CollisionEventUpdate(); + collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); + } + } } + // The scene is telling us it's time to pass our collected collisions into the simulator public void SendCollisions() { - if (collisionCollection != null) + if (collisionCollection != null && collisionCollection.Count > 0) { base.SendCollisionUpdate(collisionCollection); - collisionCollection = null; + collisionCollection.Clear(); } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 94a0ccf..417cb5f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -52,6 +52,7 @@ using OpenSim.Region.Framework; // Should prim.link() and prim.delink() membership checking happen at taint time? // Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once // Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect +// Use collision masks for collision with terrain and phantom objects // Implement the genCollisions feature in BulletSim::SetObjectProperties (don't pass up unneeded collisions) // Implement LockAngularMotion // Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation) @@ -62,9 +63,6 @@ using OpenSim.Region.Framework; // Multiple contact points on collision? // See code in ode::near... calls to collision_accounting_events() // (This might not be a problem. ODE collects all the collisions with one object in one tick.) -// Use collision masks for collision with terrain and phantom objects -// Figure out how to not allocate a new Dictionary and List for every collision -// in BSPrim.Collide() and BSCharacter.Collide(). Can the same ones be reused? // Raycast // namespace OpenSim.Region.Physics.BulletSPlugin @@ -405,6 +403,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters // prevent simulation until we've been initialized if (!m_initialized) return 10.0f; + long simulateStartTime = Util.EnvironmentTickCount(); + // update the prim states while we know the physics engine is not busy ProcessTaints(); @@ -437,13 +437,18 @@ public class BSScene : PhysicsScene, IPhysicsParameters } } - // The SendCollision's batch up the collisions on the objects. Now push the collisions into the simulator. + // The above SendCollision's batch up the collisions on the objects. + // Now push the collisions into the simulator. foreach (BSPrim bsp in m_primsWithCollisions) bsp.SendCollisions(); m_primsWithCollisions.Clear(); + + // This is a kludge to get avatar movement updated. + // Don't send collisions only if there were collisions -- send everytime. + // ODE sends collisions even if there are none and this is used to update + // avatar animations and stuff. // foreach (BSCharacter bsc in m_avatarsWithCollisions) // bsc.SendCollisions(); - // This is a kludge to get avatar movement updated. ODE sends collisions even if there isn't any foreach (KeyValuePair kvp in m_avatars) kvp.Value.SendCollisions(); m_avatarsWithCollisions.Clear(); @@ -465,10 +470,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters if (m_avatars.TryGetValue(entprop.ID, out actor)) { actor.UpdateProperties(entprop); + continue; } } } + // If enabled, call into the physics engine to dump statistics if (m_detailedStatsStep > 0) { if ((m_simulationStep % m_detailedStatsStep) == 0) @@ -477,6 +484,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters } } + // this is a waste since the outside routine also calcuates the physics simulation + // period. TODO: There should be a way of computing physics frames from simulator computation. + // long simulateTotalTime = Util.EnvironmentTickCountSubtract(simulateStartTime); + // return (timeStep * (float)simulateTotalTime); + // TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation. return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f; } @@ -528,6 +540,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters public override void SetWaterLevel(float baseheight) { m_waterLevel = baseheight; + // TODO: pass to physics engine so things will float? } public float GetWaterLevel() { -- cgit v1.1 From 74014a38548b831ab56fa552f20d26fa29a83332 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 6 Jul 2012 23:13:00 +0100 Subject: minor: Remove some wrong comments in attachments regression tests --- .../CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index c1ba8a8..5dcbd28 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -407,7 +407,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name)); Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest)); - // Teleporting attachments should not end up in the scene graph Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1)); // Check attachments have been removed from sceneA @@ -422,7 +421,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests List actualSceneAAttachments = afterTeleportSceneASp.GetAttachments(); Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0)); - // Teleporting attachments should not end up in the scene graph Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0)); } -- cgit v1.1 From f1f390cfdfa7485d771e65449889b12b64ad7f56 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 6 Jul 2012 23:22:40 +0100 Subject: Remove now duplicate interregion object check that should have been removed a few commits ago in 43a2da9 --- OpenSim/Region/Framework/Scenes/Scene.cs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d98c01d..5c7bca0 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2600,18 +2600,6 @@ namespace OpenSim.Region.Framework.Scenes else { AddRestoredSceneObject(sceneObject, true, false); - - if (!Permissions.CanObjectEntry(sceneObject.UUID, - true, sceneObject.AbsolutePosition)) - { - // Deny non attachments based on parcel settings - // - m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings"); - - DeleteSceneObject(sceneObject, false); - - return false; - } } return true; -- cgit v1.1 From af9d8de515ff0043d2c19b67a2ce9040b462d12e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 6 Jul 2012 15:56:35 -0700 Subject: BulletSim: update the binaries to the current sources --- bin/lib32/BulletSim.dll | Bin 533504 -> 538112 bytes bin/lib32/libBulletSim.so | Bin 2333901 -> 2334329 bytes bin/lib64/BulletSim.dll | Bin 686080 -> 690688 bytes bin/lib64/libBulletSim.so | Bin 2528521 -> 2529000 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll index 2c28063..a3ccb98 100755 Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so index f40f446..0b286aa 100755 Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll index d9e5e89..d91dac1 100755 Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so index 06770a4..891c956 100755 Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ -- cgit v1.1 From 7ff4eec79cf16886439604a23126abd195ae8b2e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 7 Jul 2012 00:02:45 +0100 Subject: Remove redundant SetScene() function in Scene.AddSceneObject() This is always done later on in SceneGraph.AddSceneObject() if the call hasn't failed due to sanity checks. There's no other purpose for this method to exist and it's dangerous/pointless to call in other conditions. --- OpenSim/Data/Tests/RegionTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 2 -- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 6 +++--- .../Region/Framework/Scenes/SceneObjectGroup.cs | 10 ---------- .../Shared/Tests/OSSL_ApiAppearanceTest.cs | 14 ++++++------- .../ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs | 6 +++--- OpenSim/Tests/Common/Helpers/SceneHelpers.cs | 23 +++++++++++++++++++--- 7 files changed, 34 insertions(+), 29 deletions(-) diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs index 474609b..55b9b4d 100644 --- a/OpenSim/Data/Tests/RegionTests.cs +++ b/OpenSim/Data/Tests/RegionTests.cs @@ -1081,7 +1081,7 @@ namespace OpenSim.Data.Tests sop.Shape = PrimitiveBaseShape.Default; SceneObjectGroup sog = new SceneObjectGroup(sop); - sog.SetScene(scene); +// sog.SetScene(scene); return sog; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 5c7bca0..ec911a5 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2554,8 +2554,6 @@ namespace OpenSim.Region.Framework.Scenes /// True if the SceneObjectGroup was added, False if it was not public bool AddSceneObject(SceneObjectGroup sceneObject) { - sceneObject.SetScene(this); - // Force allocation of new LocalId // SceneObjectPart[] parts = sceneObject.Parts; diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index bc9a585..2be5364 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -355,9 +355,9 @@ namespace OpenSim.Region.Framework.Scenes if (Entities.ContainsKey(sceneObject.UUID)) { -// m_log.DebugFormat( -// "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()", -// m_parentScene.RegionInfo.RegionName, sceneObject.UUID); + m_log.DebugFormat( + "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()", + m_parentScene.RegionInfo.RegionName, sceneObject.UUID); return false; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 96cc376..4e0e183 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1055,16 +1055,6 @@ namespace OpenSim.Region.Framework.Scenes { return Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); } - - /// - /// Added as a way for the storage provider to reset the scene, - /// most likely a better way to do this sort of thing but for now... - /// - /// - public void SetScene(Scene scene) - { - m_scene = scene; - } /// /// Set a part to act as the root part for this scene object diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index 3965734..c8718d9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs @@ -79,7 +79,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests /// Test creation of an NPC where the appearance data comes from a notecard /// [Test] - public void TestOsNpcCreateFromNotecard() + public void TestOsNpcCreateUsingAppearanceFromNotecard() { TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); @@ -90,7 +90,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId); sp.Appearance.AvatarHeight = newHeight; - SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId); + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10); SceneObjectPart part = so.RootPart; m_scene.AddSceneObject(so); @@ -114,10 +114,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests /// Test creation of an NPC where the appearance data comes from an avatar already in the region. /// [Test] - public void TestOsNpcCreateFromAvatar() + public void TestOsNpcCreateUsingAppearanceFromAvatar() { TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); +// TestHelpers.EnableLogging(); // Store an avatar with a different height from default in a notecard. UUID userId = TestHelpers.ParseTail(0x1); @@ -125,7 +125,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId); sp.Appearance.AvatarHeight = newHeight; - SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId); + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10); SceneObjectPart part = so.RootPart; m_scene.AddSceneObject(so); @@ -156,7 +156,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId); sp.Appearance.AvatarHeight = newHeight; - SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId); + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10); SceneObjectPart part = so.RootPart; m_scene.AddSceneObject(so); @@ -197,7 +197,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, nonOwnerId); sp.Appearance.AvatarHeight = newHeight; - SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, ownerId); + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, ownerId, 0x10); SceneObjectPart part = so.RootPart; m_scene.AddSceneObject(so); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs index 813e53b..25679a6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs @@ -97,11 +97,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId); sp.Appearance.AvatarHeight = newHeight; - SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId); + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10); SceneObjectPart part = so.RootPart; m_scene.AddSceneObject(so); - SceneObjectGroup otherSo = SceneHelpers.CreateSceneObject(1, otherUserId); + SceneObjectGroup otherSo = SceneHelpers.CreateSceneObject(1, otherUserId, 0x20); SceneObjectPart otherPart = otherSo.RootPart; m_scene.AddSceneObject(otherSo); @@ -148,7 +148,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId); sp.Appearance.AvatarHeight = newHeight; - SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId); + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10); SceneObjectPart part = so.RootPart; m_scene.AddSceneObject(so); diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index 3a2e420..d5354cb 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs @@ -601,19 +601,36 @@ namespace OpenSim.Tests.Common ownerId, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero) { Name = name, UUID = id, Scale = new Vector3(1, 1, 1) }; } - + /// /// Create a scene object but do not add it to the scene. /// /// - /// UUID always starts at 00000000-0000-0000-0000-000000000001 + /// UUID always starts at 00000000-0000-0000-0000-000000000001. For some purposes, (e.g. serializing direct + /// to another object's inventory) we do not need a scene unique ID. So it would be better to add the + /// UUID when we actually add an object to a scene rather than on creation. /// /// The number of parts that should be in the scene object /// /// public static SceneObjectGroup CreateSceneObject(int parts, UUID ownerId) { - return CreateSceneObject(parts, ownerId, "", 0x1); + return CreateSceneObject(parts, ownerId, 0x1); + } + + /// + /// Create a scene object but do not add it to the scene. + /// + /// The number of parts that should be in the scene object + /// + /// + /// The hexadecimal last part of the UUID for parts created. A UUID of the form "00000000-0000-0000-0000-{0:XD12}" + /// will be given to the root part, and incremented for each part thereafter. + /// + /// + public static SceneObjectGroup CreateSceneObject(int parts, UUID ownerId, int uuidTail) + { + return CreateSceneObject(parts, ownerId, "", uuidTail); } /// -- cgit v1.1 From 3bd134474bead7c211b84413275a6bdcc7dc7dea Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 7 Jul 2012 00:09:12 +0100 Subject: minor: Get RegionReady module to shout initialization complete status to draw the eye --- .../OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs index 0b9f875..db2cbeb 100644 --- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs @@ -228,7 +228,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady // m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}", // m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString()); - m_log.InfoFormat("[RegionReady]: Initialization complete - logins enabled for {0}", m_scene.RegionInfo.RegionName); + m_log.InfoFormat( + "[RegionReady]: INITIALIZATION COMPLETE - LOGINS ENABLED FOR {0}", + m_scene.RegionInfo.RegionName); if ( m_uri != string.Empty ) { -- cgit v1.1 From a85741ac37ef04e5c33e8aa30113cccd0291962f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 7 Jul 2012 00:14:16 +0100 Subject: minor: Make WORLD MAP category log lines consistent --- OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index c1c6b49..724533b 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -730,7 +730,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap { if (Environment.TickCount > (m_blacklistedregions[regionhandle] + blacklistTimeout)) { - m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted region {0}", regionhandle); + m_log.DebugFormat("[WORLD MAP]: Unblock blacklisted region {0}", regionhandle); m_blacklistedregions.Remove(regionhandle); } @@ -781,7 +781,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap { if (Environment.TickCount > (m_blacklistedurls[httpserver] + blacklistTimeout)) { - m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted URL {0}", httpserver); + m_log.DebugFormat("[WORLD MAP]: Unblock blacklisted URL {0}", httpserver); m_blacklistedurls.Remove(httpserver); } @@ -1343,7 +1343,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap if (terrain == null) return; - m_log.DebugFormat("[WORLDMAP]: Generating map image for {0}", m_scene.RegionInfo.RegionName); + m_log.DebugFormat("[WORLD MAP]: Generating map image for {0}", m_scene.RegionInfo.RegionName); byte[] data = terrain.WriteJpeg2000Image(); if (data == null) @@ -1365,7 +1365,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap asset.Flags = AssetFlags.Maptile; // Store the new one - m_log.DebugFormat("[WORLDMAP]: Storing map tile {0} for {1}", asset.ID, m_scene.RegionInfo.RegionName); + m_log.DebugFormat("[WORLD MAP]: Storing map tile {0} for {1}", asset.ID, m_scene.RegionInfo.RegionName); m_scene.AssetService.Store(asset); -- cgit v1.1 From 1201307c73da77f6f3f0725ce8c985af179f54bd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 7 Jul 2012 00:26:25 +0100 Subject: Remove duplicate Warp3DImageModule entry in CoreModulePlugin.addin.xml This was causing 2 copies of the module to be created for each scene. Probably no bad consequences other than a small waste of memory (both for the module and for the warp3D renderer it loaded) --- OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml index dc6efed..424e0ab 100644 --- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml +++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml @@ -79,7 +79,6 @@ \ \ - \ -- cgit v1.1 From 16d5b79d57602b6c28e958c98de18e18927fa7a3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 7 Jul 2012 00:36:01 +0100 Subject: minor: remove some recent mono compiler warnings --- OpenSim/Data/Tests/RegionTests.cs | 2 -- OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs index 55b9b4d..dbed8f6 100644 --- a/OpenSim/Data/Tests/RegionTests.cs +++ b/OpenSim/Data/Tests/RegionTests.cs @@ -1069,8 +1069,6 @@ namespace OpenSim.Data.Tests regionInfo.RegionLocX = 0; regionInfo.RegionLocY = 0; - Scene scene = new Scene(regionInfo); - SceneObjectPart sop = new SceneObjectPart(); sop.Name = name; sop.Description = name; diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs index 537b8aa..78db2c6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs @@ -158,7 +158,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests { osslApi.osForceAttachToAvatarFromInventory(taskInvObjItemName, (int)attachPoint); } - catch (Exception e) + catch (Exception) { exceptionCaught = true; } -- cgit v1.1 From 112cddc9ca839579cc2710df5e2ea0906110dd8e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 7 Jul 2012 00:53:17 +0100 Subject: minor: rearrange INITIALIZATION COMPLETE log message so that it's clear init is only complete for a particular region at a time --- .../OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs index db2cbeb..600cafb 100644 --- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs @@ -229,10 +229,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady // m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString()); m_log.InfoFormat( - "[RegionReady]: INITIALIZATION COMPLETE - LOGINS ENABLED FOR {0}", - m_scene.RegionInfo.RegionName); + "[RegionReady]: INITIALIZATION COMPLETE FOR {0} - LOGINS ENABLED", m_scene.Name); - if ( m_uri != string.Empty ) + if (m_uri != string.Empty) { RRAlert("enabled"); } -- cgit v1.1 From 57094bd0177e656ce1ed08df87b19657a6043c68 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Sun, 8 Jul 2012 13:02:02 -0400 Subject: Add more automation keys to OpenSim.ini.example --- bin/OpenSim.ini.example | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index c07e1ab..ce571ee 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -61,17 +61,20 @@ ;; Place to create a PID file ; PIDFile = "/tmp/my.pid" + ;# {region_info_source} {} {Where to load region from?} {filesystem web} filesystem ;; Determine where OpenSimulator looks for the files which tell it ;; which regions to server ;; Default is "filesystem" ; region_info_source = "filesystem" ; region_info_source = "web" - + + ;# {regionload_regionsdir} {region_info_source} {Location of file?} {} Regions ;; Determines where the region XML files are stored if you are loading ;; these from the filesystem. ;; Defaults to bin/Regions in your OpenSimulator installation directory ; regionload_regionsdir="C:\somewhere\xmlfiles\" + ;# {regionload_webserver_url} {region_info_source} {URL to load region from?} {} ;; Determines the page from which regions xml is retrieved if you are ;; loading these from the web. ;; The XML here has the same format as it does on the filesystem @@ -92,6 +95,7 @@ ;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file. ; PhysicalPrimMax = 10 + ;# {ClampPrimSize} {} {Clamp viewer rezzed prims to max sizes?} {true false} false ;; If a viewer attempts to rez a prim larger than the non-physical or physical prim max, clamp the dimensions to the appropriate maximum ;; This can be overriden in the region config file. ; ClampPrimSize = false @@ -117,6 +121,7 @@ ;; This will likely break them ; CombineContiguousRegions = false + ;# {InworldRestartShutsDown} {} {Shutdown instance on region restart?} {true false} false ;; If you have only one region in an instance, or to avoid the many bugs ;; that you can trigger in modules by restarting a region, set this to ;; true to make the entire instance exit instead of restarting the region. @@ -131,14 +136,17 @@ ;; If both of these values are set to zero then persistence of all changed ;; objects will happen on every sweep. + ;# {MinimumTimeBeforePersistenceConsidered} {} {Time before un-changed object may be persisted} {} 60 ;; Objects will be considered for persistance in the next sweep when they ;; have not changed for this number of seconds. ; MinimumTimeBeforePersistenceConsidered = 60 + ;# {MaximumTimeBeforePersistenceConsidered} {} {Time before changed objects may be persisted?} {} 600 ;; Objects will always be considered for persistance in the next sweep ;; if the first change occurred this number of seconds ago. ; MaximumTimeBeforePersistenceConsidered = 600 + ;# {see_into_this_sim_from_neighbor} {} {Should avatars in neighbor sims see objects in this sim?} {true false} true ;; Should avatars in neighbor sims see objects in this sim? ; see_into_this_sim_from_neighbor = true @@ -153,6 +161,7 @@ ;; Note that only the ODE physics engine currently deals with meshed ;; prims in a satisfactory way. + ;# {meshing} {} {Select mesher} {Meshmerizer ZeroMesher} Meshmerizer ;; ZeroMesher is faster but leaves the physics engine to model the mesh ;; using the basic shapes that it supports. ;; Usually this is only a box. @@ -161,6 +170,7 @@ ; meshing = ZeroMesher ;; Choose one of the physics engines below + ;# {physics} {} {Select physics engine} {OpenDynamicsEngine BulletSim basicphysics POS} OpenDynamicsEngine ;; OpenDynamicsEngine is by some distance the most developed physics engine ;; BulletSim is incomplete and experimental but in active development ;; basicphysics effectively does not model physics at all, making all objects phantom @@ -184,38 +194,52 @@ ;; If set to true, then all permissions checks are carried out ; serverside_object_permissions = true + ;# {allow_grid_gods} {} {Allow grid gods?} {true false} false ;; This allows users with a UserLevel of 200 or more to assume god ;; powers in the regions in this simulator. ; allow_grid_gods = false ;; This allows some control over permissions ;; please note that this still doesn't duplicate SL, and is not intended to + ;# {region_owner_is_god} {} {Allow region owner gods} {true false} true + ;; Allow region owners to assume god powers in their regions ; region_owner_is_god = true + + ;# {region_manager_is_god} {} {Allow region manager gods} {true false} false + ;; Allow region managers to assume god powers in regions they manage ; region_manager_is_god = false + + ;# {parcel_owner_is_god} {} {Allow parcel owner gods} {true false} true + ;; Allow parcel owners to assume god powers in their parcels ; parcel_owner_is_god = true + ;# {simple_build_permissions} {} {Allow building in parcel by access list (no groups)} {true false} false ;; More control over permissions ;; This is definitely not SL! - ; Provides a simple control for land owners to give build rights to specific avatars - ; in publicly accessible parcels that disallow object creation in general. - ; Owners specific avatars by adding them to the Access List of the parcel - ; without having to use the Groups feature + ;; Provides a simple control for land owners to give build rights to specific avatars + ;; in publicly accessible parcels that disallow object creation in general. + ;; Owners specific avatars by adding them to the Access List of the parcel + ;; without having to use the Groups feature ; simple_build_permissions = false + ;# {DefaultScriptEngine} {} {Default script engine} {XEngine} XEngine ;; Default script engine to use. Currently, we only have XEngine ; DefaultScriptEngine = "XEngine" + ;# {GenerateMaptiles} {} {Generate map tiles?} {true false} true ;; Map tile options. You can choose to generate no map tiles at all, ;; generate normal maptiles, or nominate an uploaded texture to ;; be the map tile ; GenerateMaptiles = true + ;# {MaptileRefresh} {GenerateMaptiles} {Maptile refresh period?} {} 0 ;; If desired, a running region can update the map tiles periodically ;; to reflect building activity. This names no sense of you don't have ;; prims on maptiles. Value is in seconds. ; MaptileRefresh = 0 + ;# {MaptileStaticUUID} {} {Asset ID for static map texture} {} 00000000-0000-0000-0000-000000000000 ;; If not generating maptiles, use this static texture asset ID ; MaptileStaticUUID = "00000000-0000-0000-0000-000000000000" @@ -228,9 +252,11 @@ ;; got a large number of objects, so you can turn it off here if you'd like. ; DrawPrimOnMapTile = true + ;# {HttpProxy} {} {Proxy URL for llHTTPRequest and dynamic texture loading} {} http://proxy.com:8080 ;; Http proxy setting for llHTTPRequest and dynamic texture loading, if required ; HttpProxy = "http://proxy.com:8080" + ;# {HttpProxyExceptions} {HttpProxy} {Set of regular expressions defining URL that should not be proxied} {} ;; If you're using HttpProxy, then you can set HttpProxyExceptions to a list of regular expressions for URLs that you don't want to go through the proxy ;; For example, servers inside your firewall. ;; Separate patterns with a ';' @@ -254,7 +280,8 @@ ;; default is false ; TelehubAllowLandmark = false - ;# Comma separated list of viewers which may gain access to the regions. + ;# {AllowedViewerList} {} {Comma separated list of allowed viewers} {} + ;; Comma separated list of viewers which may gain access to the regions. ;; One can use a Substring of the viewer name to enable only certain subversions ;; Example: Agent uses the viewer "Imprudence 1.3.2.0" ;; - "Imprudence" has access @@ -262,6 +289,7 @@ ;; - "Imprudence 1.3.1" has no access ;; AllowedViewerList = + ;# {BannedViewerList} {} {Comma separated list of banned viewers} {} ;# Comma separated list of viewers which may not gain access to the regions. ;; One can use a Substring of the viewer name to disable only certain subversions ;; Example: Agent uses the viewer "Imprudence 1.3.2.0" -- cgit v1.1 From a96ac7330291c3041729fac08b06d0098469f4d7 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Sun, 8 Jul 2012 13:44:04 -0400 Subject: Add more keys for OpenSim.ini.defaults automation --- bin/OpenSim.ini.example | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index ce571ee..661abc0 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -304,16 +304,30 @@ ; If these values are uncommented then they will be used to create a default estate as necessary. ; New regions will be automatically assigned to that default estate. + ;# {DefaultEstateName} {} {Default name for estate?} {} My Estate + ;; Name for the default estate ; DefaultEstateName = My Estate + + ;# {DefaultEstateOwnerName} {} {Default estate owner name?} {} FirstName LastName + ;; Name for default estate owner ; DefaultEstateOwnerName = FirstName LastName - - ; The following parameters will only be used on a standalone system to create an estate owner that does not already exist - ; If DefaultEstateOwnerUUID is left at UUID.Zero (as below) then a random UUID will be assigned. - ; This is normally what you want + + ; ** Standalone Estate Settings ** + ; The following parameters will only be used on a standalone system to + ; create an estate owner that does not already exist + + ;# {DefaultEstateOwnerUUID} {} {Default estate owner UUID?} {} 00000000-0000-0000-0000-000000000000 + ;; If DefaultEstateOwnerUUID is left at UUID.Zero (as below) then a random + ;; UUID will be assigned. This is normally what you want ; DefaultEstateOwnerUUID = 00000000-0000-0000-0000-000000000000 + ;# {DefaultEstateOwnerEMail} {} {Default estate owner email?} {} + ;; Email address for the default estate owner ; DefaultEstateOwnerEMail = owner@domain.com + + ;# {DefaultEstateOwnerPassword} {} {Default estate owner password} {} + ;; Password for the default estate owner ; DefaultEstateOwnerPassword = password -- cgit v1.1 From 1a2ab7bc691192f4a263d3d57e2d83bb05f8c69c Mon Sep 17 00:00:00 2001 From: BlueWall Date: Sun, 8 Jul 2012 22:49:36 -0400 Subject: More keys for automated ini processing --- bin/OpenSim.ini.example | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 661abc0..33eaccb 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -364,10 +364,14 @@ ; SMTP_SERVER_PASSWORD = "" [Network] + + ;# {ConsoleUser} {} {User name for console account} {} ;; Configure the remote console user here. This will not actually be used ;; unless you use -console=rest at startup. ; ConsoleUser = "Test" + ;# {ConsolePass} {} {Password for console account} {} ; ConsolePass = "secret" + ;# {console_port} {} {Port for console connections} {} 0 ; console_port = 0 ;# {http_listener_port} {} {TCP Port for this simulator to listen on? (This must be unique to the simulator!)} {} 9000 @@ -431,11 +435,14 @@ [SimulatorFeatures] + + ;# {MapImageServerURI} {} {URL for the map server} {} ; Experimental new information sent in SimulatorFeatures cap for Kokua viewers ; meant to override the MapImage and search server url given at login, and varying ; on a sim-basis. ; Viewers that don't understand it, will ignore it ;MapImageServerURI = "http://127.0.0.1:9000/" + ;# {SearchServerURI} {} {URL of the search server} {} ;SearchServerURI = "http://127.0.0.1:9000/" @@ -629,6 +636,7 @@ [Economy] + ;# {SellEnabled} {} {Enable selling for 0?} {true false} true ; The default economy module only implements just enough to allow free actions (transfer of objects, etc). ; There is no intention to implement anything further in core OpenSimulator. ; This functionality has to be provided by third party modules. @@ -636,9 +644,11 @@ ;; Enables selling things for $0. Default is true. ; SellEnabled = true + ;# {PriceUpload} {} {Price for uploading?} {} 0 ;; Money Unit fee to upload textures, animations etc. Default is 0. ; PriceUpload = 0 + ;# {PriceGroupCreate} {} {Fee for group creation} {} 0 ;; Money Unit fee to create groups. Default is 0. ; PriceGroupCreate = 0 @@ -748,32 +758,41 @@ ; If both Allow_ and Creators_ are given, effective permissions ; are the union of the two. + ;# {EventLimit} {} {Amount of time a script can spend in an event handler} {} 30 ;; Time a script can spend in an event handler before it is interrupted ; EventLimit = 30 + ;# {KillTimedOutScripts} {} {Kill script in case of event time overruns?} {true false} false ;; If a script overruns it's event limit, kill the script? ; KillTimedOutScripts = false + ;# {ScriptDelayFactor} {} {Multiplier for scripting delays} {} 1.0 ;; Sets the multiplier for the scripting delays ; ScriptDelayFactor = 1.0 + ;# {ScriptDistanceLimitFactor} {} {Multiplier for 10.0m distance limits?} {} ;; The factor the 10 m distances limits are multiplied by ; ScriptDistanceLimitFactor = 1.0 + ;# {NotecardLineReadCharsMax} {} {Maximum length of notecard line?} {} 255 ;; Maximum length of notecard line read ;; Increasing this to large values potentially opens ;; up the system to malicious scripters ; NotecardLineReadCharsMax = 255 + ;# {SensorMaxRange} {} {Sensor range} {} 96.0 ;; Sensor settings ; SensorMaxRange = 96.0 + ;# {SensorMaxResults} {} {Max sensor results returned?} {} ; SensorMaxResults = 16 + ;# {DisableUndergroundMovement} {} {Disable underground movement of prims} {true false} true ;; Disable underground movement of prims (default true); set to ;; false to allow script controlled underground positioning of ;; prims ; DisableUndergroundMovement = true + ;# {ScriptEnginesPath} {} {Path to script assemblies} {} ScriptEngines ;; Path to script engine assemblies ;; Default is ./bin/ScriptEngines ; ScriptEnginesPath = "ScriptEngines" -- cgit v1.1 From 2eaa6d5ace738cf1848f82ce7a0b435928b6846f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 9 Jul 2012 21:24:32 +0100 Subject: Do not allow a script to attach a prim if its being sat upon. This prevents a stack overflow where a get position on the avatar will refer to the attachment which will in turn refer back to the avatar. This required recording of all sitting avatars on a prim which is done separately from recording the sit target avatar. Recording HashSet is null if there are no sitting avatars in order to save memory. --- .../Avatar/Attachments/AttachmentsModule.cs | 9 ++ .../Attachments/Tests/AttachmentsModuleTests.cs | 32 ++++++- .../Region/Framework/Scenes/SceneObjectGroup.cs | 14 ++++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 98 ++++++++++++++++++++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 18 +++- OpenSim/Tests/Common/Helpers/SceneHelpers.cs | 75 +++++++++++++---- OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs | 9 ++ 7 files changed, 229 insertions(+), 26 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 9eb0e38..eccf7a6 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -251,6 +251,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", // group.Name, group.LocalId, sp.Name, attachmentPt, silent); + + if (group.GetSittingAvatarsCount() != 0) + { +// m_log.WarnFormat( +// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it", +// group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount()); + + return false; + } if (sp.GetAttachments(attachmentPt).Contains(group)) { diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 5dcbd28..3e06900 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -118,7 +118,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Scene scene = CreateDefaultTestScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); - ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); string attName = "att"; @@ -154,6 +154,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // TestHelpers.DisableLogging(); } + /// + /// Test that we do not attempt to attach an in-world object that someone else is sitting on. + /// + [Test] + public void TestAddSatOnAttachmentFromGround() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + Scene scene = CreateDefaultTestScene(); + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); + + string attName = "att"; + + SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); + + UserAccount ua2 = UserAccountHelpers.CreateUserWithInventory(scene, 0x2); + ScenePresence sp2 = SceneHelpers.AddScenePresence(scene, ua2); + + // Put avatar within 10m of the prim so that sit doesn't fail. + sp2.AbsolutePosition = new Vector3(0, 0, 0); + sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); + + scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false); + + Assert.That(sp.HasAttachments(), Is.False); + Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); + } + [Test] public void TestAddAttachmentFromInventory() { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 4e0e183..fc04761 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3401,6 +3401,20 @@ namespace OpenSim.Region.Framework.Scenes return count; } + /// + /// Gets the number of sitting avatars. + /// + /// This applies to all sitting avatars whether there is a sit target set or not. + /// + public int GetSittingAvatarsCount() + { + int count = 0; + + Array.ForEach(m_parts.GetArray(), p => count += p.GetSittingAvatarsCount()); + + return count; + } + public override string ToString() { return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 3d81358..6518b84 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -374,7 +374,6 @@ namespace OpenSim.Region.Framework.Scenes private uint _category; private Int32 _creationDate; private uint _parentID = 0; - private UUID m_sitTargetAvatar = UUID.Zero; private uint _baseMask = (uint)PermissionMask.All; private uint _ownerMask = (uint)PermissionMask.All; private uint _groupMask = (uint)PermissionMask.None; @@ -1233,13 +1232,20 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero + /// ID of the avatar that is sat on us if we have a sit target. If there is no such avatar then is UUID.Zero /// - public UUID SitTargetAvatar - { - get { return m_sitTargetAvatar; } - set { m_sitTargetAvatar = value; } - } + public UUID SitTargetAvatar { get; set; } + + /// + /// IDs of all avatars start on this object part. + /// + /// + /// We need to track this so that we can stop sat upon prims from being attached. + /// + /// + /// null if there are no sitting avatars. This is to save us create a hashset for every prim in a scene. + /// + private HashSet m_sittingAvatars; public virtual UUID RegionID { @@ -4493,5 +4499,83 @@ namespace OpenSim.Region.Framework.Scenes Color color = Color; return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); } + + /// + /// Record an avatar sitting on this part. + /// + /// This is called for all the sitting avatars whether there is a sit target set or not. + /// + /// true if the avatar was not already recorded, false otherwise. + /// + /// + protected internal bool AddSittingAvatar(UUID avatarId) + { + HashSet sittingAvatars = m_sittingAvatars; + + if (sittingAvatars == null) + sittingAvatars = new HashSet(); + + lock (sittingAvatars) + { + m_sittingAvatars = sittingAvatars; + return m_sittingAvatars.Add(avatarId); + } + } + + /// + /// Remove an avatar recorded as sitting on this part. + /// + /// This applies to all sitting avatars whether there is a sit target set or not. + /// + /// true if the avatar was present and removed, false if it was not present. + /// + /// + protected internal bool RemoveSittingAvatar(UUID avatarId) + { + HashSet sittingAvatars = m_sittingAvatars; + + // This can occur under a race condition where another thread + if (sittingAvatars == null) + return false; + + lock (sittingAvatars) + { + if (sittingAvatars.Remove(avatarId)) + { + if (sittingAvatars.Count == 0) + m_sittingAvatars = null; + + return true; + } + } + + return false; + } + + /// + /// Get a copy of the list of sitting avatars. + /// + /// This applies to all sitting avatars whether there is a sit target set or not. + /// + public HashSet GetSittingAvatars() + { + return new HashSet(m_sittingAvatars); + } + + /// + /// Gets the number of sitting avatars. + /// + /// This applies to all sitting avatars whether there is a sit target set or not. + /// + public int GetSittingAvatarsCount() + { + HashSet sittingAvatars = m_sittingAvatars; + + if (sittingAvatars == null) + return 0; + + lock (sittingAvatars) + return sittingAvatars.Count; + } } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c7a670f..c6a2a03 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -578,6 +578,12 @@ namespace OpenSim.Region.Framework.Scenes public uint ParentID { get; set; } /// + /// Are we sitting on an object? + /// + /// A more readable way of testing presence sit status than ParentID == 0 + public bool IsSatOnObject { get { return ParentID != 0; } } + + /// /// If the avatar is sitting, the prim that it's sitting on. If not sitting then null. /// /// @@ -1808,6 +1814,8 @@ namespace OpenSim.Region.Framework.Scenes SendAvatarDataToAllAgents(); m_requestedSitTargetID = 0; + part.RemoveSittingAvatar(UUID); + if (part != null) part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); } @@ -1887,7 +1895,7 @@ namespace OpenSim.Region.Framework.Scenes ) )); -// m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied); + m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied); if (PhysicsActor != null) m_sitAvatarHeight = PhysicsActor.Size.Z; @@ -1920,6 +1928,12 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); canSit = true; } +// else +// { +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m", +// Name, part.Name, part.LocalId); +// } } if (canSit) @@ -1930,6 +1944,8 @@ namespace OpenSim.Region.Framework.Scenes RemoveFromPhysicalScene(); } + part.AddSittingAvatar(UUID); + cameraAtOffset = part.GetCameraAtOffset(); cameraEyeOffset = part.GetCameraEyeOffset(); forceMouselook = part.GetForceMouselook(); diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index d5354cb..769de83 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs @@ -412,26 +412,49 @@ namespace OpenSim.Tests.Common /// public static AgentCircuitData GenerateAgentData(UUID agentId) { - string firstName = "testfirstname"; + AgentCircuitData acd = GenerateCommonAgentData(); - AgentCircuitData agentData = new AgentCircuitData(); - agentData.AgentID = agentId; - agentData.firstname = firstName; - agentData.lastname = "testlastname"; + acd.AgentID = agentId; + acd.firstname = "testfirstname"; + acd.lastname = "testlastname"; + acd.ServiceURLs = new Dictionary(); + + return acd; + } + + /// + /// Generate some standard agent connection data. + /// + /// + /// + public static AgentCircuitData GenerateAgentData(UserAccount ua) + { + AgentCircuitData acd = GenerateCommonAgentData(); + + acd.AgentID = ua.PrincipalID; + acd.firstname = ua.FirstName; + acd.lastname = ua.LastName; + acd.ServiceURLs = ua.ServiceURLs; + + return acd; + } + + private static AgentCircuitData GenerateCommonAgentData() + { + AgentCircuitData acd = new AgentCircuitData(); // XXX: Sessions must be unique, otherwise one presence can overwrite another in NullPresenceData. - agentData.SessionID = UUID.Random(); - agentData.SecureSessionID = UUID.Random(); - - agentData.circuitcode = 123; - agentData.BaseFolder = UUID.Zero; - agentData.InventoryFolder = UUID.Zero; - agentData.startpos = Vector3.Zero; - agentData.CapsPath = "http://wibble.com"; - agentData.ServiceURLs = new Dictionary(); - agentData.Appearance = new AvatarAppearance(); - - return agentData; + acd.SessionID = UUID.Random(); + acd.SecureSessionID = UUID.Random(); + + acd.circuitcode = 123; + acd.BaseFolder = UUID.Zero; + acd.InventoryFolder = UUID.Zero; + acd.startpos = Vector3.Zero; + acd.CapsPath = "http://wibble.com"; + acd.Appearance = new AvatarAppearance(); + + return acd; } /// @@ -440,6 +463,9 @@ namespace OpenSim.Tests.Common /// /// This can be used for tests where there is only one region or where there are multiple non-neighbour regions /// and teleport doesn't take place. + /// + /// XXX: Use the version of this method that takes the UserAccount structure wherever possible - this will + /// make the agent circuit data (e.g. first, lastname) consistent with the user account data. /// /// /// @@ -452,6 +478,10 @@ namespace OpenSim.Tests.Common /// /// Add a root agent where the details of the agent connection (apart from the id) are unimportant for the test /// + /// + /// XXX: Use the version of this method that takes the UserAccount structure wherever possible - this will + /// make the agent circuit data (e.g. first, lastname) consistent with the user account data. + /// /// /// /// @@ -464,6 +494,17 @@ namespace OpenSim.Tests.Common /// /// Add a root agent. /// + /// + /// + /// + public static ScenePresence AddScenePresence(Scene scene, UserAccount ua) + { + return AddScenePresence(scene, GenerateAgentData(ua)); + } + + /// + /// Add a root agent. + /// /// /// This function /// diff --git a/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs b/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs index 3d3e65c..2fbebc4 100644 --- a/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs @@ -138,6 +138,15 @@ namespace OpenSim.Tests.Common CreateUserWithInventory(scene, ua, pw); return ua; } + + public static UserAccount CreateUserWithInventory( + Scene scene, string firstName, string lastName, int userId, string pw) + { + UserAccount ua + = new UserAccount(TestHelpers.ParseTail(userId)) { FirstName = firstName, LastName = lastName }; + CreateUserWithInventory(scene, ua, pw); + return ua; + } public static void CreateUserWithInventory(Scene scene, UserAccount ua, string pw) { -- cgit v1.1 From d6f563794efb857210f4c773ef5218855c9a4ea4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 9 Jul 2012 21:43:44 +0100 Subject: Don't allow a prim to be sat upon if its part of an attachment --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c6a2a03..51ca9bd 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2219,6 +2219,15 @@ namespace OpenSim.Region.Framework.Scenes if (part != null) { + if (part.ParentGroup.IsAttachment) + { + m_log.WarnFormat( + "[SCENE PRESENCE]: Avatar {0} tried to sit on part {1} from object {2} in {3} but this is an attachment for avatar id {4}", + Name, part.Name, part.ParentGroup.Name, Scene.Name, part.ParentGroup.AttachedAvatar); + + return; + } + if (part.SitTargetAvatar == UUID) { Vector3 sitTargetPos = part.SitTargetPosition; -- cgit v1.1 From c8af20f966e005fb512869299d80be6b83cb70bf Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 9 Jul 2012 23:08:41 +0100 Subject: This script allows an object to be attached directly from prim inventory to another avatar in the scene. Very useful in serious game/environment scenarios where its only allowed for trusted creators. Threat level Severe --- .../Shared/Api/Implementation/OSSL_Api.cs | 25 ++++++++-- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 18 +++++++- .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 5 ++ .../Shared/Tests/OSSL_ApiAttachmentTests.cs | 53 ++++++++++++++++++++++ 4 files changed, 96 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 61394af..e90f577 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -3190,13 +3190,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatarFromInventory"); + m_host.AddScriptLPS(1); + + ForceAttachToAvatarFromInventory(m_host.OwnerID, itemName, attachmentPoint); + } + + public void osForceAttachToOtherAvatarFromInventory(string rawAvatarId, string itemName, int attachmentPoint) + { + CheckThreatLevel(ThreatLevel.Severe, "osForceAttachToOtherAvatarFromInventory"); + + m_host.AddScriptLPS(1); + + UUID avatarId; + + if (!UUID.TryParse(rawAvatarId, out avatarId)) + return; + + ForceAttachToAvatarFromInventory(avatarId, itemName, attachmentPoint); + } + + public void ForceAttachToAvatarFromInventory(UUID avatarId, string itemName, int attachmentPoint) + { IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; if (attachmentsModule == null) return; - m_host.AddScriptLPS(1); - InitLSL(); TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); @@ -3219,7 +3238,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; } - ScenePresence sp = World.GetScenePresence(m_host.OwnerID); + ScenePresence sp = World.GetScenePresence(avatarId); if (sp == null) return; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index d38709e..b5416c8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -101,19 +101,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces // Attachment commands /// - /// Attach the object containing this script to the avatar that owns it without checking for PERMISSION_ATTACH + /// Attach the object containing this script to the avatar that owns it without asking for PERMISSION_ATTACH /// /// The attachment point. For example, ATTACH_CHEST void osForceAttachToAvatar(int attachment); /// - /// Attach the inventory item in the object containing this script to the avatar that owns it without checking for PERMISSION_ATTACH + /// Attach an inventory item in the object containing this script to the avatar that owns it without asking for PERMISSION_ATTACH /// + /// + /// Nothing happens if the owner is not in the region. + /// /// Tha name of the item. If this is not found then a warning is said to the owner /// The attachment point. For example, ATTACH_CHEST void osForceAttachToAvatarFromInventory(string itemName, int attachment); /// + /// Attach an inventory item in the object containing this script to any avatar in the region without asking for PERMISSION_ATTACH + /// + /// + /// Nothing happens if the avatar is not in the region. + /// + /// The UUID of the avatar to which to attach. Nothing happens if this is not a UUID + /// The name of the item. If this is not found then a warning is said to the owner + /// The attachment point. For example, ATTACH_CHEST + void osForceAttachToOtherAvatarFromInventory(string rawAvatarId, string itemName, int attachmentPoint); + + /// /// Detach the object containing this script from the avatar it is attached to without checking for PERMISSION_ATTACH /// /// Nothing happens if the object is not attached. diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 692bb0a..b40bdf0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -301,6 +301,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osForceAttachToAvatarFromInventory(itemName, attachmentPoint); } + public void osForceAttachToOtherAvatarFromInventory(string rawAvatarId, string itemName, int attachmentPoint) + { + m_OSSL_Functions.osForceAttachToOtherAvatarFromInventory(rawAvatarId, itemName, attachmentPoint); + } + public void osForceDetachFromAvatar() { m_OSSL_Functions.osForceDetachFromAvatar(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs index 78db2c6..f5aa518 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs @@ -174,5 +174,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests List attachmentsInAppearance = sp.Appearance.GetAttachments(); Assert.That(attachmentsInAppearance.Count, Is.EqualTo(0)); } + + [Test] + public void TestOsForceAttachToOtherAvatarFromInventory() + { + TestHelpers.InMethod(); + TestHelpers.EnableLogging(); + + string taskInvObjItemName = "sphere"; + UUID taskInvObjItemId = UUID.Parse("00000000-0000-0000-0000-100000000000"); + AttachmentPoint attachPoint = AttachmentPoint.Chin; + + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(m_scene, "user", "one", 0x1, "pass"); + UserAccount ua2 = UserAccountHelpers.CreateUserWithInventory(m_scene, "user", "two", 0x2, "pass"); + + ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, ua1); + SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); + TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); + + new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem); + OSSL_Api osslApi = new OSSL_Api(); + osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem); + + // Create an object embedded inside the first + TaskInventoryHelpers.AddSceneObject(m_scene, inWorldObj.RootPart, taskInvObjItemName, taskInvObjItemId, ua1.PrincipalID); + + ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, ua2); + + osslApi.osForceAttachToOtherAvatarFromInventory(sp2.UUID.ToString(), taskInvObjItemName, (int)attachPoint); + + // Check scene presence status + Assert.That(sp.HasAttachments(), Is.False); + List attachments = sp.GetAttachments(); + Assert.That(attachments.Count, Is.EqualTo(0)); + + Assert.That(sp2.HasAttachments(), Is.True); + List attachments2 = sp2.GetAttachments(); + Assert.That(attachments2.Count, Is.EqualTo(1)); + SceneObjectGroup attSo = attachments2[0]; + Assert.That(attSo.Name, Is.EqualTo(taskInvObjItemName)); + Assert.That(attSo.OwnerID, Is.EqualTo(ua2.PrincipalID)); + Assert.That(attSo.AttachmentPoint, Is.EqualTo((uint)attachPoint)); + Assert.That(attSo.IsAttachment); + Assert.That(attSo.UsesPhysics, Is.False); + Assert.That(attSo.IsTemporary, Is.False); + + // Check appearance status + List attachmentsInAppearance = sp.Appearance.GetAttachments(); + Assert.That(attachmentsInAppearance.Count, Is.EqualTo(0)); + + List attachmentsInAppearance2 = sp2.Appearance.GetAttachments(); + Assert.That(attachmentsInAppearance2.Count, Is.EqualTo(1)); + Assert.That(sp2.Appearance.GetAttachpoint(attachmentsInAppearance2[0].ItemID), Is.EqualTo((uint)attachPoint)); + } } } \ No newline at end of file -- cgit v1.1 From eb5ec4a78698a3b1fd6d581c800ac985d5d946fa Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 10 Jul 2012 21:42:51 +0100 Subject: If a script is being stopped manually, then give the scriptpool thread 1 second to finish normally before forcibly aborting. This is to avoid the worst of the problems in mono 2.6, 2.10 where an aborted thread does not always release all its locks. This very short grace period is identical to the existing behaviour when a script is removed from the scene. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 7f3bd76..efcae94 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1574,7 +1574,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine { IScriptInstance instance = GetInstance(itemID); if (instance != null) - instance.Stop(0); + { + // Give the script some time to finish processing its last event. Simply aborting the script thread can + // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort. + instance.Stop(1000); + } } public DetectParams GetDetectParams(UUID itemID, int idx) -- cgit v1.1 From f3134b5cf688af9b824880e0221072b24d22f33e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 10 Jul 2012 22:41:11 +0100 Subject: When an attachment is detached to inv or derezzed, stop the scripts, update the known item with script state still in the script engine and then remove the scripts. This is to fix a regression starting from 5301648 where attachments had to start being deleted before persistence in order to avoid race conditions with hud update threads. --- .../Avatar/Attachments/AttachmentsModule.cs | 20 +++++--- .../Framework/Interfaces/IEntityInventory.cs | 15 +++++- OpenSim/Region/Framework/Scenes/Scene.cs | 19 ++++++- .../Framework/Scenes/SceneObjectGroup.Inventory.cs | 10 +++- .../Framework/Scenes/SceneObjectPartInventory.cs | 59 ++++++++++++++++++++-- 5 files changed, 110 insertions(+), 13 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index eccf7a6..efab6ed 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -211,16 +211,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments lock (sp.AttachmentsSyncLock) { - foreach (SceneObjectGroup grp in sp.GetAttachments()) + foreach (SceneObjectGroup so in sp.GetAttachments()) { - grp.Scene.DeleteSceneObject(grp, false); + // We can only remove the script instances from the script engine after we've retrieved their xml state + // when we update the attachment item. + m_scene.DeleteSceneObject(so, false, false); if (saveChanged || saveAllScripted) { - grp.IsAttachment = false; - grp.AbsolutePosition = grp.RootPart.AttachedPos; - UpdateKnownItem(sp, grp, saveAllScripted); + so.IsAttachment = false; + so.AbsolutePosition = so.RootPart.AttachedPos; + UpdateKnownItem(sp, so, saveAllScripted); } + + so.RemoveScriptInstances(true); } sp.ClearAttachments(); @@ -682,7 +686,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero); sp.RemoveAttachment(so); - m_scene.DeleteSceneObject(so, false); + + // We can only remove the script instances from the script engine after we've retrieved their xml state + // when we update the attachment item. + m_scene.DeleteSceneObject(so, false, false); // Prepare sog for storage so.AttachedAvatar = UUID.Zero; @@ -691,6 +698,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments so.AbsolutePosition = so.RootPart.AttachedPos; UpdateKnownItem(sp, so, true); + so.RemoveScriptInstances(true); } private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 1c9bdce..8d62847 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -92,7 +92,7 @@ namespace OpenSim.Region.Framework.Interfaces void ResumeScripts(); /// - /// Stop all the scripts in this entity. + /// Stop and remove all the scripts in this entity from the scene. /// /// /// Should be true if these scripts are being removed because the scene @@ -101,6 +101,11 @@ namespace OpenSim.Region.Framework.Interfaces void RemoveScriptInstances(bool sceneObjectBeingDeleted); /// + /// Stop all the scripts in this entity. + /// + void StopScriptInstances(); + + /// /// Start a script which is in this entity's inventory. /// /// @@ -129,7 +134,7 @@ namespace OpenSim.Region.Framework.Interfaces bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource); /// - /// Stop a script which is in this prim's inventory. + /// Stop and remove a script which is in this prim's inventory from the scene. /// /// /// @@ -139,6 +144,12 @@ namespace OpenSim.Region.Framework.Interfaces void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted); /// + /// Stop a script which is in this prim's inventory. + /// + /// + void StopScriptInstance(UUID itemId); + + /// /// Add an item to this entity's inventory. If an item with the same name already exists, then an alternative /// name is chosen. /// diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index ec911a5..25223b9 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2183,13 +2183,30 @@ namespace OpenSim.Region.Framework.Scenes /// /// Synchronously delete the given object from the scene. /// + /// + /// Scripts are also removed. + /// /// Object Id /// Suppress broadcasting changes to other clients. public void DeleteSceneObject(SceneObjectGroup group, bool silent) + { + DeleteSceneObject(group, silent, true); + } + + /// + /// Synchronously delete the given object from the scene. + /// + /// Object Id + /// Suppress broadcasting changes to other clients. + /// If true, then scripts are removed. If false, then they are only stopped. + public void DeleteSceneObject(SceneObjectGroup group, bool silent, bool removeScripts) { // m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID); - group.RemoveScriptInstances(true); + if (removeScripts) + group.RemoveScriptInstances(true); + else + group.StopScriptInstances(); SceneObjectPart[] partList = group.Parts; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 2866b54..ddf5da0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -79,7 +79,7 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Stop the scripts contained in all the prims in this group + /// Stop and remove the scripts contained in all the prims in this group /// /// /// Should be true if these scripts are being removed because the scene @@ -93,6 +93,14 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// Stop the scripts contained in all the prims in this group + /// + public void StopScriptInstances() + { + Array.ForEach(m_parts.GetArray(), p => p.Inventory.StopScriptInstances()); + } + + /// /// Add an inventory item from a user's inventory to a prim in this scene object. /// /// The agent adding the item. diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 866311a..cf2ed1a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -280,7 +280,7 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Stop all the scripts in this prim. + /// Stop and remove all the scripts in this prim. /// /// /// Should be true if these scripts are being removed because the scene @@ -294,6 +294,14 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// Stop all the scripts in this prim. + /// + public void StopScriptInstances() + { + GetInventoryItems(InventoryType.LSL).ForEach(i => StopScriptInstance(i)); + } + + /// /// Start a script which is in this prim's inventory. /// /// @@ -443,7 +451,7 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Stop a script which is in this prim's inventory. + /// Stop and remove a script which is in this prim's inventory. /// /// /// @@ -470,7 +478,36 @@ namespace OpenSim.Region.Framework.Scenes } else { - m_log.ErrorFormat( + m_log.WarnFormat( + "[PRIM INVENTORY]: " + + "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", + itemId, m_part.Name, m_part.UUID, + m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); + } + } + + /// + /// Stop a script which is in this prim's inventory. + /// + /// + /// + /// Should be true if this script is being removed because the scene + /// object is being deleted. This will prevent spurious updates to the client. + /// + public void StopScriptInstance(UUID itemId) + { + TaskInventoryItem scriptItem; + + lock (m_items) + m_items.TryGetValue(itemId, out scriptItem); + + if (scriptItem != null) + { + StopScriptInstance(scriptItem); + } + else + { + m_log.WarnFormat( "[PRIM INVENTORY]: " + "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", itemId, m_part.Name, m_part.UUID, @@ -479,6 +516,22 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// Stop a script which is in this prim's inventory. + /// + /// + /// + /// Should be true if this script is being removed because the scene + /// object is being deleted. This will prevent spurious updates to the client. + /// + public void StopScriptInstance(TaskInventoryItem item) + { + m_part.ParentGroup.Scene.EventManager.TriggerStopScript(m_part.LocalId, item.ItemID); + + // At the moment, even stopped scripts are counted as active, which is probably wrong. +// m_part.ParentGroup.AddActiveScriptCount(-1); + } + + /// /// Check if the inventory holds an item with a given name. /// /// -- cgit v1.1 From 58869e5aa09a292dc2159c73bada2c487151dda0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 10 Jul 2012 23:03:52 +0100 Subject: Fix recent SOP.GetSittingAvatars() to return null if there are no sitting avatars rather than throwing an exception. Extends sitting avatar regression tests to test new sitters information --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 14 +++++++++++-- .../Scenes/Tests/ScenePresenceSitTests.cs | 24 ++++++++++++++++++---- prebuild.xml | 1 + 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 6518b84..6677dae 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4556,10 +4556,20 @@ namespace OpenSim.Region.Framework.Scenes /// Get a copy of the list of sitting avatars. /// /// This applies to all sitting avatars whether there is a sit target set or not. - /// + /// A hashset of the sitting avatars. Returns null if there are no sitting avatars. public HashSet GetSittingAvatars() { - return new HashSet(m_sittingAvatars); + HashSet sittingAvatars = m_sittingAvatars; + + if (sittingAvatars == null) + { + return null; + } + else + { + lock (sittingAvatars) + return new HashSet(sittingAvatars); + } } /// diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs index ed39be1..493ab70 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs @@ -26,6 +26,7 @@ */ using System; +using System.Collections.Generic; using System.Reflection; using Nini.Config; using NUnit.Framework; @@ -69,6 +70,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); + Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0)); + Assert.That(part.GetSittingAvatars(), Is.Null); Assert.That(m_sp.ParentID, Is.EqualTo(0)); } @@ -86,7 +89,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); + Assert.That(m_sp.PhysicsActor, Is.Null); + Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); + Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1)); + HashSet sittingAvatars = part.GetSittingAvatars(); + Assert.That(sittingAvatars.Count, Is.EqualTo(1)); + Assert.That(sittingAvatars.Contains(m_sp.UUID)); Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId)); } @@ -104,10 +113,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); - Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); - Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId)); - Assert.That(m_sp.PhysicsActor, Is.Null); - // FIXME: This is different for live avatars - z position is adjusted. This is half the height of the // default avatar. // Curiously, Vector3.ToString() will not display the last two places of the float. For example, @@ -119,6 +124,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests m_sp.StandUp(); Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); + Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0)); + Assert.That(part.GetSittingAvatars(), Is.Null); Assert.That(m_sp.ParentID, Is.EqualTo(0)); Assert.That(m_sp.PhysicsActor, Is.Not.Null); } @@ -145,11 +152,20 @@ namespace OpenSim.Region.Framework.Scenes.Tests Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT)); Assert.That(m_sp.PhysicsActor, Is.Null); + Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1)); + HashSet sittingAvatars = part.GetSittingAvatars(); + Assert.That(sittingAvatars.Count, Is.EqualTo(1)); + Assert.That(sittingAvatars.Contains(m_sp.UUID)); + m_sp.StandUp(); Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); Assert.That(m_sp.ParentID, Is.EqualTo(0)); Assert.That(m_sp.PhysicsActor, Is.Not.Null); + + Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); + Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0)); + Assert.That(part.GetSittingAvatars(), Is.Null); } [Test] diff --git a/prebuild.xml b/prebuild.xml index 45f58c7..3419119 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -3042,6 +3042,7 @@ ../../../bin/ + -- cgit v1.1 From 9f01c3d4087266a8aa9a372a87ff78cae971d0c5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 10 Jul 2012 23:04:44 +0100 Subject: Disable logging in regression test in OSSL_ApiAttachmentTests --- OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs index f5aa518..5ed1f3d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs @@ -179,7 +179,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests public void TestOsForceAttachToOtherAvatarFromInventory() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); string taskInvObjItemName = "sphere"; UUID taskInvObjItemId = UUID.Parse("00000000-0000-0000-0000-100000000000"); -- cgit v1.1 From 506437b68449ab521f0ccf467ad642ad5e442d73 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 10 Jul 2012 23:06:34 +0100 Subject: Remove log line accidentally left in SP.SendSitResponse() --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 51ca9bd..c71bae9 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1895,7 +1895,7 @@ namespace OpenSim.Region.Framework.Scenes ) )); - m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied); +// m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied); if (PhysicsActor != null) m_sitAvatarHeight = PhysicsActor.Size.Z; -- cgit v1.1 From e8347b70957273421ee567577e2d9a6139af0621 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 10 Jul 2012 23:19:52 +0100 Subject: Move common code to detect whether a part has a valid sit target into a SOP property rather than being repeated in SP. This also makes the detection in SP.FindNextAvailableSitTarget() and SendSitResponse() identical. Previously they varied slightly (SendSitResponse didn't check for an older type of invalid quaternion) but the practical effect is most probably zero. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 15 ++++++++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 35 ++++------------------ 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 6677dae..dcec7e9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -135,6 +135,21 @@ namespace OpenSim.Region.Framework.Scenes get { return ParentGroup.RootPart == this; } } + /// + /// Is an explicit sit target set for this part? + /// + public bool IsSitTargetSet + { + get + { + return + !(SitTargetPosition == Vector3.Zero + && (SitTargetOrientation == Quaternion.Identity // Valid Zero Rotation quaternion + || SitTargetOrientation.X == 0f && SitTargetOrientation.Y == 0f && SitTargetOrientation.Z == 1f && SitTargetOrientation.W == 0f // W-Z Mapping was invalid at one point + || SitTargetOrientation.X == 0f && SitTargetOrientation.Y == 0f && SitTargetOrientation.Z == 0f && SitTargetOrientation.W == 0f)); // Invalid Quaternion + } + } + #region Fields public bool AllowedDrop; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c71bae9..c644ea5 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1846,15 +1846,7 @@ namespace OpenSim.Region.Framework.Scenes //look for prims with explicit sit targets that are available foreach (SceneObjectPart part in partArray) { - // Is a sit target available? - Vector3 avSitOffset = part.SitTargetPosition; - Quaternion avSitOrientation = part.SitTargetOrientation; - UUID avOnTargetAlready = part.SitTargetAvatar; - - bool SitTargetUnOccupied = avOnTargetAlready == UUID.Zero; - bool SitTargetisSet = avSitOffset != Vector3.Zero || avSitOrientation != Quaternion.Identity; - - if (SitTargetisSet && SitTargetUnOccupied) + if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) { //switch the target to this prim return part; @@ -1880,40 +1872,23 @@ namespace OpenSim.Region.Framework.Scenes // TODO: determine position to sit at based on scene geometry; don't trust offset from client // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it - // Is a sit target available? - Vector3 avSitOffSet = part.SitTargetPosition; - Quaternion avSitOrientation = part.SitTargetOrientation; - UUID avOnTargetAlready = part.SitTargetAvatar; - - bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); - bool SitTargetisSet = - (!(avSitOffSet == Vector3.Zero && - ( - avSitOrientation == Quaternion.Identity // Valid Zero Rotation quaternion - || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point - || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion - ) - )); - -// m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied); - if (PhysicsActor != null) m_sitAvatarHeight = PhysicsActor.Size.Z; bool canSit = false; pos = part.AbsolutePosition + offset; - if (SitTargetisSet) + if (part.IsSitTargetSet) { - if (SitTargetUnOccupied) + if (part.SitTargetAvatar == UUID.Zero) { // m_log.DebugFormat( // "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied", // Name, part.Name, part.LocalId); part.SitTargetAvatar = UUID; - offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); - sitOrientation = avSitOrientation; + offset = part.SitTargetPosition; + sitOrientation = part.SitTargetOrientation; canSit = true; } } -- cgit v1.1 From 69a6f6e3cd5cf1146a2d11d1393df0851c051e67 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 10 Jul 2012 23:26:40 +0100 Subject: refactor: use sit orientation argument passed in to SP.SendSitResponse() rather than creating a new copy There are no issues with side-effects since this is a struct. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c644ea5..a8c98ed 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1857,10 +1857,8 @@ namespace OpenSim.Region.Framework.Scenes return targetPart; } - private void SendSitResponse(UUID targetID, Vector3 offset, Quaternion pSitOrientation) + private void SendSitResponse(UUID targetID, Vector3 offset, Quaternion sitOrientation) { - Vector3 pos = new Vector3(); - Quaternion sitOrientation = pSitOrientation; Vector3 cameraEyeOffset = Vector3.Zero; Vector3 cameraAtOffset = Vector3.Zero; bool forceMouselook = false; @@ -1876,7 +1874,7 @@ namespace OpenSim.Region.Framework.Scenes m_sitAvatarHeight = PhysicsActor.Size.Z; bool canSit = false; - pos = part.AbsolutePosition + offset; + Vector3 pos = part.AbsolutePosition + offset; if (part.IsSitTargetSet) { -- cgit v1.1 From c8f0d476d2f775ba4d7afca12eeff527b46bb8e2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 10 Jul 2012 23:34:40 +0100 Subject: refactor: Add SOP.IsSitTargetOccupied to improve readability --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 7 ++++++- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index dcec7e9..937f43e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -136,6 +136,11 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// Is the sit target of this part occupied? + /// + public bool IsSitTargetOccupied { get { return SitTargetAvatar != UUID.Zero; } } + + /// /// Is an explicit sit target set for this part? /// public bool IsSitTargetSet @@ -736,7 +741,7 @@ namespace OpenSim.Region.Framework.Scenes } // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too - if (SitTargetAvatar != UUID.Zero) + if (IsSitTargetOccupied) { ScenePresence avatar; if (ParentGroup.Scene.TryGetScenePresence(SitTargetAvatar, out avatar)) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a8c98ed..c824e56 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1846,7 +1846,7 @@ namespace OpenSim.Region.Framework.Scenes //look for prims with explicit sit targets that are available foreach (SceneObjectPart part in partArray) { - if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) + if (part.IsSitTargetSet && !part.IsSitTargetOccupied) { //switch the target to this prim return part; @@ -1878,7 +1878,7 @@ namespace OpenSim.Region.Framework.Scenes if (part.IsSitTargetSet) { - if (part.SitTargetAvatar == UUID.Zero) + if (!part.IsSitTargetOccupied) { // m_log.DebugFormat( // "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied", -- cgit v1.1 From 11e0ad6dc8663756154652465750c1ebaaf3124f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 10 Jul 2012 23:39:05 +0100 Subject: Revert "refactor: Add SOP.IsSitTargetOccupied to improve readability" This reverts commit c8f0d476d2f775ba4d7afca12eeff527b46bb8e2. On reconsideration, I think this is less readable since immediately following code still sets SitTargetAvatar directly --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 7 +------ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 4 ++-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 937f43e..dcec7e9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -136,11 +136,6 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Is the sit target of this part occupied? - /// - public bool IsSitTargetOccupied { get { return SitTargetAvatar != UUID.Zero; } } - - /// /// Is an explicit sit target set for this part? /// public bool IsSitTargetSet @@ -741,7 +736,7 @@ namespace OpenSim.Region.Framework.Scenes } // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too - if (IsSitTargetOccupied) + if (SitTargetAvatar != UUID.Zero) { ScenePresence avatar; if (ParentGroup.Scene.TryGetScenePresence(SitTargetAvatar, out avatar)) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c824e56..a8c98ed 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1846,7 +1846,7 @@ namespace OpenSim.Region.Framework.Scenes //look for prims with explicit sit targets that are available foreach (SceneObjectPart part in partArray) { - if (part.IsSitTargetSet && !part.IsSitTargetOccupied) + if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) { //switch the target to this prim return part; @@ -1878,7 +1878,7 @@ namespace OpenSim.Region.Framework.Scenes if (part.IsSitTargetSet) { - if (!part.IsSitTargetOccupied) + if (part.SitTargetAvatar == UUID.Zero) { // m_log.DebugFormat( // "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied", -- cgit v1.1 From cdea572d2ea0256423a4cd72f132346d88a93e92 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 10 Jul 2012 23:50:04 +0100 Subject: refactor: move management of SOP.SitTargetAvatar into SOP.AddSittingAvatar() and SOP.RemoveSittingAvatar() --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 6 ++++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 5 ----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index dcec7e9..b3f11a7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4525,6 +4525,9 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal bool AddSittingAvatar(UUID avatarId) { + if (IsSitTargetSet && SitTargetAvatar == UUID.Zero) + SitTargetAvatar = avatarId; + HashSet sittingAvatars = m_sittingAvatars; if (sittingAvatars == null) @@ -4547,6 +4550,9 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal bool RemoveSittingAvatar(UUID avatarId) { + if (SitTargetAvatar == avatarId) + SitTargetAvatar = UUID.Zero; + HashSet sittingAvatars = m_sittingAvatars; // This can occur under a race condition where another thread diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a8c98ed..514c314 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1799,10 +1799,6 @@ namespace OpenSim.Region.Framework.Scenes } } - // Reset sit target. - if (part.SitTargetAvatar == UUID) - part.SitTargetAvatar = UUID.Zero; - ParentPosition = part.GetWorldPosition(); ControllingClient.SendClearFollowCamProperties(part.ParentUUID); @@ -1884,7 +1880,6 @@ namespace OpenSim.Region.Framework.Scenes // "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied", // Name, part.Name, part.LocalId); - part.SitTargetAvatar = UUID; offset = part.SitTargetPosition; sitOrientation = part.SitTargetOrientation; canSit = true; -- cgit v1.1 From 337ea019bd0fa617df00d7bee10b869e73a50075 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 10 Jul 2012 23:55:22 +0100 Subject: If a part has a sit target and an avatar is already sitting, allow another avatar to sit in the position given if no sit target was set. Previous behave was that the second avatar could not sit. This matches behaviour observed on the LL grid. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 514c314..0e7f2e5 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1872,18 +1872,15 @@ namespace OpenSim.Region.Framework.Scenes bool canSit = false; Vector3 pos = part.AbsolutePosition + offset; - if (part.IsSitTargetSet) + if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) { - if (part.SitTargetAvatar == UUID.Zero) - { // m_log.DebugFormat( // "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied", // Name, part.Name, part.LocalId); - offset = part.SitTargetPosition; - sitOrientation = part.SitTargetOrientation; - canSit = true; - } + offset = part.SitTargetPosition; + sitOrientation = part.SitTargetOrientation; + canSit = true; } else { -- cgit v1.1 From 14d05dc2a907fcb304e622ab85150049b43f4fd5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 11 Jul 2012 19:54:40 +0100 Subject: Add regression TestRezScriptedAttachmentsFromInventory() though this currently only checks for the presence of script items, not for started scripts --- .../Attachments/Tests/AttachmentsModuleTests.cs | 27 +++++++- .../Tests/Common/Helpers/TaskInventoryHelpers.cs | 3 +- .../Tests/Common/Helpers/UserInventoryHelpers.cs | 78 ++++++++++++++++------ 3 files changed, 85 insertions(+), 23 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 3e06900..416aa6f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -185,7 +185,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests } [Test] - public void TestAddAttachmentFromInventory() + public void TestRezAttachmentFromInventory() { TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); @@ -217,6 +217,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); } + /// + /// Test specific conditions associated with rezzing a scripted attachment from inventory. + /// + [Test] + public void TestRezScriptedAttachmentFromInventory() + { + TestHelpers.InMethod(); + + Scene scene = CreateDefaultTestScene(); + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); + + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10); + TaskInventoryHelpers.AddScript(scene, so.RootPart); + InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000); + + scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); + + // TODO: Need to have a test that checks the script is actually started but this involves a lot more + // plumbing of the script engine and either pausing for events or more infrastructure to turn off various + // script engine delays/asychronicity that isn't helpful in an automated regression testing context. + SceneObjectGroup attSo = scene.GetSceneObjectGroup(so.Name); + Assert.That(attSo.ContainsScripts(), Is.True); + } + [Test] public void TestDetachAttachmentToGround() { diff --git a/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs index 9607f1f..c4e29e2 100644 --- a/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs @@ -69,7 +69,7 @@ namespace OpenSim.Tests.Common } /// - /// Add a blank script to the given part. + /// Add a simple script to the given part. /// /// /// TODO: Accept input for item and asset IDs to avoid mysterious script failures that try to use any of these @@ -81,6 +81,7 @@ namespace OpenSim.Tests.Common public static TaskInventoryItem AddScript(Scene scene, SceneObjectPart part) { AssetScriptText ast = new AssetScriptText(); + ast.Source = "default { state_entry() {} }"; ast.Encode(); UUID assetUuid = new UUID("00000000-0000-0000-1000-000000000000"); diff --git a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs index fdc60d8..b3a7c9e 100644 --- a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs @@ -43,6 +43,57 @@ namespace OpenSim.Tests.Common public static readonly string PATH_DELIMITER = "/"; /// + /// Add an existing scene object as an item in the user's inventory. + /// + /// + /// + /// + /// + /// The inventory item created. + public static InventoryItemBase AddInventoryItem( + Scene scene, SceneObjectGroup so, int inventoryIdTail, int assetIdTail) + { + return AddInventoryItem( + scene, + so.Name, + TestHelpers.ParseTail(inventoryIdTail), + InventoryType.Object, + AssetHelpers.CreateAsset(TestHelpers.ParseTail(assetIdTail), so), + so.OwnerID); + } + + /// + /// Creates a notecard in the objects folder and specify an item id. + /// + /// + /// + /// + /// + /// The serialized asset for this item + /// + /// + private static InventoryItemBase AddInventoryItem( + Scene scene, string itemName, UUID itemId, InventoryType itemType, AssetBase asset, UUID userId) + { + scene.AssetService.Store(asset); + + InventoryItemBase item = new InventoryItemBase(); + item.Name = itemName; + item.AssetID = asset.FullID; + item.ID = itemId; + item.Owner = userId; + item.AssetType = asset.Type; + item.InvType = (int)itemType; + + InventoryFolderBase folder = scene.InventoryService.GetFolderForType(userId, (AssetType)asset.Type); + + item.Folder = folder.ID; + scene.AddInventoryItem(item); + + return item; + } + + /// /// Creates a notecard in the objects folder and specify an item id. /// /// @@ -81,42 +132,27 @@ namespace OpenSim.Tests.Common /// Type of item to create /// public static InventoryItemBase CreateInventoryItem( - Scene scene, string itemName, UUID itemId, UUID assetId, UUID userId, InventoryType type) + Scene scene, string itemName, UUID itemId, UUID assetId, UUID userId, InventoryType itemType) { AssetBase asset = null; - if (type == InventoryType.Notecard) + if (itemType == InventoryType.Notecard) { asset = AssetHelpers.CreateNotecardAsset(); asset.CreatorID = userId.ToString(); } - else if (type == InventoryType.Object) + else if (itemType == InventoryType.Object) { asset = AssetHelpers.CreateAsset(assetId, SceneHelpers.CreateSceneObject(1, userId)); } else { - throw new Exception(string.Format("Inventory type {0} not supported", type)); + throw new Exception(string.Format("Inventory type {0} not supported", itemType)); } - scene.AssetService.Store(asset); - - InventoryItemBase item = new InventoryItemBase(); - item.Name = itemName; - item.AssetID = asset.FullID; - item.ID = itemId; - item.Owner = userId; - item.AssetType = asset.Type; - item.InvType = (int)type; - - InventoryFolderBase folder = scene.InventoryService.GetFolderForType(userId, AssetType.Notecard); - - item.Folder = folder.ID; - scene.AddInventoryItem(item); - - return item; + return AddInventoryItem(scene, itemName, itemId, itemType, asset, userId); } - + /// /// Create inventory folders starting from the user's root folder. /// -- cgit v1.1 From fc2456320646df66b95a06d4cd292c3b2385a8ea Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 11 Jul 2012 21:43:35 +0100 Subject: Add regression TestDetachScriptedAttachmentToInventory() This currently only does a relatively crude check for a ScriptState node in the serialized xml --- .../Avatar/Attachments/AttachmentsModule.cs | 16 ++- .../Attachments/Tests/AttachmentsModuleTests.cs | 131 ++++++++++++++++++--- .../Framework/Interfaces/IAttachmentsModule.cs | 2 +- .../Framework/Scenes/SceneObjectPartInventory.cs | 4 + .../Api/Implementation/AsyncCommandManager.cs | 15 ++- .../Shared/Api/Implementation/Plugins/Listener.cs | 8 +- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 4 +- .../Tests/Common/Helpers/TaskInventoryHelpers.cs | 2 +- prebuild.xml | 1 + 9 files changed, 151 insertions(+), 32 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index efab6ed..64ee7e4 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -339,7 +339,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); } - public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) + public SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) { if (!Enabled) return null; @@ -527,6 +527,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// /// + /// private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, bool saveAllScripted) { // Saving attachments for NPCs messes them up for the real owner! @@ -720,18 +721,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, false, false, sp.UUID, true); - // m_log.DebugFormat( - // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", - // objatt.Name, remoteClient.Name, AttachmentPt); - if (objatt != null) { +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", +// objatt.Name, sp.Name, attachmentPt, m_scene.Name); + // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. objatt.HasGroupChanged = false; bool tainted = false; if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) tainted = true; + // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal + // course of events. If not, then it's probably not worth trying to recover the situation + // since this is more likely to trigger further exceptions and confuse later debugging. If + // exceptions can be thrown in expected error conditions (not NREs) then make this consistent + // since other normal error conditions will simply return false instead. // This will throw if the attachment fails try { diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 416aa6f..81e889d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -31,6 +31,7 @@ using System.Reflection; using System.Text; using System.Threading; using System.Timers; +using System.Xml; using Timer=System.Timers.Timer; using Nini.Config; using NUnit.Framework; @@ -41,10 +42,12 @@ using OpenSim.Region.CoreModules.Avatar.Attachments; using OpenSim.Region.CoreModules.Framework; using OpenSim.Region.CoreModules.Framework.EntityTransfer; using OpenSim.Region.CoreModules.Framework.InventoryAccess; -using OpenSim.Region.CoreModules.World.Serialiser; +using OpenSim.Region.CoreModules.Scripting.WorldComm; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; +using OpenSim.Region.CoreModules.World.Serialiser; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.ScriptEngine.XEngine; using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; @@ -57,6 +60,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests [TestFixture] public class AttachmentsModuleTests : OpenSimTestCase { + private AutoResetEvent m_chatEvent = new AutoResetEvent(false); + private OSChatMessage m_osChatMessageReceived; + [TestFixtureSetUp] public void FixtureInit() { @@ -72,16 +78,73 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; } - private Scene CreateDefaultTestScene() + private void OnChatFromWorld(object sender, OSChatMessage oscm) + { +// Console.WriteLine("Got chat [{0}]", oscm.Message); + + m_osChatMessageReceived = oscm; + m_chatEvent.Set(); + } + + private Scene CreateTestScene() + { + IConfigSource config = new IniConfigSource(); + List modules = new List(); + + AddCommonConfig(config, modules); + + Scene scene + = new SceneHelpers().SetupScene( + "attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config); + SceneHelpers.SetupSceneModules(scene, config, modules.ToArray()); + + return scene; + } + + private Scene CreateScriptingEnabledTestScene() { IConfigSource config = new IniConfigSource(); + List modules = new List(); + + AddCommonConfig(config, modules); + AddScriptingConfig(config, modules); + + Scene scene + = new SceneHelpers().SetupScene( + "attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config); + SceneHelpers.SetupSceneModules(scene, config, modules.ToArray()); + + scene.StartScripts(); + + return scene; + } + + private void AddCommonConfig(IConfigSource config, List modules) + { config.AddConfig("Modules"); config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); - Scene scene = new SceneHelpers().SetupScene(); - SceneHelpers.SetupSceneModules(scene, config, new AttachmentsModule(), new BasicInventoryAccessModule()); + modules.Add(new AttachmentsModule()); + modules.Add(new BasicInventoryAccessModule()); + } - return scene; + private void AddScriptingConfig(IConfigSource config, List modules) + { + IConfig startupConfig = config.AddConfig("Startup"); + startupConfig.Set("DefaultScriptEngine", "XEngine"); + + IConfig xEngineConfig = config.AddConfig("XEngine"); + xEngineConfig.Set("Enabled", "true"); + + // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call + // to AssemblyResolver.OnAssemblyResolve fails. + xEngineConfig.Set("AppDomainLoading", "false"); + + modules.Add(new XEngine()); + + // Necessary to stop serialization complaining + // FIXME: Stop this being necessary if at all possible +// modules.Add(new WorldCommModule()); } /// @@ -116,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); - Scene scene = CreateDefaultTestScene(); + Scene scene = CreateTestScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); @@ -163,7 +226,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); - Scene scene = CreateDefaultTestScene(); + Scene scene = CreateTestScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); @@ -190,7 +253,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = CreateDefaultTestScene(); + Scene scene = CreateTestScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); @@ -225,7 +288,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests { TestHelpers.InMethod(); - Scene scene = CreateDefaultTestScene(); + Scene scene = CreateTestScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); @@ -248,7 +311,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = CreateDefaultTestScene(); + Scene scene = CreateTestScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); @@ -278,9 +341,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests public void TestDetachAttachmentToInventory() { TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - Scene scene = CreateDefaultTestScene(); + Scene scene = CreateTestScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); @@ -303,6 +365,45 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests } /// + /// Test specific conditions associated with detaching a scripted attachment from inventory. + /// + [Test] + public void TestDetachScriptedAttachmentToInventory() + { + TestHelpers.InMethod(); + TestHelpers.EnableLogging(); + + Scene scene = CreateScriptingEnabledTestScene(); + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); + + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10); + TaskInventoryHelpers.AddScript(scene, so.RootPart); + InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000); + + // FIXME: Right now, we have to do a tricksy chat listen to make sure we know when the script is running. + // In the future, we need to be able to do this programatically more predicably. + scene.EventManager.OnChatFromWorld += OnChatFromWorld; + + SceneObjectGroup soRezzed + = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); + + // Wait for chat to signal rezzed script has been started. + m_chatEvent.WaitOne(60000); + + scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, soRezzed); + + InventoryItemBase userItemUpdated = scene.InventoryService.GetItem(userItem); + AssetBase asset = scene.AssetService.Get(userItemUpdated.AssetID.ToString()); + + XmlDocument soXml = new XmlDocument(); + soXml.LoadXml(Encoding.UTF8.GetString(asset.Data)); + + XmlNodeList scriptStateNodes = soXml.GetElementsByTagName("ScriptState"); + Assert.That(scriptStateNodes.Count, Is.EqualTo(1)); + } + + /// /// Test that attachments don't hang about in the scene when the agent is closed /// [Test] @@ -311,7 +412,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = CreateDefaultTestScene(); + Scene scene = CreateTestScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); @@ -334,7 +435,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - Scene scene = CreateDefaultTestScene(); + Scene scene = CreateTestScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); @@ -370,7 +471,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests { TestHelpers.InMethod(); - Scene scene = CreateDefaultTestScene(); + Scene scene = CreateTestScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index ba35a41..351e603 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -92,7 +92,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// /// The scene object that was attached. Null if the scene object could not be found - ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt); + SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt); /// /// Rez multiple attachments from a user's inventory diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index cf2ed1a..821fd81 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -1295,6 +1295,10 @@ namespace OpenSim.Region.Framework.Scenes { if (e != null) { +// m_log.DebugFormat( +// "[PRIM INVENTORY]: Getting script state from engine {0} for {1} in part {2} in group {3} in {4}", +// e.Name, item.Name, m_part.Name, m_part.ParentGroup.Name, m_part.ParentGroup.Scene.Name); + string n = e.GetXMLState(item.ItemID); if (n != String.Empty) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs index 993d10f..5b22860 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs @@ -233,17 +233,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_Timer[engine].UnSetTimerEvents(localID, itemID); // Remove from: HttpRequest - IHttpRequestModule iHttpReq = - engine.World.RequestModuleInterface(); - iHttpReq.StopHttpRequest(localID, itemID); + IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface(); + if (iHttpReq != null) + iHttpReq.StopHttpRequest(localID, itemID); IWorldComm comms = engine.World.RequestModuleInterface(); if (comms != null) comms.DeleteListener(itemID); IXMLRPC xmlrpc = engine.World.RequestModuleInterface(); - xmlrpc.DeleteChannels(itemID); - xmlrpc.CancelSRDRequests(itemID); + if (xmlrpc != null) + { + xmlrpc.DeleteChannels(itemID); + xmlrpc.CancelSRDRequests(itemID); + } // Remove Sensors m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID); @@ -305,7 +308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { List data = new List(); - Object[] listeners=m_Listener[engine].GetSerializationData(itemID); + Object[] listeners = m_Listener[engine].GetSerializationData(itemID); if (listeners.Length > 0) { data.Add("listener"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Listener.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Listener.cs index 93e0261..efa86fc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Listener.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Listener.cs @@ -88,13 +88,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins public Object[] GetSerializationData(UUID itemID) { - return m_commsPlugin.GetSerializationData(itemID); + if (m_commsPlugin != null) + return m_commsPlugin.GetSerializationData(itemID); + else + return new Object[]{}; } public void CreateFromData(uint localID, UUID itemID, UUID hostID, Object[] data) { - m_commsPlugin.CreateFromData(localID, itemID, hostID, data); + if (m_commsPlugin != null) + m_commsPlugin.CreateFromData(localID, itemID, hostID, data); } } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index efcae94..e07ae1c 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1676,12 +1676,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine public string GetXMLState(UUID itemID) { -// m_log.DebugFormat("[XEngine]: Getting XML state for {0}", itemID); +// m_log.DebugFormat("[XEngine]: Getting XML state for script instance {0}", itemID); IScriptInstance instance = GetInstance(itemID); if (instance == null) { -// m_log.DebugFormat("[XEngine]: Found no script for {0}, returning empty string", itemID); +// m_log.DebugFormat("[XEngine]: Found no script instance for {0}, returning empty string", itemID); return ""; } diff --git a/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs index c4e29e2..fba03ab 100644 --- a/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs @@ -81,7 +81,7 @@ namespace OpenSim.Tests.Common public static TaskInventoryItem AddScript(Scene scene, SceneObjectPart part) { AssetScriptText ast = new AssetScriptText(); - ast.Source = "default { state_entry() {} }"; + ast.Source = "default { state_entry() { llSay(0, \"Hello World\"); } }"; ast.Encode(); UUID assetUuid = new UUID("00000000-0000-0000-1000-000000000000"); diff --git a/prebuild.xml b/prebuild.xml index 3419119..ba8cdfb 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2929,6 +2929,7 @@ + -- cgit v1.1 From 0e611c47d322e1596d4636e283b9b855c7e58b60 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 11 Jul 2012 21:46:46 +0100 Subject: Remove WorldComm module from the regression TestCompileAndStartScript() since the infrastructure no longer fails if this module isn't present, at least on the tested codepaths --- OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs index a3f848c..fe4b0fa 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs @@ -58,9 +58,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine.Tests // Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory); m_xEngine = new XEngine(); - // Necessary to stop serialization complaining - WorldCommModule wcModule = new WorldCommModule(); - IniConfigSource configSource = new IniConfigSource(); IConfig startupConfig = configSource.AddConfig("Startup"); @@ -74,7 +71,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine.Tests xEngineConfig.Set("AppDomainLoading", "false"); m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource); - SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine, wcModule); + SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine); m_scene.StartScripts(); } -- cgit v1.1 From 33cff9b9d7c9d742b1cb7064ed78677e3f030e72 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 11 Jul 2012 21:55:18 +0100 Subject: Allow XEngine StartDelay to be configured in the [XEngine] config section. This is only currently meant for use by regression tests that don't have any issues if XEngine is started up quickly, since no other operations will be occuring simultaneously. Therefore, this is not yet documented externally. --- .../Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 3 ++- OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs | 1 + OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 11 +++++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 81e889d..b021a47 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -135,6 +135,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests IConfig xEngineConfig = config.AddConfig("XEngine"); xEngineConfig.Set("Enabled", "true"); + xEngineConfig.Set("StartDelay", "0"); // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call // to AssemblyResolver.OnAssemblyResolve fails. @@ -371,7 +372,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests public void TestDetachScriptedAttachmentToInventory() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); Scene scene = CreateScriptingEnabledTestScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs index fe4b0fa..f247a0b 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs @@ -65,6 +65,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine.Tests IConfig xEngineConfig = configSource.AddConfig("XEngine"); xEngineConfig.Set("Enabled", "true"); + xEngineConfig.Set("StartDelay", "0"); // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call // to AssemblyResolver.OnAssemblyResolve fails. diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index e07ae1c..f768cf2 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -77,7 +77,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine private IConfigSource m_ConfigSource = null; private ICompiler m_Compiler; private int m_MinThreads; - private int m_MaxThreads ; + private int m_MaxThreads; + + /// + /// Amount of time to delay before starting. + /// + private int m_StartDelay; + private int m_IdleTimeout; private int m_StackSize; private int m_SleepTime; @@ -231,6 +237,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_MaxThreads = m_ScriptConfig.GetInt("MaxThreads", 100); m_IdleTimeout = m_ScriptConfig.GetInt("IdleTimeout", 60); string priority = m_ScriptConfig.GetString("Priority", "BelowNormal"); + m_StartDelay = m_ScriptConfig.GetInt("StartDelay", 15000); m_MaxScriptQueue = m_ScriptConfig.GetInt("MaxScriptEventQueue",300); m_StackSize = m_ScriptConfig.GetInt("ThreadStackSize", 262144); m_SleepTime = m_ScriptConfig.GetInt("MaintenanceInterval", 10) * 1000; @@ -886,7 +893,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine { // This delay exists to stop mono problems where script compilation and startup would stop the sim // working properly for the session. - System.Threading.Thread.Sleep(15000); + System.Threading.Thread.Sleep(m_StartDelay); } object[] o; -- cgit v1.1 From 9c89ad9154952ca895e7a305ba259c02b98e46c4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 11 Jul 2012 22:15:53 +0100 Subject: Fix build break for windows with missing package for IScriptEngine in prebuild.xml for OpenSim.Region.CoreModules.Tests.dll --- prebuild.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/prebuild.xml b/prebuild.xml index ba8cdfb..b06aa1c 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2929,6 +2929,7 @@ + -- cgit v1.1 From 916e3bf886ee622e2f18d6eb74f90fee8c630471 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 11 Jul 2012 22:54:22 +0100 Subject: Where possible, use the system Encoding.ASCII and Encoding.UTF8 rather than constructing fresh copies. The encodings are thread-safe and already used in such a manner in other places. This isn't done where Byte Order Mark output is suppressed, since Encoding.UTF8 is constructed to output the BOM. --- OpenSim/ConsoleClient/Requester.cs | 2 +- .../Serialization/External/LandDataSerializer.cs | 4 +--- .../External/RegionSettingsSerializer.cs | 4 +--- .../Framework/Serialization/TarArchiveReader.cs | 8 +++----- .../Framework/Serialization/TarArchiveWriter.cs | 23 +++++++++++----------- OpenSim/Framework/Servers/BaseOpenSimServer.cs | 4 ++-- OpenSim/Framework/Util.cs | 3 +-- .../CoreModules/World/Archiver/AssetsDearchiver.cs | 2 -- .../World/Terrain/FileLoaders/Terragen.cs | 2 +- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 3 +-- .../XmlRpcGroupsServicesConnectorModule.cs | 3 +-- .../Scripting/JsonStore/JsonStoreScriptModule.cs | 7 +++---- .../Scripting/Minimodule/MRMModule.cs | 5 +---- .../Shared/Api/Implementation/LSL_Api.cs | 8 ++------ .../Shared/Api/Implementation/OSSL_Api.cs | 3 +-- .../ScriptEngine/Shared/CodeTools/Compiler.cs | 8 +++----- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 19 ++++++++---------- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 2 +- OpenSim/Server/Base/ServicesServerBase.cs | 8 ++++---- OpenSim/Tools/Compiler/Program.cs | 13 +++++------- 20 files changed, 51 insertions(+), 80 deletions(-) diff --git a/OpenSim/ConsoleClient/Requester.cs b/OpenSim/ConsoleClient/Requester.cs index fefe969..aabb02c 100644 --- a/OpenSim/ConsoleClient/Requester.cs +++ b/OpenSim/ConsoleClient/Requester.cs @@ -50,7 +50,7 @@ namespace OpenSim.ConsoleClient request.ContentType = "application/x-www-form-urlencoded"; - byte[] buffer = new System.Text.ASCIIEncoding().GetBytes(data); + byte[] buffer = Encoding.ASCII.GetBytes(data); int length = (int) buffer.Length; request.ContentLength = length; diff --git a/OpenSim/Framework/Serialization/External/LandDataSerializer.cs b/OpenSim/Framework/Serialization/External/LandDataSerializer.cs index e8d82d3..a64f01c 100644 --- a/OpenSim/Framework/Serialization/External/LandDataSerializer.cs +++ b/OpenSim/Framework/Serialization/External/LandDataSerializer.cs @@ -44,8 +44,6 @@ namespace OpenSim.Framework.Serialization.External { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - protected static UTF8Encoding m_utf8Encoding = new UTF8Encoding(); - private static Dictionary> m_ldProcessors = new Dictionary>(); @@ -163,7 +161,7 @@ namespace OpenSim.Framework.Serialization.External /// public static LandData Deserialize(byte[] serializedLandData) { - return Deserialize(m_utf8Encoding.GetString(serializedLandData, 0, serializedLandData.Length)); + return Deserialize(Encoding.UTF8.GetString(serializedLandData, 0, serializedLandData.Length)); } /// diff --git a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs index f18435d..19468c3 100644 --- a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs +++ b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs @@ -40,8 +40,6 @@ namespace OpenSim.Framework.Serialization.External /// public class RegionSettingsSerializer { - protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding(); - /// /// Deserialize settings /// @@ -50,7 +48,7 @@ namespace OpenSim.Framework.Serialization.External /// public static RegionSettings Deserialize(byte[] serializedSettings) { - return Deserialize(m_asciiEncoding.GetString(serializedSettings, 0, serializedSettings.Length)); + return Deserialize(Encoding.ASCII.GetString(serializedSettings, 0, serializedSettings.Length)); } /// diff --git a/OpenSim/Framework/Serialization/TarArchiveReader.cs b/OpenSim/Framework/Serialization/TarArchiveReader.cs index 77c29f8..339a37a 100644 --- a/OpenSim/Framework/Serialization/TarArchiveReader.cs +++ b/OpenSim/Framework/Serialization/TarArchiveReader.cs @@ -53,8 +53,6 @@ namespace OpenSim.Framework.Serialization TYPE_CONTIGUOUS_FILE = 8, } - protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding(); - /// /// Binary reader for the underlying stream /// @@ -120,13 +118,13 @@ namespace OpenSim.Framework.Serialization if (header[156] == (byte)'L') { int longNameLength = ConvertOctalBytesToDecimal(header, 124, 11); - tarHeader.FilePath = m_asciiEncoding.GetString(ReadData(longNameLength)); + tarHeader.FilePath = Encoding.ASCII.GetString(ReadData(longNameLength)); //m_log.DebugFormat("[TAR ARCHIVE READER]: Got long file name {0}", tarHeader.FilePath); header = m_br.ReadBytes(512); } else { - tarHeader.FilePath = m_asciiEncoding.GetString(header, 0, 100); + tarHeader.FilePath = Encoding.ASCII.GetString(header, 0, 100); tarHeader.FilePath = tarHeader.FilePath.Trim(m_nullCharArray); //m_log.DebugFormat("[TAR ARCHIVE READER]: Got short file name {0}", tarHeader.FilePath); } @@ -205,7 +203,7 @@ namespace OpenSim.Framework.Serialization { // Trim leading white space: ancient tars do that instead // of leading 0s :-( don't ask. really. - string oString = m_asciiEncoding.GetString(bytes, startIndex, count).TrimStart(m_spaceCharArray); + string oString = Encoding.ASCII.GetString(bytes, startIndex, count).TrimStart(m_spaceCharArray); int d = 0; diff --git a/OpenSim/Framework/Serialization/TarArchiveWriter.cs b/OpenSim/Framework/Serialization/TarArchiveWriter.cs index fca909f..122fa8e 100644 --- a/OpenSim/Framework/Serialization/TarArchiveWriter.cs +++ b/OpenSim/Framework/Serialization/TarArchiveWriter.cs @@ -41,7 +41,6 @@ namespace OpenSim.Framework.Serialization { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding(); protected static UTF8Encoding m_utf8Encoding = new UTF8Encoding(); /// @@ -85,7 +84,7 @@ namespace OpenSim.Framework.Serialization public void WriteFile(string filePath, byte[] data) { if (filePath.Length > 100) - WriteEntry("././@LongLink", m_asciiEncoding.GetBytes(filePath), 'L'); + WriteEntry("././@LongLink", Encoding.ASCII.GetBytes(filePath), 'L'); char fileType; @@ -137,7 +136,7 @@ namespace OpenSim.Framework.Serialization oString = "0" + oString; } - byte[] oBytes = m_asciiEncoding.GetBytes(oString); + byte[] oBytes = Encoding.ASCII.GetBytes(oString); return oBytes; } @@ -156,20 +155,20 @@ namespace OpenSim.Framework.Serialization byte[] header = new byte[512]; // file path field (100) - byte[] nameBytes = m_asciiEncoding.GetBytes(filePath); + byte[] nameBytes = Encoding.ASCII.GetBytes(filePath); int nameSize = (nameBytes.Length >= 100) ? 100 : nameBytes.Length; Array.Copy(nameBytes, header, nameSize); // file mode (8) - byte[] modeBytes = m_asciiEncoding.GetBytes("0000777"); + byte[] modeBytes = Encoding.ASCII.GetBytes("0000777"); Array.Copy(modeBytes, 0, header, 100, 7); // owner user id (8) - byte[] ownerIdBytes = m_asciiEncoding.GetBytes("0000764"); + byte[] ownerIdBytes = Encoding.ASCII.GetBytes("0000764"); Array.Copy(ownerIdBytes, 0, header, 108, 7); // group user id (8) - byte[] groupIdBytes = m_asciiEncoding.GetBytes("0000764"); + byte[] groupIdBytes = Encoding.ASCII.GetBytes("0000764"); Array.Copy(groupIdBytes, 0, header, 116, 7); // file size in bytes (12) @@ -181,17 +180,17 @@ namespace OpenSim.Framework.Serialization Array.Copy(fileSizeBytes, 0, header, 124, 11); // last modification time (12) - byte[] lastModTimeBytes = m_asciiEncoding.GetBytes("11017037332"); + byte[] lastModTimeBytes = Encoding.ASCII.GetBytes("11017037332"); Array.Copy(lastModTimeBytes, 0, header, 136, 11); // entry type indicator (1) - header[156] = m_asciiEncoding.GetBytes(new char[] { fileType })[0]; + header[156] = Encoding.ASCII.GetBytes(new char[] { fileType })[0]; - Array.Copy(m_asciiEncoding.GetBytes("0000000"), 0, header, 329, 7); - Array.Copy(m_asciiEncoding.GetBytes("0000000"), 0, header, 337, 7); + Array.Copy(Encoding.ASCII.GetBytes("0000000"), 0, header, 329, 7); + Array.Copy(Encoding.ASCII.GetBytes("0000000"), 0, header, 337, 7); // check sum for header block (8) [calculated last] - Array.Copy(m_asciiEncoding.GetBytes(" "), 0, header, 148, 8); + Array.Copy(Encoding.ASCII.GetBytes(" "), 0, header, 148, 8); int checksum = 0; foreach (byte b in header) diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 9459f76..14d8b0c 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -591,8 +591,8 @@ namespace OpenSim.Framework.Servers { string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString(); FileStream fs = File.Create(path); - System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); - Byte[] buf = enc.GetBytes(pidstring); + + Byte[] buf = Encoding.ASCII.GetBytes(pidstring); fs.Write(buf, 0, buf.Length); fs.Close(); m_pidFile = path; diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index e03bb74..fd9586c 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1236,8 +1236,7 @@ namespace OpenSim.Framework public static string Base64ToString(string str) { - UTF8Encoding encoder = new UTF8Encoding(); - Decoder utf8Decode = encoder.GetDecoder(); + Decoder utf8Decode = Encoding.UTF8.GetDecoder(); byte[] todecode_byte = Convert.FromBase64String(str); int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length); diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs index 2c04008..8c0ef88 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs @@ -46,8 +46,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding(); - /// /// Store for asset data we received before we get the metadata /// diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs index 7a0db26..b5c7d33 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs @@ -252,7 +252,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders if (horizontalScale < 0.01d) horizontalScale = 0.01d; - System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); + Encoding enc = Encoding.ASCII; bs.Write(enc.GetBytes("TERRAGENTERRAIN ")); diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index be8873d..7fafdc6 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -823,11 +823,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_log.DebugFormat("[FreeSwitchVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}", landName, land.LocalID, landUUID); } - System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); // slvoice handles the sip address differently if it begins with confctl, hiding it from the user in the friends list. however it also disables // the personal speech indicators as well unless some siren14-3d codec magic happens. we dont have siren143d so we'll settle for the personal speech indicator. - channelUri = String.Format("sip:conf-{0}@{1}", "x" + Convert.ToBase64String(encoding.GetBytes(landUUID)), m_freeSwitchRealm); + channelUri = String.Format("sip:conf-{0}@{1}", "x" + Convert.ToBase64String(Encoding.ASCII.GetBytes(landUUID)), m_freeSwitchRealm); lock (m_ParcelAddress) { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 52fc27d..61aaf04 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -1120,7 +1120,6 @@ namespace Nwc.XmlRpc /// Class supporting the request side of an XML-RPC transaction. public class ConfigurableKeepAliveXmlRpcRequest : XmlRpcRequest { - private Encoding _encoding = new ASCIIEncoding(); private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer(); private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer(); private bool _disableKeepAlive = true; @@ -1153,7 +1152,7 @@ namespace Nwc.XmlRpc request.KeepAlive = !_disableKeepAlive; Stream stream = request.GetRequestStream(); - XmlTextWriter xml = new XmlTextWriter(stream, _encoding); + XmlTextWriter xml = new XmlTextWriter(stream, Encoding.ASCII); _serializer.Serialize(xml, this); xml.Flush(); xml.Close(); diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index 4949097..eaba816 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -425,10 +425,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore try { - System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); - string jsondata = SLUtil.ParseNotecardToString(enc.GetString(a.Data)); - int result = m_store.SetValue(storeID,path,jsondata,true) ? 1 : 0; - m_comms.DispatchReply(scriptID,result,"",reqID.ToString()); + string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data)); + int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0; + m_comms.DispatchReply(scriptID,result, "", reqID.ToString()); return; } catch (Exception e) diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs index 74f5208..03481d2 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs @@ -482,10 +482,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule // Convert to base64 // string filetext = Convert.ToBase64String(data); - - ASCIIEncoding enc = new ASCIIEncoding(); - - Byte[] buf = enc.GetBytes(filetext); + Byte[] buf = Encoding.ASCII.GetBytes(filetext); m_log.Info("MRM 9"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 0a25454..0ebcd8d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10536,9 +10536,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; } - System.Text.UTF8Encoding enc = - new System.Text.UTF8Encoding(); - string data = enc.GetString(a.Data); + string data = Encoding.UTF8.GetString(a.Data); //m_log.Debug(data); NotecardCache.Cache(id, data); AsyncCommands. @@ -10591,9 +10589,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; } - System.Text.UTF8Encoding enc = - new System.Text.UTF8Encoding(); - string data = enc.GetString(a.Data); + string data = Encoding.UTF8.GetString(a.Data); //m_log.Debug(data); NotecardCache.Cache(id, data); AsyncCommands.DataserverPlugin.DataserverReply(id.ToString(), diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index e90f577..cfa08c2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -1811,8 +1811,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (a == null) return UUID.Zero; - System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); - string data = enc.GetString(a.Data); + string data = Encoding.UTF8.GetString(a.Data); NotecardCache.Cache(assetID, data); }; diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index 8f2ec49..17a0d69 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Globalization; using System.Reflection; using System.IO; +using System.Text; using Microsoft.CSharp; //using Microsoft.JScript; using Microsoft.VisualBasic; @@ -711,9 +712,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // string filetext = System.Convert.ToBase64String(data); - System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); - - Byte[] buf = enc.GetBytes(filetext); + Byte[] buf = Encoding.ASCII.GetBytes(filetext); FileStream sfs = File.Create(assembly + ".text"); sfs.Write(buf, 0, buf.Length); @@ -804,8 +803,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools mapstring += String.Format("{0},{1},{2},{3}\n", k.Key, k.Value, v.Key, v.Value); } - System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); - Byte[] mapbytes = enc.GetBytes(mapstring); + Byte[] mapbytes = Encoding.ASCII.GetBytes(mapstring); FileStream mfs = File.Create(filename); mfs.Write(mapbytes, 0, mapbytes.Length); mfs.Close(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 306090e..1c0cac7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -26,15 +26,16 @@ */ using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; using System.IO; +using System.Reflection; using System.Runtime.Remoting; using System.Runtime.Remoting.Lifetime; -using System.Threading; -using System.Collections; -using System.Collections.Generic; using System.Security.Policy; -using System.Reflection; -using System.Globalization; +using System.Text; +using System.Threading; using System.Xml; using OpenMetaverse; using log4net; @@ -298,13 +299,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance using (FileStream fs = File.Open(savedState, FileMode.Open, FileAccess.Read, FileShare.None)) { - System.Text.UTF8Encoding enc = - new System.Text.UTF8Encoding(); - Byte[] data = new Byte[size]; fs.Read(data, 0, size); - xml = enc.GetString(data); + xml = Encoding.UTF8.GetString(data); ScriptSerializer.Deserialize(xml, this); @@ -954,8 +952,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance try { FileStream fs = File.Create(Path.Combine(Path.GetDirectoryName(assembly), ItemID.ToString() + ".state")); - System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); - Byte[] buf = enc.GetBytes(xml); + Byte[] buf = (new UTF8Encoding()).GetBytes(xml); fs.Write(buf, 0, buf.Length); fs.Close(); } diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index f768cf2..20fad05 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1763,7 +1763,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine tfs.Read(tdata, 0, tdata.Length); } - assem = new System.Text.ASCIIEncoding().GetString(tdata); + assem = Encoding.ASCII.GetString(tdata); } catch (Exception e) { diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs index 36c48e6..b137c05 100644 --- a/OpenSim/Server/Base/ServicesServerBase.cs +++ b/OpenSim/Server/Base/ServicesServerBase.cs @@ -27,9 +27,10 @@ using System; using System.IO; -using System.Xml; -using System.Threading; using System.Reflection; +using System.Threading; +using System.Text; +using System.Xml; using OpenSim.Framework; using OpenSim.Framework.Console; using log4net; @@ -335,8 +336,7 @@ namespace OpenSim.Server.Base { string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString(); FileStream fs = File.Create(path); - System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); - Byte[] buf = enc.GetBytes(pidstring); + Byte[] buf = Encoding.ASCII.GetBytes(pidstring); fs.Write(buf, 0, buf.Length); fs.Close(); m_pidFile = path; diff --git a/OpenSim/Tools/Compiler/Program.cs b/OpenSim/Tools/Compiler/Program.cs index 249e18b..6c59c31 100644 --- a/OpenSim/Tools/Compiler/Program.cs +++ b/OpenSim/Tools/Compiler/Program.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; using Microsoft.CSharp; using OpenSim.Region.ScriptEngine.Shared.CodeTools; using System.CodeDom.Compiler; @@ -201,12 +202,8 @@ namespace OpenSim.Tools.LSL.Compiler // Convert to base64 // string filetext = System.Convert.ToBase64String(data); - - System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); - - Byte[] buf = enc.GetBytes(filetext); - - FileStream sfs = File.Create(OutFile+".text"); + Byte[] buf = Encoding.ASCII.GetBytes(filetext); + FileStream sfs = File.Create(OutFile + ".text"); sfs.Write(buf, 0, buf.Length); sfs.Close(); @@ -222,9 +219,9 @@ namespace OpenSim.Tools.LSL.Compiler // } // } - buf = enc.GetBytes(posmap); + buf = Encoding.ASCII.GetBytes(posmap); - FileStream mfs = File.Create(OutFile+".map"); + FileStream mfs = File.Create(OutFile + ".map"); mfs.Write(buf, 0, buf.Length); mfs.Close(); -- cgit v1.1 From 743437262ed645204d9040e1705a41902860a648 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 11 Jul 2012 16:07:14 -0700 Subject: Many explanitory comments added to the link and delink code in SOG and SOP. Should have no functionality changes. --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 88 ++++++++++++++++++---- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 28 +++++-- 2 files changed, 93 insertions(+), 23 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index fc04761..52469a2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -451,6 +451,8 @@ namespace OpenSim.Region.Framework.Scenes } } + // Restuff the new GroupPosition into each SOP of the linkset. + // This has the affect of resetting and tainting the physics actors. SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) parts[i].GroupPosition = val; @@ -1133,6 +1135,9 @@ namespace OpenSim.Region.Framework.Scenes public void ResetChildPrimPhysicsPositions() { + // Setting this SOG's absolute position also loops through and sets the positions + // of the SOP's in this SOG's linkset. This has the side affect of making sure + // the physics world matches the simulated world. AbsolutePosition = AbsolutePosition; // could someone in the know please explain how this works? // teravus: AbsolutePosition is NOT a normal property! @@ -1987,6 +1992,8 @@ namespace OpenSim.Region.Framework.Scenes LinkToGroup(objectGroup, false); } + // Link an existing group to this group. + // The group being linked need not be a linkset -- it can have just one prim. public void LinkToGroup(SceneObjectGroup objectGroup, bool insert) { // m_log.DebugFormat( @@ -1997,35 +2004,51 @@ namespace OpenSim.Region.Framework.Scenes if (objectGroup == this) return; + // 'linkPart' == the root of the group being linked into this group SceneObjectPart linkPart = objectGroup.m_rootPart; // physics flags from group to be applied to linked parts bool grpusephys = UsesPhysics; bool grptemporary = IsTemporary; + // Remember where the group being linked thought it was Vector3 oldGroupPosition = linkPart.GroupPosition; Quaternion oldRootRotation = linkPart.RotationOffset; + // A linked SOP remembers its location and rotation relative to the root of a group. + // Convert the root of the group being linked to be relative to the + // root of the group being linked to. + // Note: Some of the assignments have complex side effects. + + // First move the new group's root SOP's position to be relative to ours + // (radams1: Not sure if the multiple setting of OffsetPosition is required. If not, + // this code can be reordered to have a more logical flow.) linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition; + // Assign the new parent to the root of the old group linkPart.ParentID = m_rootPart.LocalId; + // Now that it's a child, it's group position is our root position linkPart.GroupPosition = AbsolutePosition; - Vector3 axPos = linkPart.OffsetPosition; + Vector3 axPos = linkPart.OffsetPosition; + // Rotate the linking root SOP's position to be relative to the new root prim Quaternion parentRot = m_rootPart.RotationOffset; axPos *= Quaternion.Inverse(parentRot); - linkPart.OffsetPosition = axPos; + + // Make the linking root SOP's rotation relative to the new root prim Quaternion oldRot = linkPart.RotationOffset; Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot; linkPart.RotationOffset = newRot; - linkPart.ParentID = m_rootPart.LocalId; - + // If there is only one SOP in a SOG, the LinkNum is zero. I.e., not a linkset. + // Now that we know this SOG has at least two SOPs in it, the new root + // SOP becomes the first in the linkset. if (m_rootPart.LinkNum == 0) m_rootPart.LinkNum = 1; lock (m_parts.SyncRoot) { + // Calculate the new link number for the old root SOP int linkNum; if (insert) { @@ -2041,6 +2064,7 @@ namespace OpenSim.Region.Framework.Scenes linkNum = PrimCount + 1; } + // Add the old root SOP as a part in our group's list m_parts.Add(linkPart.UUID, linkPart); linkPart.SetParent(this); @@ -2048,6 +2072,8 @@ namespace OpenSim.Region.Framework.Scenes // let physics know preserve part volume dtc messy since UpdatePrimFlags doesn't look to parent changes for now linkPart.UpdatePrimFlags(grpusephys, grptemporary, (IsPhantom || (linkPart.Flags & PrimFlags.Phantom) != 0), linkPart.VolumeDetectActive); + + // If the added SOP is physical, also tell the physics engine about the link relationship. if (linkPart.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical) { linkPart.PhysActor.link(m_rootPart.PhysActor); @@ -2056,20 +2082,26 @@ namespace OpenSim.Region.Framework.Scenes linkPart.LinkNum = linkNum++; + // Get a list of the SOP's in the old group in order of their linknum's. SceneObjectPart[] ogParts = objectGroup.Parts; Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b) { return a.LinkNum - b.LinkNum; }); + // Add each of the SOP's from the old linkset to our linkset for (int i = 0; i < ogParts.Length; i++) { SceneObjectPart part = ogParts[i]; if (part.UUID != objectGroup.m_rootPart.UUID) { LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); - // let physics know + + // Update the physics flags for the newly added SOP + // (Is this necessary? LinkNonRootPart() has already called UpdatePrimFlags but with different flags!??) part.UpdatePrimFlags(grpusephys, grptemporary, (IsPhantom || (part.Flags & PrimFlags.Phantom) != 0), part.VolumeDetectActive); + + // If the added SOP is physical, also tell the physics engine about the link relationship. if (part.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical) { part.PhysActor.link(m_rootPart.PhysActor); @@ -2080,6 +2112,7 @@ namespace OpenSim.Region.Framework.Scenes } } + // Now that we've aquired all of the old SOG's parts, remove the old SOG from the scene. m_scene.UnlinkSceneObject(objectGroup, true); objectGroup.IsDeleted = true; @@ -2152,7 +2185,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race /// condition. But currently there is no - /// alternative method that does take a lonk to delink a single prim. + /// alternative method that does take a lock to delink a single prim. /// /// /// @@ -2165,6 +2198,7 @@ namespace OpenSim.Region.Framework.Scenes linkPart.ClearUndoState(); + Vector3 worldPos = linkPart.GetWorldPosition(); Quaternion worldRot = linkPart.GetWorldRotation(); // Remove the part from this object @@ -2174,6 +2208,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart[] parts = m_parts.GetArray(); + // Rejigger the linknum's of the remaining SOP's to fill any gap if (parts.Length == 1 && RootPart != null) { // Single prim left @@ -2195,22 +2230,31 @@ namespace OpenSim.Region.Framework.Scenes PhysicsActor linkPartPa = linkPart.PhysActor; + // Remove the SOP from the physical scene. + // If the new SOG is physical, it is re-created later. + // (There is a problem here in that we have not yet told the physics + // engine about the delink. Someday, linksets should be made first + // class objects in the physics engine interface). if (linkPartPa != null) m_scene.PhysicsScene.RemovePrim(linkPartPa); // We need to reset the child part's position // ready for life as a separate object after being a part of another object - Quaternion parentRot = m_rootPart.RotationOffset; + /* This commented out code seems to recompute what GetWorldPosition already does. + * Replace with a call to GetWorldPosition (before unlinking) + Quaternion parentRot = m_rootPart.RotationOffset; Vector3 axPos = linkPart.OffsetPosition; - axPos *= parentRot; linkPart.OffsetPosition = new Vector3(axPos.X, axPos.Y, axPos.Z); linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition; linkPart.OffsetPosition = new Vector3(0, 0, 0); - + */ + linkPart.GroupPosition = worldPos; + linkPart.OffsetPosition = Vector3.Zero; linkPart.RotationOffset = worldRot; + // Create a new SOG to go around this unlinked and unattached SOP SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart); m_scene.AddNewSceneObject(objectGroup, true); @@ -2239,42 +2283,56 @@ namespace OpenSim.Region.Framework.Scenes m_isBackedUp = false; } + // This links an SOP from a previous linkset into my linkset. + // The trick is that the SOP's position and rotation are relative to the old root SOP's + // so we are passed in the position and rotation of the old linkset so this can + // unjigger this SOP's position and rotation from the previous linkset and + // then make them relative to my linkset root. private void LinkNonRootPart(SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation, int linkNum) { Quaternion parentRot = oldGroupRotation; Quaternion oldRot = part.RotationOffset; - Quaternion worldRot = parentRot * oldRot; - - parentRot = oldGroupRotation; + // Move our position to not be relative to the old parent Vector3 axPos = part.OffsetPosition; - axPos *= parentRot; part.OffsetPosition = axPos; part.GroupPosition = oldGroupPosition + part.OffsetPosition; part.OffsetPosition = Vector3.Zero; + + // Compution our rotation to be not relative to the old parent + Quaternion worldRot = parentRot * oldRot; part.RotationOffset = worldRot; + // Add this SOP to our linkset part.SetParent(this); part.ParentID = m_rootPart.LocalId; - m_parts.Add(part.UUID, part); part.LinkNum = linkNum; + // Compute the new position of this SOP relative to the group position part.OffsetPosition = part.GroupPosition - AbsolutePosition; - Quaternion rootRotation = m_rootPart.RotationOffset; + // (radams1 20120711: I don't know why part.OffsetPosition is set multiple times. + // It would have the affect of setting the physics engine position multiple + // times. In theory, that is not necessary but I don't have a good linkset + // test to know that cleaning up this code wouldn't break things.) + // Rotate the relative position by the rotation of the group + Quaternion rootRotation = m_rootPart.RotationOffset; Vector3 pos = part.OffsetPosition; pos *= Quaternion.Inverse(rootRotation); part.OffsetPosition = pos; + // Compute the SOP's rotation relative to the rotation of the group. parentRot = m_rootPart.RotationOffset; oldRot = part.RotationOffset; Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot; part.RotationOffset = newRot; + // Since this SOP's state has changed, push those changes into the physics engine + // and the simulator. part.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b3f11a7..4b2fede 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -693,9 +693,11 @@ namespace OpenSim.Region.Framework.Scenes { // If this is a linkset, we don't want the physics engine mucking up our group position here. PhysicsActor actor = PhysActor; + // If physical and the root prim of a linkset, the position of the group is what physics thinks. if (actor != null && ParentID == 0) m_groupPosition = actor.Position; + // If I'm an attachment, my position is reported as the position of who I'm attached to if (ParentGroup.IsAttachment) { ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar); @@ -721,7 +723,7 @@ namespace OpenSim.Region.Framework.Scenes } else { - // To move the child prim in respect to the group position and rotation we have to calculate + // The physics engine always sees all objects (root or linked) in world coordinates. actor.Position = GetWorldPosition(); actor.Orientation = GetWorldRotation(); } @@ -795,6 +797,8 @@ namespace OpenSim.Region.Framework.Scenes { // We don't want the physics engine mucking up the rotations in a linkset PhysicsActor actor = PhysActor; + // If this is a root of a linkset, the real rotation is what the physics engine thinks. + // If not a root prim, the offset rotation is computed by SOG and is relative to the root. if (ParentID == 0 && (Shape.PCode != 9 || Shape.State == 0) && actor != null) { if (actor.Orientation.X != 0f || actor.Orientation.Y != 0f @@ -1980,14 +1984,20 @@ namespace OpenSim.Region.Framework.Scenes /// A Linked Child Prim objects position in world public Vector3 GetWorldPosition() { - Quaternion parentRot = ParentGroup.RootPart.RotationOffset; - Vector3 axPos = OffsetPosition; - axPos *= parentRot; - Vector3 translationOffsetPosition = axPos; - if(_parentID == 0) - return GroupPosition; + Vector3 ret; + if (_parentID == 0) + // if a root SOP, my position is what it is + ret = GroupPosition; else - return ParentGroup.AbsolutePosition + translationOffsetPosition; + { + // If a child SOP, my position is relative to the root SOP so take + // my info and add the root's position and rotation to + // get my world position. + Quaternion parentRot = ParentGroup.RootPart.RotationOffset; + Vector3 translationOffsetPosition = OffsetPosition * parentRot; + ret = ParentGroup.AbsolutePosition + translationOffsetPosition; + } + return ret; } /// @@ -2004,6 +2014,8 @@ namespace OpenSim.Region.Framework.Scenes } else { + // A child SOP's rotation is relative to the root SOP's rotation. + // Combine them to get my absolute rotation. Quaternion parentRot = ParentGroup.RootPart.RotationOffset; Quaternion oldRot = RotationOffset; newRot = parentRot * oldRot; -- cgit v1.1 From ca412032e89939146a05cf708a4b9df93f74c4ac Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 12 Jul 2012 21:36:33 +0100 Subject: Put output for "show connections" command into standard table format. Also moves into own method. --- OpenSim/Region/Application/OpenSim.cs | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 56ad5c9..f3e4a2d 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -996,25 +996,7 @@ namespace OpenSim break; case "connections": - System.Text.StringBuilder connections = new System.Text.StringBuilder("Connections:\n"); - m_sceneManager.ForEachScene( - delegate(Scene scene) { - scene.ForEachClient( - delegate(IClientAPI client) { - connections.AppendFormat( - "{0}: {1} ({2}) from {3} on circuit {4}\n", - scene.RegionInfo.RegionName, - client.Name, - client.AgentId, - client.RemoteEndPoint, - client.CircuitCode - ); - } - ); - } - ); - - MainConsole.Instance.Output(connections.ToString()); + HandleShowConnections(); break; case "circuits": @@ -1138,6 +1120,21 @@ namespace OpenSim } } + private void HandleShowConnections() + { + ConsoleDisplayTable cdt = new ConsoleDisplayTable(); + cdt.AddColumn("Region", 20); + cdt.AddColumn("Avatar name", 25); + cdt.AddColumn("Remote endpoint", 23); + cdt.AddColumn("Circuit number", 14); + + m_sceneManager.ForEachScene( + s => s.ForEachClient( + c => cdt.AddRow(s.RegionInfo.RegionName, c.Name, c.RemoteEndPoint.ToString(), c.CircuitCode.ToString()))); + + MainConsole.Instance.Output(cdt.ToString()); + } + /// /// Use XML2 format to serialize data to a file /// -- cgit v1.1 From 6a0de355e09c264ce3f9e2c7db0b69919794e30c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 12 Jul 2012 22:37:48 +0100 Subject: Add active status to "show connections" --- OpenSim/Region/Application/OpenSim.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index f3e4a2d..e980716 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -1127,10 +1127,16 @@ namespace OpenSim cdt.AddColumn("Avatar name", 25); cdt.AddColumn("Remote endpoint", 23); cdt.AddColumn("Circuit number", 14); + cdt.AddColumn("Active?", 7); m_sceneManager.ForEachScene( s => s.ForEachClient( - c => cdt.AddRow(s.RegionInfo.RegionName, c.Name, c.RemoteEndPoint.ToString(), c.CircuitCode.ToString()))); + c => cdt.AddRow( + s.RegionInfo.RegionName, + c.Name, + c.RemoteEndPoint.ToString(), + c.CircuitCode.ToString(), + c.IsActive.ToString()))); MainConsole.Instance.Output(cdt.ToString()); } -- cgit v1.1 From 15283d35f1c567d6b33d0ba2884c1a73c83c6ce6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 12 Jul 2012 23:09:36 +0100 Subject: Extend "show circuits" to show circuit code, ip and viewer name. Also change to use standard table formatting "show circuits" and "show connections" console commands are very similar but access different data structures. --- OpenSim/Framework/AgentCircuitData.cs | 5 ++++ OpenSim/Region/Application/OpenSim.cs | 51 +++++++++++++++++++++-------------- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs index 57fb808..ffcc584 100644 --- a/OpenSim/Framework/AgentCircuitData.cs +++ b/OpenSim/Framework/AgentCircuitData.cs @@ -99,6 +99,11 @@ namespace OpenSim.Framework public string lastname; /// + /// Agent's full name. + /// + public string Name { get { return string.Format("{0} {1}", firstname, lastname); } } + + /// /// Random Unique GUID for this session. Client gets this at login and it's /// only supposed to be disclosed over secure channels /// diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index e980716..230af8e 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -1000,22 +1000,7 @@ namespace OpenSim break; case "circuits": - System.Text.StringBuilder acd = new System.Text.StringBuilder("Agent Circuits:\n"); - m_sceneManager.ForEachScene( - delegate(Scene scene) { - //this.HttpServer. - acd.AppendFormat("{0}:\n", scene.RegionInfo.RegionName); - foreach (AgentCircuitData aCircuit in scene.AuthenticateHandler.GetAgentCircuits().Values) - acd.AppendFormat( - "\t{0} {1} ({2})\n", - aCircuit.firstname, - aCircuit.lastname, - (aCircuit.child ? "Child" : "Root") - ); - } - ); - - MainConsole.Instance.Output(acd.ToString()); + HandleShowCircuits(); break; case "http-handlers": @@ -1120,19 +1105,45 @@ namespace OpenSim } } + private void HandleShowCircuits() + { + ConsoleDisplayTable cdt = new ConsoleDisplayTable(); + cdt.AddColumn("Region", 20); + cdt.AddColumn("Avatar name", 24); + cdt.AddColumn("Type", 5); + cdt.AddColumn("Code", 10); + cdt.AddColumn("IP", 16); + cdt.AddColumn("Viewer Name", 24); + + m_sceneManager.ForEachScene( + s => + { + foreach (AgentCircuitData aCircuit in s.AuthenticateHandler.GetAgentCircuits().Values) + cdt.AddRow( + s.Name, + aCircuit.Name, + aCircuit.child ? "child" : "root", + aCircuit.circuitcode.ToString(), + aCircuit.IPAddress.ToString(), + aCircuit.Viewer); + }); + + MainConsole.Instance.Output(cdt.ToString()); + } + private void HandleShowConnections() { ConsoleDisplayTable cdt = new ConsoleDisplayTable(); cdt.AddColumn("Region", 20); - cdt.AddColumn("Avatar name", 25); - cdt.AddColumn("Remote endpoint", 23); - cdt.AddColumn("Circuit number", 14); + cdt.AddColumn("Avatar name", 24); + cdt.AddColumn("Circuit code", 12); + cdt.AddColumn("Endpoint", 23); cdt.AddColumn("Active?", 7); m_sceneManager.ForEachScene( s => s.ForEachClient( c => cdt.AddRow( - s.RegionInfo.RegionName, + s.Name, c.Name, c.RemoteEndPoint.ToString(), c.CircuitCode.ToString(), -- cgit v1.1 From 75ab9b4b882feb8645ccc2904b11aebb9ae06e64 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 12 Jul 2012 23:18:30 +0100 Subject: Change very recent AllowedViewerList and BannedViewerList config setting names in OpenSim.ini.example to AllowedClients and BannedClients to match long-existing settings in [LoginService] Also changes separator from comma to bar to match existing [LoginService] config features. Divergence of config names for identical facilities in different places makes for an unnecessarily confusing user experience. --- OpenSim/Region/Framework/Scenes/Scene.cs | 8 ++++---- bin/OpenSim.ini.example | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 25223b9..3e9583c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -782,19 +782,19 @@ namespace OpenSim.Region.Framework.Scenes } } - string grant = startupConfig.GetString("AllowedViewerList", String.Empty); + string grant = startupConfig.GetString("AllowedClients", String.Empty); if (grant.Length > 0) { - foreach (string viewer in grant.Split(',')) + foreach (string viewer in grant.Split('|')) { m_AllowedViewers.Add(viewer.Trim().ToLower()); } } - grant = startupConfig.GetString("BannedViewerList", String.Empty); + grant = startupConfig.GetString("BannedClients", String.Empty); if (grant.Length > 0) { - foreach (string viewer in grant.Split(',')) + foreach (string viewer in grant.Split('|')) { m_BannedViewers.Add(viewer.Trim().ToLower()); } diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 33eaccb..9c68b65 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -280,18 +280,18 @@ ;; default is false ; TelehubAllowLandmark = false - ;# {AllowedViewerList} {} {Comma separated list of allowed viewers} {} - ;; Comma separated list of viewers which may gain access to the regions. - ;; One can use a Substring of the viewer name to enable only certain subversions + ;# {AllowedClients} {} {Bar (|) separated list of allowed clients} {} + ;; Bar (|) separated list of viewers which may gain access to the regions. + ;; One can use a substring of the viewer name to enable only certain versions ;; Example: Agent uses the viewer "Imprudence 1.3.2.0" ;; - "Imprudence" has access ;; - "Imprudence 1.3" has access ;; - "Imprudence 1.3.1" has no access - ;; AllowedViewerList = + ; AllowedViewerList = - ;# {BannedViewerList} {} {Comma separated list of banned viewers} {} - ;# Comma separated list of viewers which may not gain access to the regions. - ;; One can use a Substring of the viewer name to disable only certain subversions + ;# {BannedClients} {} {Bar (|) separated list of banned clients} {} + ;# Bar (|) separated list of viewers which may not gain access to the regions. + ;; One can use a Substring of the viewer name to disable only certain versions ;; Example: Agent uses the viewer "Imprudence 1.3.2.0" ;; - "Imprudence" has no access ;; - "Imprudence 1.3" has no access -- cgit v1.1 From 3b3d9967b18335c28ce2dfc269e47bac0ede075a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 12 Jul 2012 23:29:57 +0100 Subject: Remove IClientAPI.GetClientEP() in favour of existing identical IClientAPI.RemoteEndpoint. --- OpenSim/Framework/IClientAPI.cs | 1 - OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 5 ----- .../Agent/InternetRelayClientView/Server/IRCClientView.cs | 5 ----- OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | 5 ----- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 8 ++------ OpenSim/Tests/Common/Mock/TestClient.cs | 5 ----- 6 files changed, 2 insertions(+), 27 deletions(-) diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 4cc2e2c..d5952c4 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -1353,7 +1353,6 @@ namespace OpenSim.Framework void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message); void SendLogoutPacket(); - EndPoint GetClientEP(); // WARNING WARNING WARNING // diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 8874585..0457fe6 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -11845,11 +11845,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_udpClient.SetClientInfo(info); } - public EndPoint GetClientEP() - { - return m_userEndPoint; - } - #region Media Parcel Members public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time) diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 3a32528..363a1b8 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -1431,11 +1431,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server Disconnect(); } - public EndPoint GetClientEP() - { - return null; - } - public ClientInfo GetClientInfo() { return new ClientInfo(); diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 9b3400d..67989ba 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -945,11 +945,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } - public EndPoint GetClientEP() - { - return null; - } - public ClientInfo GetClientInfo() { return null; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index cfa08c2..3654106 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -874,13 +874,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (World.Entities.ContainsKey((UUID)agent) && World.Entities[avatarID] is ScenePresence) { ScenePresence target = (ScenePresence)World.Entities[avatarID]; - EndPoint ep = target.ControllingClient.GetClientEP(); - if (ep is IPEndPoint) - { - IPEndPoint ip = (IPEndPoint)ep; - return ip.Address.ToString(); - } + return target.ControllingClient.RemoteEndPoint.Address.ToString(); } + // fall through case, just return nothing return ""; } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 376465c..89c4f11 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -963,11 +963,6 @@ namespace OpenSim.Tests.Common.Mock { } - public EndPoint GetClientEP() - { - return null; - } - public ClientInfo GetClientInfo() { return null; -- cgit v1.1 From dda999a22c5f36d1d413f2f5f29ce8782af85b0b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 12 Jul 2012 23:43:02 +0100 Subject: Remove IClientIPEndpoint client interface for now. This may well come back in the future when this subinterface is actually used but it currently isn't and I feel the name was poor. Everything uses IClientAPI.RemoveEndPoint which also returned the full endpoint rather than just the ip address. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 21 +-------------------- .../InternetRelayClientView/Server/IRCClientView.cs | 11 +---------- 2 files changed, 2 insertions(+), 30 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 0457fe6..bc5315b 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -59,7 +59,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Handles new client connections /// Constructor takes a single Packet and authenticates everything /// - public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IClientIPEndpoint, IStatsCollector + public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IStatsCollector { /// /// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details. @@ -450,7 +450,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP RegisterInterface(this); RegisterInterface(this); RegisterInterface(this); - RegisterInterface(this); m_scene = scene; m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); @@ -12114,24 +12113,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP return numPackets; } - #region IClientIPEndpoint Members - - public IPAddress EndPoint - { - get - { - if (m_userEndPoint is IPEndPoint) - { - IPEndPoint ep = (IPEndPoint)m_userEndPoint; - - return ep.Address; - } - return null; - } - } - - #endregion - public void SendRebakeAvatarTextures(UUID textureID) { RebakeAvatarTexturesPacket pack = diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 363a1b8..5043208 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -44,7 +44,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server { public delegate void OnIRCClientReadyDelegate(IRCClientView cv); - public class IRCClientView : IClientAPI, IClientCore, IClientIPEndpoint + public class IRCClientView : IClientAPI, IClientCore { public event OnIRCClientReadyDelegate OnIRCReady; @@ -1628,15 +1628,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server #endregion - #region Implementation of IClientIPEndpoint - - public IPAddress EndPoint - { - get { return ((IPEndPoint) m_client.Client.RemoteEndPoint).Address; } - } - - #endregion - public void SendRebakeAvatarTextures(UUID textureID) { } -- cgit v1.1 From d6f54b25cd8e3d7a465e9875d2e00dd414a1b019 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 12 Jul 2012 23:48:42 +0100 Subject: Stop redundantly passing in the endpoint to the LLClientView constructor. This can always be retrieved via the LLUDPClient and is so done in various places already. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 5 +---- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index bc5315b..73cdec3 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -357,7 +357,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected string m_lastName; protected Thread m_clientThread; protected Vector3 m_startpos; - protected EndPoint m_userEndPoint; protected UUID m_activeGroupID; protected string m_activeGroupName = String.Empty; protected ulong m_activeGroupPowers; @@ -442,7 +441,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// /// Constructor /// - public LLClientView(EndPoint remoteEP, Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo, + public LLClientView(Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo, UUID agentId, UUID sessionId, uint circuitCode) { // DebugPacketLevel = 1; @@ -466,7 +465,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_sessionId = sessionId; m_secureSessionId = sessionInfo.LoginInfo.SecureSession; m_circuitCode = circuitCode; - m_userEndPoint = remoteEP; m_firstName = sessionInfo.LoginInfo.First; m_lastName = sessionInfo.LoginInfo.Last; m_startpos = sessionInfo.LoginInfo.StartPos; @@ -11832,7 +11830,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP { ClientInfo info = m_udpClient.GetClientInfo(); - info.userEP = m_userEndPoint; info.proxyEP = null; info.agentcircuit = RequestClientInfo(); diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 468d524..097f109 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1103,7 +1103,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO); - client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); + client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); client.OnLogout += LogoutHandler; ((LLClientView)client).DisableFacelights = m_disableFacelights; -- cgit v1.1 From 9ccb5787211f81c1c2059aa4b889f68cd460b539 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 13 Jul 2012 00:44:00 +0100 Subject: Don't cache regions data on the other unused LocalGridServiceConnector that the module code still sets up even if we're using one directly instantiated from the RemoteGridServiceConnector. Also improves log messages to indicate which regions are sending/receiving various neighbour protocol messages. --- .../Grid/LocalGridServiceConnector.cs | 35 +++++++++++++--------- .../ServiceConnectorsOut/Grid/RegionCache.cs | 1 + .../Neighbour/LocalNeighbourServiceConnector.cs | 6 ++-- .../Framework/Scenes/SceneCommunicationService.cs | 22 ++++++++++---- 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs index 540f33a..01be339 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs @@ -41,8 +41,7 @@ using OpenMetaverse; namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid { - public class LocalGridServicesConnector : - ISharedRegionModule, IGridService + public class LocalGridServicesConnector : ISharedRegionModule, IGridService { private static readonly ILog m_log = LogManager.GetLogger( @@ -51,7 +50,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid private IGridService m_GridService; private Dictionary m_LocalCache = new Dictionary(); - private bool m_Enabled = false; + private bool m_Enabled; public LocalGridServicesConnector() { @@ -59,7 +58,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public LocalGridServicesConnector(IConfigSource source) { - m_log.Debug("[LOCAL GRID CONNECTOR]: LocalGridServicesConnector instantiated"); + m_log.Debug("[LOCAL GRID SERVICE CONNECTOR]: LocalGridServicesConnector instantiated directly."); InitialiseService(source); } @@ -84,8 +83,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if (name == Name) { InitialiseService(source); - m_Enabled = true; - m_log.Info("[LOCAL GRID CONNECTOR]: Local grid connector enabled"); + m_log.Info("[LOCAL GRID SERVICE CONNECTOR]: Local grid connector enabled"); } } } @@ -95,7 +93,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid IConfig assetConfig = source.Configs["GridService"]; if (assetConfig == null) { - m_log.Error("[LOCAL GRID CONNECTOR]: GridService missing from OpenSim.ini"); + m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: GridService missing from OpenSim.ini"); return; } @@ -104,7 +102,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if (serviceDll == String.Empty) { - m_log.Error("[LOCAL GRID CONNECTOR]: No LocalServiceModule named in section GridService"); + m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: No LocalServiceModule named in section GridService"); return; } @@ -115,16 +113,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if (m_GridService == null) { - m_log.Error("[LOCAL GRID CONNECTOR]: Can't load grid service"); + m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: Can't load grid service"); return; } + + m_Enabled = true; } public void PostInitialise() { + // FIXME: We will still add this command even if we aren't enabled since RemoteGridServiceConnector + // will have instantiated us directly. MainConsole.Instance.Commands.AddCommand("Regions", false, "show neighbours", "show neighbours", - "Shows the local regions' neighbours", NeighboursCommand); + "Shows the local regions' neighbours", HandleShowNeighboursCommand); } public void Close() @@ -133,17 +135,22 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public void AddRegion(Scene scene) { - if (m_Enabled) - scene.RegisterModuleInterface(this); + if (!m_Enabled) + return; + + scene.RegisterModuleInterface(this); if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID)) - m_log.ErrorFormat("[LOCAL GRID CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!"); + m_log.ErrorFormat("[LOCAL GRID SERVICE CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!"); else m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene)); } public void RemoveRegion(Scene scene) { + if (!m_Enabled) + return; + m_LocalCache[scene.RegionInfo.RegionID].Clear(); m_LocalCache.Remove(scene.RegionInfo.RegionID); } @@ -232,7 +239,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid #endregion - public void NeighboursCommand(string module, string[] cmdparams) + public void HandleShowNeighboursCommand(string module, string[] cmdparams) { System.Text.StringBuilder caps = new System.Text.StringBuilder(); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs index 9172536..8d83fb6 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs @@ -55,6 +55,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public RegionCache(Scene s) { + Util.PrintCallStack(); m_scene = s; m_scene.EventManager.OnRegionUp += OnRegionUp; } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs index 40cc536..7a90686 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs @@ -125,13 +125,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour uint x, y; Utils.LongToUInts(regionHandle, out x, out y); - m_log.DebugFormat("[NEIGHBOUR CONNECTOR]: HelloNeighbour from region {0} to region at {1}-{2}", - thisRegion.RegionName, x / Constants.RegionSize, y / Constants.RegionSize); - foreach (Scene s in m_Scenes) { if (s.RegionInfo.RegionHandle == regionHandle) { + m_log.DebugFormat("[LOCAL NEIGHBOUR SERVICE CONNECTOR]: HelloNeighbour from region {0} to neighbour {1} at {2}-{3}", + thisRegion.RegionName, s.Name, x / Constants.RegionSize, y / Constants.RegionSize); + //m_log.Debug("[NEIGHBOUR CONNECTOR]: Found region to SendHelloNeighbour"); return s.IncomingHelloNeighbour(thisRegion); } diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index eff635b..661e03c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -84,16 +84,23 @@ namespace OpenSim.Region.Framework.Scenes if (neighbourService != null) neighbour = neighbourService.HelloNeighbour(regionhandle, region); else - m_log.DebugFormat("[SCENE COMMUNICATION SERVICE]: No neighbour service provided for informing neigbhours of this region"); + m_log.DebugFormat( + "[SCENE COMMUNICATION SERVICE]: No neighbour service provided for region {0} to inform neigbhours of status", + m_scene.Name); if (neighbour != null) { - m_log.DebugFormat("[SCENE COMMUNICATION SERVICE]: Successfully informed neighbour {0}-{1} that I'm here", x / Constants.RegionSize, y / Constants.RegionSize); + m_log.DebugFormat( + "[SCENE COMMUNICATION SERVICE]: Region {0} successfully informed neighbour {1} at {2}-{3} that it is up", + m_scene.Name, neighbour.RegionName, x / Constants.RegionSize, y / Constants.RegionSize); + m_scene.EventManager.TriggerOnRegionUp(neighbour); } else { - m_log.InfoFormat("[SCENE COMMUNICATION SERVICE]: Failed to inform neighbour {0}-{1} that I'm here.", x / Constants.RegionSize, y / Constants.RegionSize); + m_log.WarnFormat( + "[SCENE COMMUNICATION SERVICE]: Region {0} failed to inform neighbour at {1}-{2} that it is up.", + x / Constants.RegionSize, y / Constants.RegionSize); } } @@ -101,8 +108,13 @@ namespace OpenSim.Region.Framework.Scenes { //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName); - List neighbours = m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID); - m_log.DebugFormat("[SCENE COMMUNICATION SERVICE]: Informing {0} neighbours that this region is up", neighbours.Count); + List neighbours + = m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID); + + m_log.DebugFormat( + "[SCENE COMMUNICATION SERVICE]: Informing {0} neighbours that region {1} is up", + neighbours.Count, m_scene.Name); + foreach (GridRegion n in neighbours) { InformNeighbourThatRegionUpDelegate d = InformNeighboursThatRegionIsUpAsync; -- cgit v1.1 From 884d603cac6c3fe0cdbd199e13e1514146ff82bc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 13 Jul 2012 01:03:28 +0100 Subject: Rather than instantiating a UTF8 encoding everywhere when we want to supress the BOM, use a single Util.UTF8NoBomEncoding. This class is thread-safe (as evidenced by the provision of the system-wide Encoding.UTF8 which does not suppress BOM on output). --- OpenSim/Capabilities/LLSDStreamHandler.cs | 4 +- .../Framework/Serialization/TarArchiveWriter.cs | 4 +- OpenSim/Framework/Util.cs | 1 + .../Grid/LocalGridServiceConnector.cs | 2 +- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 2 +- .../AuthenticationServerPostHandler.cs | 3 +- .../Handlers/Avatar/AvatarServerPostHandler.cs | 3 +- .../Handlers/Friends/FriendsServerPostHandler.cs | 5 +-- .../Server/Handlers/Grid/GridServerPostHandler.cs | 42 ++++++++++---------- .../Handlers/GridUser/GridUserServerPostHandler.cs | 13 +++---- .../Hypergrid/HGFriendsServerPostHandler.cs | 6 +-- .../Handlers/Inventory/XInventoryInConnector.cs | 45 +++++++++++----------- .../Handlers/Presence/PresenceServerPostHandler.cs | 9 ++--- .../UserAccounts/UserAccountServerPostHandler.cs | 9 ++--- .../Neighbour/NeighbourServicesConnector.cs | 3 +- 15 files changed, 67 insertions(+), 84 deletions(-) diff --git a/OpenSim/Capabilities/LLSDStreamHandler.cs b/OpenSim/Capabilities/LLSDStreamHandler.cs index f5c728c..5df24b2 100644 --- a/OpenSim/Capabilities/LLSDStreamHandler.cs +++ b/OpenSim/Capabilities/LLSDStreamHandler.cs @@ -66,9 +66,7 @@ namespace OpenSim.Framework.Capabilities TResponse response = m_method(llsdRequest); - Encoding encoding = new UTF8Encoding(false); - - return encoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response)); + return Util.UTF8NoBomEncoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response)); } } } diff --git a/OpenSim/Framework/Serialization/TarArchiveWriter.cs b/OpenSim/Framework/Serialization/TarArchiveWriter.cs index 122fa8e..2a3bc48 100644 --- a/OpenSim/Framework/Serialization/TarArchiveWriter.cs +++ b/OpenSim/Framework/Serialization/TarArchiveWriter.cs @@ -41,8 +41,6 @@ namespace OpenSim.Framework.Serialization { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - protected static UTF8Encoding m_utf8Encoding = new UTF8Encoding(); - /// /// Binary writer for the underlying stream /// @@ -73,7 +71,7 @@ namespace OpenSim.Framework.Serialization /// public void WriteFile(string filePath, string data) { - WriteFile(filePath, m_utf8Encoding.GetBytes(data)); + WriteFile(filePath, Util.UTF8NoBomEncoding.GetBytes(data)); } /// diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index fd9586c..8cc29ee 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -148,6 +148,7 @@ namespace OpenSim.Framework } public static Encoding UTF8 = Encoding.UTF8; + public static Encoding UTF8NoBomEncoding = new UTF8Encoding(false); /// /// Well known UUID for the blank texture used in the Linden SL viewer version 1.20 (and hopefully onwards) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs index 01be339..3c6e381 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs @@ -150,7 +150,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid { if (!m_Enabled) return; - + m_LocalCache[scene.RegionInfo.RegionID].Clear(); m_LocalCache.Remove(scene.RegionInfo.RegionID); } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 1c0cac7..f1abd4b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -952,7 +952,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance try { FileStream fs = File.Create(Path.Combine(Path.GetDirectoryName(assembly), ItemID.ToString() + ".state")); - Byte[] buf = (new UTF8Encoding()).GetBytes(xml); + Byte[] buf = Util.UTF8NoBomEncoding.GetBytes(xml); fs.Write(buf, 0, buf.Length); fs.Close(); } diff --git a/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs b/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs index a19b599..6b93cd9 100644 --- a/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs @@ -321,8 +321,7 @@ namespace OpenSim.Server.Handlers.Authentication private byte[] ResultToBytes(Dictionary result) { string xmlString = ServerUtils.BuildXmlResponse(result); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } } } diff --git a/OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs b/OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs index 3ee405c..393584e 100644 --- a/OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs @@ -121,8 +121,7 @@ namespace OpenSim.Server.Handlers.Avatar string xmlString = ServerUtils.BuildXmlResponse(result); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } return FailureResult(); diff --git a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs index ef9b96f..47a8558 100644 --- a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs @@ -152,10 +152,9 @@ namespace OpenSim.Server.Handlers.Friends } string xmlString = ServerUtils.BuildXmlResponse(result); - //m_log.DebugFormat("[FRIENDS HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + //m_log.DebugFormat("[FRIENDS HANDLER]: resp string: {0}", xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] StoreFriend(Dictionary request) diff --git a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs index 91d14cb..ef5f33e 100644 --- a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs @@ -226,10 +226,9 @@ namespace OpenSim.Server.Handlers.Grid } string xmlString = ServerUtils.BuildXmlResponse(result); - //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] GetRegionByUUID(Dictionary request) @@ -256,9 +255,9 @@ namespace OpenSim.Server.Handlers.Grid result["result"] = rinfo.ToKeyValuePairs(); string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] GetRegionByPosition(Dictionary request) @@ -289,9 +288,9 @@ namespace OpenSim.Server.Handlers.Grid result["result"] = rinfo.ToKeyValuePairs(); string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] GetRegionByName(Dictionary request) @@ -318,9 +317,9 @@ namespace OpenSim.Server.Handlers.Grid result["result"] = rinfo.ToKeyValuePairs(); string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] GetRegionsByName(Dictionary request) @@ -361,9 +360,9 @@ namespace OpenSim.Server.Handlers.Grid } string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] GetRegionRange(Dictionary request) @@ -410,9 +409,9 @@ namespace OpenSim.Server.Handlers.Grid } } string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] GetDefaultRegions(Dictionary request) @@ -440,9 +439,9 @@ namespace OpenSim.Server.Handlers.Grid } } string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] GetFallbackRegions(Dictionary request) @@ -481,9 +480,9 @@ namespace OpenSim.Server.Handlers.Grid } } string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] GetHyperlinks(Dictionary request) @@ -511,9 +510,9 @@ namespace OpenSim.Server.Handlers.Grid } } string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] GetRegionFlags(Dictionary request) @@ -537,12 +536,11 @@ namespace OpenSim.Server.Handlers.Grid result["result"] = flags.ToString(); string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } - #endregion #region Misc diff --git a/OpenSim/Server/Handlers/GridUser/GridUserServerPostHandler.cs b/OpenSim/Server/Handlers/GridUser/GridUserServerPostHandler.cs index bf21255..687cf8d 100644 --- a/OpenSim/Server/Handlers/GridUser/GridUserServerPostHandler.cs +++ b/OpenSim/Server/Handlers/GridUser/GridUserServerPostHandler.cs @@ -117,10 +117,9 @@ namespace OpenSim.Server.Handlers.GridUser result["result"] = guinfo.ToKeyValuePairs(); string xmlString = ServerUtils.BuildXmlResponse(result); - //m_log.DebugFormat("[GRID USER HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + //m_log.DebugFormat("[GRID USER HANDLER]: resp string: {0}", xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] LoggedOut(Dictionary request) @@ -189,10 +188,9 @@ namespace OpenSim.Server.Handlers.GridUser result["result"] = guinfo.ToKeyValuePairs(); string xmlString = ServerUtils.BuildXmlResponse(result); - //m_log.DebugFormat("[GRID USER HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + //m_log.DebugFormat("[GRID USER HANDLER]: resp string: {0}", xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] GetGridUserInfos(Dictionary request) @@ -231,8 +229,7 @@ namespace OpenSim.Server.Handlers.GridUser } string xmlString = ServerUtils.BuildXmlResponse(result); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } private bool UnpackArgs(Dictionary request, out string user, out UUID region, out Vector3 position, out Vector3 lookAt) diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs index c2f127c..0aa2729 100644 --- a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs @@ -279,13 +279,11 @@ namespace OpenSim.Server.Handlers.Hypergrid } string xmlString = ServerUtils.BuildXmlResponse(result); - //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } - #endregion #region Misc diff --git a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs index cb9b65d..64127c2 100644 --- a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs +++ b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs @@ -217,9 +217,9 @@ namespace OpenSim.Server.Handlers.Asset result["RESULT"] = "False"; string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] HandleGetInventorySkeleton(Dictionary request) @@ -245,9 +245,9 @@ namespace OpenSim.Server.Handlers.Asset result["FOLDERS"] = sfolders; string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] HandleGetUserInventory(Dictionary request) @@ -284,9 +284,9 @@ namespace OpenSim.Server.Handlers.Asset } string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] HandleGetRootFolder(Dictionary request) @@ -300,9 +300,9 @@ namespace OpenSim.Server.Handlers.Asset result["folder"] = EncodeFolder(rfolder); string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] HandleGetFolderForType(Dictionary request) @@ -317,9 +317,9 @@ namespace OpenSim.Server.Handlers.Asset result["folder"] = EncodeFolder(folder); string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] HandleGetFolderContent(Dictionary request) @@ -358,9 +358,9 @@ namespace OpenSim.Server.Handlers.Asset } string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] HandleGetFolderItems(Dictionary request) @@ -386,9 +386,9 @@ namespace OpenSim.Server.Handlers.Asset result["ITEMS"] = sitems; string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] HandleAddFolder(Dictionary request) @@ -550,9 +550,9 @@ namespace OpenSim.Server.Handlers.Asset result["item"] = EncodeItem(item); string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] HandleGetFolder(Dictionary request) @@ -567,9 +567,9 @@ namespace OpenSim.Server.Handlers.Asset result["folder"] = EncodeFolder(folder); string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] HandleGetActiveGestures(Dictionary request) @@ -592,9 +592,9 @@ namespace OpenSim.Server.Handlers.Asset result["ITEMS"] = items; string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] HandleGetAssetPermissions(Dictionary request) @@ -609,12 +609,11 @@ namespace OpenSim.Server.Handlers.Asset result["RESULT"] = perms.ToString(); string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } - private Dictionary EncodeFolder(InventoryFolderBase f) { Dictionary ret = new Dictionary(); diff --git a/OpenSim/Server/Handlers/Presence/PresenceServerPostHandler.cs b/OpenSim/Server/Handlers/Presence/PresenceServerPostHandler.cs index 6b6a552..2d67c6d 100644 --- a/OpenSim/Server/Handlers/Presence/PresenceServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Presence/PresenceServerPostHandler.cs @@ -199,9 +199,9 @@ namespace OpenSim.Server.Handlers.Presence result["result"] = pinfo.ToKeyValuePairs(); string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] GetAgents(Dictionary request) @@ -240,12 +240,11 @@ namespace OpenSim.Server.Handlers.Presence } string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } - private byte[] SuccessResult() { XmlDocument doc = new XmlDocument(); diff --git a/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs b/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs index 3fd69ae..72551ef 100644 --- a/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs +++ b/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs @@ -195,9 +195,9 @@ namespace OpenSim.Server.Handlers.UserAccounts } string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } byte[] StoreAccount(Dictionary request) @@ -353,8 +353,7 @@ namespace OpenSim.Server.Handlers.UserAccounts private byte[] ResultToBytes(Dictionary result) { string xmlString = ServerUtils.BuildXmlResponse(result); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); } } -} +} \ No newline at end of file diff --git a/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs b/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs index 888b072..7429293 100644 --- a/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs +++ b/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs @@ -132,8 +132,7 @@ namespace OpenSim.Services.Connectors try { strBuffer = OSDParser.SerializeJsonString(args); - UTF8Encoding str = new UTF8Encoding(); - buffer = str.GetBytes(strBuffer); + buffer = Util.UTF8NoBomEncoding.GetBytes(strBuffer); } catch (Exception e) { -- cgit v1.1 From 2954ceccae906927932df6cedeb6c75479d0fe5c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 13 Jul 2012 01:08:49 +0100 Subject: Remove a callstack print out I accidentally left in 2 commits ago in 9ccb578 --- OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs index 8d83fb6..9172536 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs @@ -55,7 +55,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public RegionCache(Scene s) { - Util.PrintCallStack(); m_scene = s; m_scene.EventManager.OnRegionUp += OnRegionUp; } -- cgit v1.1 From ec6a195e40ad570a6e812c952f0505e76e7323d1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 14 Jul 2012 01:11:30 +0100 Subject: When generating a Warp3D texture, set the detailTexture[i] variable on resize from the JPEG2000 original rather than only saving it to disk. This appears to be the cause of the warp 3d exception seen when starting a new region for the first time. Subsequent starts were okay because resized saved bitmap was correctly retrieved from disk. Should fix http://opensimulator.org/mantis/view.php?id=5204 and http://opensimulator.org/mantis/view.php?id=5272 --- .../CoreModules/World/Warp3DMap/TerrainSplat.cs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs index 91252f7..df5ac92 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs @@ -111,6 +111,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap asset = assetService.GetCached(cacheID.ToString()); if (asset != null) { +// m_log.DebugFormat( +// "[TERRAIN SPLAT]: Got asset service cached terrain texture {0} {1}", i, asset.ID); + try { using (System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data)) @@ -129,6 +132,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap asset = assetService.Get(textureIDs[i].ToString()); if (asset != null) { +// m_log.DebugFormat( +// "[TERRAIN SPLAT]: Got cached original JPEG2000 terrain texture {0} {1}", i, asset.ID); + try { detailTexture[i] = (Bitmap)CSJ2K.J2kImage.FromBytes(asset.Data); } catch (Exception ex) { @@ -137,15 +143,13 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap } if (detailTexture[i] != null) - { - Bitmap bitmap = detailTexture[i]; - + { // Make sure this texture is the correct size, otherwise resize - if (bitmap.Width != 256 || bitmap.Height != 256) + if (detailTexture[i].Width != 256 || detailTexture[i].Height != 256) { - using (Bitmap origBitmap = bitmap) + using (Bitmap origBitmap = detailTexture[i]) { - bitmap = ImageUtils.ResizeImage(origBitmap, 256, 256); + detailTexture[i] = ImageUtils.ResizeImage(origBitmap, 256, 256); } } @@ -153,7 +157,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap byte[] data; using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) { - bitmap.Save(stream, ImageFormat.Png); + detailTexture[i].Save(stream, ImageFormat.Png); data = stream.ToArray(); } @@ -185,6 +189,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap { if (detailTexture[i] == null) { +// m_log.DebugFormat( +// "[TERRAIN SPLAT]: Generating solid colour for missing texture {0}", i); + // Create a solid color texture for this layer detailTexture[i] = new Bitmap(256, 256, PixelFormat.Format24bppRgb); using (Graphics gfx = Graphics.FromImage(detailTexture[i])) -- cgit v1.1 From 8d59385eeaa26feab8b19905ad6491065e4e4bf9 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Thu, 12 Jul 2012 12:25:08 +0100 Subject: Implementation of llSetRegionPos(). Does not implement failure on object entry/prim limit/access restrictions. Signed-off-by: SignpostMarv --- .../Shared/Api/Implementation/LSL_Api.cs | 43 ++++++++++++++++++++-- .../ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | 1 + .../ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs | 5 +++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 0ebcd8d..b209e23 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1917,11 +1917,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - SetPos(m_host, pos); + SetPos(m_host, pos, true); ScriptSleep(200); } + /// + /// Tries to move the entire object so that the root prim is within 0.1m of position. http://wiki.secondlife.com/wiki/LlSetRegionPos + /// Documentation indicates that the use of x/y coordinates up to 10 meters outside the bounds of a region will work but do not specify what happens if there is no adjacent region for the object to move into. + /// Uses the RegionSize constant here rather than hard-coding 266.0 to alert any developer modifying OpenSim to support variable-sized regions that this method will need tweaking. + /// + /// + /// 1 if successful, 0 otherwise. + public LSL_Integer llSetRegionPos(LSL_Vector pos) + { + m_host.AddScriptLPS(1); + if ( + llGetStatus((int)PrimFlags.Physics) == 1 || // return FALSE if physical. + m_host.ParentGroup.IsAttachment || // return FALSE if attachment + ( + pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region. + pos.x > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a east-adjacent region. + pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region. + pos.y > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a north-adjacent region. + pos.z > 4096 // return FALSE if altitude than 4096m + ) + ){ + return 0; + } + + SetPos(m_host.ParentGroup.RootPart, pos, false); + + return llVecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0; + } + // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) // note linked setpos is capped "differently" private LSL_Vector SetPosAdjust(LSL_Vector start, LSL_Vector end) @@ -1953,7 +1982,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return real_vec; } - protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) + /// + /// set object position, optionally capping the distance. + /// + /// + /// + /// if TRUE, will cap the distance to 10m. + protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) { // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) LSL_Vector currentPos = GetPartLocalPos(part); @@ -1966,12 +2001,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) targetPos.z = ground; SceneObjectGroup parent = part.ParentGroup; - LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); + LSL_Vector real_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); } else { - LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); + LSL_Vector rel_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); SceneObjectGroup parent = part.ParentGroup; parent.HasGroupChanged = true; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index d39b204..3fb463b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -359,6 +359,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llSetPrimitiveParams(LSL_List rules); void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); void llSetPrimURL(string url); + LSL_Integer llSetRegionPos(LSL_Vector pos); void llSetRemoteScriptAccessPin(int pin); void llSetRot(LSL_Rotation rot); void llSetScale(LSL_Vector scale); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index a0b3bc8..c457880 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -1618,6 +1618,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llSetPrimURL(url); } + public LSL_Integer llSetRegionPos(LSL_Vector pos) + { + return m_LSL_Functions.llSetRegionPos(pos); + } + public void llSetRemoteScriptAccessPin(int pin) { m_LSL_Functions.llSetRemoteScriptAccessPin(pin); -- cgit v1.1 From b6cd3b625ebffb45febf922a941fae337e3c1652 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Thu, 12 Jul 2012 15:57:22 +0100 Subject: adding workaround for silent failure if position is outside the bounds of a region, implementing parcel prim count check. Signed-off-by: SignpostMarv --- .../Shared/Api/Implementation/LSL_Api.cs | 54 ++++++++++++++++------ 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b209e23..8163267 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1932,23 +1932,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llSetRegionPos(LSL_Vector pos) { m_host.AddScriptLPS(1); - if ( - llGetStatus((int)PrimFlags.Physics) == 1 || // return FALSE if physical. - m_host.ParentGroup.IsAttachment || // return FALSE if attachment - ( - pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region. - pos.x > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a east-adjacent region. - pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region. - pos.y > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a north-adjacent region. - pos.z > 4096 // return FALSE if altitude than 4096m - ) - ){ + + // BEGIN WORKAROUND + // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND. + // + // This workaround is to prevent silent failure of this function. + // According to the specification on the SL Wiki, providing a position outside of the + if (pos.x < 0 || pos.x > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize) + { return 0; } + // END WORK AROUND + else{ + LSL_List parcelID = new LSL_List(ScriptBaseClass.PARCEL_DETAILS_ID); + Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition; + bool sameParcel = + llGetParcelDetails(new LSL_Vector(pos.x, pos.y, pos.z), parcelID).Data[0] == + llGetParcelDetails(pos, parcelID).Data[0] + ; + if ( + llGetStatus((int)PrimFlags.Physics) == 1 || // return FALSE if physical. + m_host.ParentGroup.IsAttachment || // return FALSE if attachment + ( + pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region. + pos.x > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a east-adjacent region. + pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region. + pos.y > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a north-adjacent region. + pos.z > 4096 // return FALSE if altitude than 4096m + ) || + // BEGIN RELIANCE ON WORK AROUND + // this check will only work if pos is within the region bounds. + ( + !sameParcel && // if it's moving within the same parcel we do not need to check if the destination parcel will exceed capacity if the object is moved. + (llGetParcelPrimCount(pos, ScriptBaseClass.PARCEL_COUNT_TOTAL, 0) + m_host.ParentGroup.PrimCount) > llGetParcelMaxPrims(pos, 0) + ) + // END RELIANCE ON WORK-AROUND + ){ + return 0; + } + + SetPos(m_host.ParentGroup.RootPart, pos, false); - SetPos(m_host.ParentGroup.RootPart, pos, false); + return llVecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0; + } - return llVecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0; + return 0; } // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) -- cgit v1.1 From e3453dd9ca1d08664a38205f05340623118a9880 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Thu, 12 Jul 2012 17:22:43 +0100 Subject: added in some extra variables, it sometimes thinks it is on the same parcel :( Signed-off-by: SignpostMarv --- .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8163267..ca240f5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1946,10 +1946,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api else{ LSL_List parcelID = new LSL_List(ScriptBaseClass.PARCEL_DETAILS_ID); Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition; - bool sameParcel = - llGetParcelDetails(new LSL_Vector(pos.x, pos.y, pos.z), parcelID).Data[0] == - llGetParcelDetails(pos, parcelID).Data[0] - ; + string parcelA = llGetParcelDetails(new LSL_Vector(objectPos.X, objectPos.X, objectPos.X), parcelID).Data[0].ToString(); + string parcelB = llGetParcelDetails(pos, parcelID).Data[0].ToString(); + bool sameParcel = parcelA == parcelB; + int objectPrimCount = m_host.ParentGroup.PrimCount; + LSL_Integer destParcelPrimCount = llGetParcelPrimCount(pos, ScriptBaseClass.PARCEL_COUNT_TOTAL, 0); + LSL_Integer max = llGetParcelMaxPrims(pos, 0); if ( llGetStatus((int)PrimFlags.Physics) == 1 || // return FALSE if physical. m_host.ParentGroup.IsAttachment || // return FALSE if attachment @@ -1964,7 +1966,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // this check will only work if pos is within the region bounds. ( !sameParcel && // if it's moving within the same parcel we do not need to check if the destination parcel will exceed capacity if the object is moved. - (llGetParcelPrimCount(pos, ScriptBaseClass.PARCEL_COUNT_TOTAL, 0) + m_host.ParentGroup.PrimCount) > llGetParcelMaxPrims(pos, 0) + (destParcelPrimCount + objectPrimCount) > max ) // END RELIANCE ON WORK-AROUND ){ -- cgit v1.1 From 423101b425d84e98f88b9c438559fc3321297c51 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Sat, 14 Jul 2012 01:14:00 +0100 Subject: acting on feedback from justincc --- .../Shared/Api/Implementation/LSL_Api.cs | 81 +++++++++++----------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ca240f5..cfcbae3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -421,15 +421,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return LSL_Vector.Norm(v); } - public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b) + private double vecDist(LSL_Vector a, LSL_Vector b) { - m_host.AddScriptLPS(1); double dx = a.x - b.x; double dy = a.y - b.y; double dz = a.z - b.z; return Math.Sqrt(dx * dx + dy * dy + dz * dz); } + public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b) + { + m_host.AddScriptLPS(1); + return vecDist(a, b); + } + //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke /// @@ -1242,6 +1247,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + private bool isPhysical(){ + return ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) == (uint)PrimFlags.Physics); + } + public LSL_Integer llGetStatus(int status) { m_host.AddScriptLPS(1); @@ -1249,11 +1258,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api switch (status) { case ScriptBaseClass.STATUS_PHYSICS: - if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) == (uint)PrimFlags.Physics) - { - return 1; - } - return 0; + return isPhysical() ? 1 : 0; case ScriptBaseClass.STATUS_PHANTOM: if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == (uint)PrimFlags.Phantom) @@ -1943,42 +1948,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return 0; } // END WORK AROUND - else{ - LSL_List parcelID = new LSL_List(ScriptBaseClass.PARCEL_DETAILS_ID); - Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition; - string parcelA = llGetParcelDetails(new LSL_Vector(objectPos.X, objectPos.X, objectPos.X), parcelID).Data[0].ToString(); - string parcelB = llGetParcelDetails(pos, parcelID).Data[0].ToString(); - bool sameParcel = parcelA == parcelB; - int objectPrimCount = m_host.ParentGroup.PrimCount; - LSL_Integer destParcelPrimCount = llGetParcelPrimCount(pos, ScriptBaseClass.PARCEL_COUNT_TOTAL, 0); - LSL_Integer max = llGetParcelMaxPrims(pos, 0); - if ( - llGetStatus((int)PrimFlags.Physics) == 1 || // return FALSE if physical. - m_host.ParentGroup.IsAttachment || // return FALSE if attachment - ( - pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region. - pos.x > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a east-adjacent region. - pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region. - pos.y > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a north-adjacent region. - pos.z > 4096 // return FALSE if altitude than 4096m - ) || - // BEGIN RELIANCE ON WORK AROUND - // this check will only work if pos is within the region bounds. - ( - !sameParcel && // if it's moving within the same parcel we do not need to check if the destination parcel will exceed capacity if the object is moved. - (destParcelPrimCount + objectPrimCount) > max - ) - // END RELIANCE ON WORK-AROUND - ){ - return 0; - } + else if ( // this is not part of the workaround if-block because it's not related to the workaround. + isPhysical() || + m_host.ParentGroup.IsAttachment || // return FALSE if attachment + ( + pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region. + pos.x > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a east-adjacent region. + pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region. + pos.y > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a north-adjacent region. + pos.z > 4096 // return FALSE if altitude than 4096m + ) + ) + { + return 0; + } + + // if we reach this point, then the object is not physical, it's not an attachment, and the destination is within the valid range. + // this could possibly be done in the above else-if block, but we're doing the check here to keep the code easier to read. - SetPos(m_host.ParentGroup.RootPart, pos, false); + Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition; + LandData here = World.GetLandData((float)objectPos.X, (float)objectPos.Y); + LandData there = World.GetLandData((float)pos.x, (float)pos.y); - return llVecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0; + // we're only checking prim limits if it's moving to a different parcel under the assumption that if the object got onto the parcel without exceeding the prim limits. + + bool sameParcel = here.GlobalID == there.GlobalID; + + if (!sameParcel && !World.Permissions.CanRezObject(m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, new Vector3((float)pos.x, (float)pos.y, (float)pos.z))) + { + return 0; } - return 0; + SetPos(m_host.ParentGroup.RootPart, pos, false); + + return vecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0; } // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) -- cgit v1.1 From 84b7ae25738c15737e70a680d1992cfbeb6cc806 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Sat, 14 Jul 2012 01:41:51 +0100 Subject: acting on feedback from justincc --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index cfcbae3..f88338d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -421,7 +421,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return LSL_Vector.Norm(v); } - private double vecDist(LSL_Vector a, LSL_Vector b) + private double VecDist(LSL_Vector a, LSL_Vector b) { double dx = a.x - b.x; double dy = a.y - b.y; @@ -432,7 +432,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b) { m_host.AddScriptLPS(1); - return vecDist(a, b); + return VecDist(a, b); } //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke @@ -1247,7 +1247,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - private bool isPhysical(){ + private bool IsPhysical() + { return ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) == (uint)PrimFlags.Physics); } @@ -1258,7 +1259,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api switch (status) { case ScriptBaseClass.STATUS_PHYSICS: - return isPhysical() ? 1 : 0; + return IsPhysical() ? 1 : 0; case ScriptBaseClass.STATUS_PHANTOM: if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == (uint)PrimFlags.Phantom) @@ -1949,7 +1950,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } // END WORK AROUND else if ( // this is not part of the workaround if-block because it's not related to the workaround. - isPhysical() || + IsPhysical() || m_host.ParentGroup.IsAttachment || // return FALSE if attachment ( pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region. @@ -1981,7 +1982,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api SetPos(m_host.ParentGroup.RootPart, pos, false); - return vecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0; + return VecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0; } // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) -- cgit v1.1 From 5d3723a47f7ddb32964055561ecf2a601f6b19f2 Mon Sep 17 00:00:00 2001 From: dahlia Date: Fri, 13 Jul 2012 21:22:15 -0700 Subject: update PrimMesher.cs to dll version r72 which fixes some path errors in sliced linear prims. Addresses Mantis #6085 --- OpenSim/Region/Physics/Meshing/PrimMesher.cs | 326 +++++++++++++++------------ 1 file changed, 183 insertions(+), 143 deletions(-) diff --git a/OpenSim/Region/Physics/Meshing/PrimMesher.cs b/OpenSim/Region/Physics/Meshing/PrimMesher.cs index 53022ad..4049ee1 100644 --- a/OpenSim/Region/Physics/Meshing/PrimMesher.cs +++ b/OpenSim/Region/Physics/Meshing/PrimMesher.cs @@ -236,6 +236,13 @@ namespace PrimMesher this.U = u; this.V = v; } + + public UVCoord Flip() + { + this.U = 1.0f - this.U; + this.V = 1.0f - this.V; + return this; + } } public struct Face @@ -603,40 +610,40 @@ namespace PrimMesher /// /// generates a profile for extrusion /// - internal class Profile + public class Profile { private const float twoPi = 2.0f * (float)Math.PI; - internal string errorMessage = null; + public string errorMessage = null; - internal List coords; - internal List faces; - internal List vertexNormals; - internal List us; - internal List faceUVs; - internal List faceNumbers; + public List coords; + public List faces; + public List vertexNormals; + public List us; + public List faceUVs; + public List faceNumbers; // use these for making individual meshes for each prim face - internal List outerCoordIndices = null; - internal List hollowCoordIndices = null; - internal List cut1CoordIndices = null; - internal List cut2CoordIndices = null; + public List outerCoordIndices = null; + public List hollowCoordIndices = null; + public List cut1CoordIndices = null; + public List cut2CoordIndices = null; - internal Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f); - internal Coord cutNormal1 = new Coord(); - internal Coord cutNormal2 = new Coord(); + public Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f); + public Coord cutNormal1 = new Coord(); + public Coord cutNormal2 = new Coord(); - internal int numOuterVerts = 0; - internal int numHollowVerts = 0; + public int numOuterVerts = 0; + public int numHollowVerts = 0; - internal int outerFaceNumber = -1; - internal int hollowFaceNumber = -1; + public int outerFaceNumber = -1; + public int hollowFaceNumber = -1; - internal bool calcVertexNormals = false; - internal int bottomFaceNumber = 0; - internal int numPrimFaces = 0; + public bool calcVertexNormals = false; + public int bottomFaceNumber = 0; + public int numPrimFaces = 0; - internal Profile() + public Profile() { this.coords = new List(); this.faces = new List(); @@ -646,7 +653,7 @@ namespace PrimMesher this.faceNumbers = new List(); } - internal Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals) + public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals) { this.calcVertexNormals = calcVertexNormals; this.coords = new List(); @@ -657,7 +664,6 @@ namespace PrimMesher this.faceNumbers = new List(); Coord center = new Coord(0.0f, 0.0f, 0.0f); - //bool hasCenter = false; List hollowCoords = new List(); List hollowNormals = new List(); @@ -682,8 +688,8 @@ namespace PrimMesher float yScale = 0.5f; if (sides == 4) // corners of a square are sqrt(2) from center { - xScale = 0.707f; - yScale = 0.707f; + xScale = 0.707107f; + yScale = 0.707107f; } float startAngle = profileStart * twoPi; @@ -724,7 +730,6 @@ namespace PrimMesher else if (!simpleFace) { this.coords.Add(center); - //hasCenter = true; if (this.calcVertexNormals) this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f)); this.us.Add(0.0f); @@ -752,7 +757,10 @@ namespace PrimMesher else hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); - hollowUs.Add(angle.angle * hollow); + if (hollowSides == 4) + hollowUs.Add(angle.angle * hollow * 0.707107f); + else + hollowUs.Add(angle.angle * hollow); } } } @@ -829,9 +837,6 @@ namespace PrimMesher if (createFaces) { - //int numOuterVerts = this.coords.Count; - //numOuterVerts = this.coords.Count; - //int numHollowVerts = hollowCoords.Count; int numTotalVerts = this.numOuterVerts + this.numHollowVerts; if (this.numOuterVerts == this.numHollowVerts) @@ -993,11 +998,7 @@ namespace PrimMesher if (startVert > 0) this.faceNumbers.Add(-1); for (int i = 0; i < this.numOuterVerts - 1; i++) - //this.faceNumbers.Add(sides < 5 ? faceNum++ : faceNum); - this.faceNumbers.Add(sides < 5 && i < sides ? faceNum++ : faceNum); - - //if (!hasHollow && !hasProfileCut) - // this.bottomFaceNumber = faceNum++; + this.faceNumbers.Add(sides < 5 && i <= sides ? faceNum++ : faceNum); this.faceNumbers.Add(hasProfileCut ? -1 : faceNum++); @@ -1014,8 +1015,7 @@ namespace PrimMesher this.hollowFaceNumber = faceNum++; } - //if (hasProfileCut || hasHollow) - // this.bottomFaceNumber = faceNum++; + this.bottomFaceNumber = faceNum++; if (hasHollow && hasProfileCut) @@ -1030,19 +1030,19 @@ namespace PrimMesher } - internal void MakeFaceUVs() + public void MakeFaceUVs() { this.faceUVs = new List(); foreach (Coord c in this.coords) - this.faceUVs.Add(new UVCoord(0.5f + c.X, 0.5f - c.Y)); + this.faceUVs.Add(new UVCoord(1.0f - (0.5f + c.X), 1.0f - (0.5f - c.Y))); } - internal Profile Copy() + public Profile Copy() { return this.Copy(true); } - internal Profile Copy(bool needFaces) + public Profile Copy(bool needFaces) { Profile copy = new Profile(); @@ -1071,12 +1071,12 @@ namespace PrimMesher return copy; } - internal void AddPos(Coord v) + public void AddPos(Coord v) { this.AddPos(v.X, v.Y, v.Z); } - internal void AddPos(float x, float y, float z) + public void AddPos(float x, float y, float z) { int i; int numVerts = this.coords.Count; @@ -1092,7 +1092,7 @@ namespace PrimMesher } } - internal void AddRot(Quat q) + public void AddRot(Quat q) { int i; int numVerts = this.coords.Count; @@ -1113,7 +1113,7 @@ namespace PrimMesher } } - internal void Scale(float x, float y) + public void Scale(float x, float y) { int i; int numVerts = this.coords.Count; @@ -1131,7 +1131,7 @@ namespace PrimMesher /// /// Changes order of the vertex indices and negates the center vertex normal. Does not alter vertex normals of radial vertices /// - internal void FlipNormals() + public void FlipNormals() { int i; int numFaces = this.faces.Count; @@ -1171,7 +1171,7 @@ namespace PrimMesher } } - internal void AddValue2FaceVertexIndices(int num) + public void AddValue2FaceVertexIndices(int num) { int numFaces = this.faces.Count; Face tmpFace; @@ -1186,7 +1186,7 @@ namespace PrimMesher } } - internal void AddValue2FaceNormalIndices(int num) + public void AddValue2FaceNormalIndices(int num) { if (this.calcVertexNormals) { @@ -1204,7 +1204,7 @@ namespace PrimMesher } } - internal void DumpRaw(String path, String name, String title) + public void DumpRaw(String path, String name, String title) { if (path == null) return; @@ -1261,6 +1261,15 @@ namespace PrimMesher public void Create(PathType pathType, int steps) { + if (this.taperX > 0.999f) + this.taperX = 0.999f; + if (this.taperX < -0.999f) + this.taperX = -0.999f; + if (this.taperY > 0.999f) + this.taperY = 0.999f; + if (this.taperY < -0.999f) + this.taperY = -0.999f; + if (pathType == PathType.Linear || pathType == PathType.Flexible) { int step = 0; @@ -1273,12 +1282,12 @@ namespace PrimMesher float start = -0.5f; float stepSize = length / (float)steps; - float percentOfPathMultiplier = stepSize; - float xOffset = 0.0f; - float yOffset = 0.0f; + float percentOfPathMultiplier = stepSize * 0.999999f; + float xOffset = this.topShearX * this.pathCutBegin; + float yOffset = this.topShearY * this.pathCutBegin; float zOffset = start; - float xOffsetStepIncrement = this.topShearX / steps; - float yOffsetStepIncrement = this.topShearY / steps; + float xOffsetStepIncrement = this.topShearX * length / steps; + float yOffsetStepIncrement = this.topShearY * length / steps; float percentOfPath = this.pathCutBegin; zOffset += percentOfPath; @@ -1573,13 +1582,6 @@ namespace PrimMesher this.hollow = 0.99f; if (hollow < 0.0f) this.hollow = 0.0f; - - //if (sphereMode) - // this.hasProfileCut = this.profileEnd - this.profileStart < 0.4999f; - //else - // //this.hasProfileCut = (this.profileStart > 0.0f || this.profileEnd < 1.0f); - // this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f; - //this.hasHollow = (this.hollow > 0.001f); } /// @@ -1614,10 +1616,9 @@ namespace PrimMesher steps = (int)(steps * 4.5 * length); } - if (sphereMode) + if (this.sphereMode) this.hasProfileCut = this.profileEnd - this.profileStart < 0.4999f; else - //this.hasProfileCut = (this.profileStart > 0.0f || this.profileEnd < 1.0f); this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f; this.hasHollow = (this.hollow > 0.001f); @@ -1630,6 +1631,22 @@ namespace PrimMesher float hollow = this.hollow; + if (pathType == PathType.Circular) + { + needEndFaces = false; + if (this.pathCutBegin != 0.0f || this.pathCutEnd != 1.0f) + needEndFaces = true; + else if (this.taperX != 0.0f || this.taperY != 0.0f) + needEndFaces = true; + else if (this.skew != 0.0f) + needEndFaces = true; + else if (twistTotal != 0.0f) + needEndFaces = true; + else if (this.radius != 0.0f) + needEndFaces = true; + } + else needEndFaces = true; + // sanity checks float initialProfileRot = 0.0f; if (pathType == PathType.Circular) @@ -1689,20 +1706,13 @@ namespace PrimMesher this.numPrimFaces = profile.numPrimFaces; - //profileOuterFaceNumber = profile.faceNumbers[0]; - //if (!needEndFaces) - // profileOuterFaceNumber--; - //profileOuterFaceNumber = needEndFaces ? 1 : 0; - - - //if (hasHollow) - //{ - // if (needEndFaces) - // profileHollowFaceNumber = profile.faceNumbers[profile.numOuterVerts + 1]; - // else - // profileHollowFaceNumber = profile.faceNumbers[profile.numOuterVerts] - 1; - //} - + int cut1FaceNumber = profile.bottomFaceNumber + 1; + int cut2FaceNumber = cut1FaceNumber + 1; + if (!needEndFaces) + { + cut1FaceNumber -= 2; + cut2FaceNumber -= 2; + } profileOuterFaceNumber = profile.outerFaceNumber; if (!needEndFaces) @@ -1732,7 +1742,8 @@ namespace PrimMesher Coord lastCutNormal1 = new Coord(); Coord lastCutNormal2 = new Coord(); - float lastV = 1.0f; + float thisV = 0.0f; + float lastV = 0.0f; Path path = new Path(); path.twistBegin = twistBegin; @@ -1754,23 +1765,6 @@ namespace PrimMesher path.Create(pathType, steps); - - if (pathType == PathType.Circular) - { - needEndFaces = false; - if (this.pathCutBegin != 0.0f || this.pathCutEnd != 1.0f) - needEndFaces = true; - else if (this.taperX != 0.0f || this.taperY != 0.0f) - needEndFaces = true; - else if (this.skew != 0.0f) - needEndFaces = true; - else if (twistTotal != 0.0f) - needEndFaces = true; - else if (this.radius != 0.0f) - needEndFaces = true; - } - else needEndFaces = true; - for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) { PathNode node = path.pathNodes[nodeIndex]; @@ -1784,7 +1778,7 @@ namespace PrimMesher { newLayer.FlipNormals(); - // add the top faces to the viewerFaces list here + // add the bottom faces to the viewerFaces list if (this.viewerMode) { Coord faceNormal = newLayer.faceNormal; @@ -1811,6 +1805,13 @@ namespace PrimMesher newViewerFace.uv2 = newLayer.faceUVs[face.v2]; newViewerFace.uv3 = newLayer.faceUVs[face.v3]; + if (pathType == PathType.Linear) + { + newViewerFace.uv1.Flip(); + newViewerFace.uv2.Flip(); + newViewerFace.uv3.Flip(); + } + this.viewerFaces.Add(newViewerFace); } } @@ -1835,7 +1836,10 @@ namespace PrimMesher // fill faces between layers int numVerts = newLayer.coords.Count; - Face newFace = new Face(); + Face newFace1 = new Face(); + Face newFace2 = new Face(); + + thisV = 1.0f - node.percentOfPath; if (nodeIndex > 0) { @@ -1853,14 +1857,23 @@ namespace PrimMesher int whichVert = i - startVert; - newFace.v1 = i; - newFace.v2 = i - numVerts; - newFace.v3 = iNext - numVerts; - this.faces.Add(newFace); + newFace1.v1 = i; + newFace1.v2 = i - numVerts; + newFace1.v3 = iNext; + + newFace1.n1 = newFace1.v1; + newFace1.n2 = newFace1.v2; + newFace1.n3 = newFace1.v3; + this.faces.Add(newFace1); - newFace.v2 = iNext - numVerts; - newFace.v3 = iNext; - this.faces.Add(newFace); + newFace2.v1 = iNext; + newFace2.v2 = i - numVerts; + newFace2.v3 = iNext - numVerts; + + newFace2.n1 = newFace2.v1; + newFace2.n2 = newFace2.v2; + newFace2.n3 = newFace2.v3; + this.faces.Add(newFace2); if (this.viewerMode) { @@ -1873,10 +1886,16 @@ namespace PrimMesher ViewerFace newViewerFace1 = new ViewerFace(primFaceNum); ViewerFace newViewerFace2 = new ViewerFace(primFaceNum); - float u1 = newLayer.us[whichVert]; + int uIndex = whichVert; + if (!hasHollow && sides > 4 && uIndex < newLayer.us.Count - 1) + { + uIndex++; + } + + float u1 = newLayer.us[uIndex]; float u2 = 1.0f; - if (whichVert < newLayer.us.Count - 1) - u2 = newLayer.us[whichVert + 1]; + if (uIndex < (int)newLayer.us.Count - 1) + u2 = newLayer.us[uIndex + 1]; if (whichVert == cut1Vert || whichVert == cut2Vert) { @@ -1894,13 +1913,22 @@ namespace PrimMesher u1 -= (int)u1; if (u2 < 0.1f) u2 = 1.0f; - //this.profileOuterFaceNumber = primFaceNum; } - else if (whichVert > profile.coords.Count - profile.numHollowVerts - 1) + } + + if (this.sphereMode) + { + if (whichVert != cut1Vert && whichVert != cut2Vert) { - u1 *= 2.0f; - u2 *= 2.0f; - //this.profileHollowFaceNumber = primFaceNum; + u1 = u1 * 2.0f - 1.0f; + u2 = u2 * 2.0f - 1.0f; + + if (whichVert >= newLayer.numOuterVerts) + { + u1 -= hollow; + u2 -= hollow; + } + } } @@ -1908,37 +1936,39 @@ namespace PrimMesher newViewerFace1.uv2.U = u1; newViewerFace1.uv3.U = u2; - newViewerFace1.uv1.V = 1.0f - node.percentOfPath; + newViewerFace1.uv1.V = thisV; newViewerFace1.uv2.V = lastV; - newViewerFace1.uv3.V = lastV; + newViewerFace1.uv3.V = thisV; - newViewerFace2.uv1.U = u1; - newViewerFace2.uv2.U = u2; + newViewerFace2.uv1.U = u2; + newViewerFace2.uv2.U = u1; newViewerFace2.uv3.U = u2; - newViewerFace2.uv1.V = 1.0f - node.percentOfPath; + newViewerFace2.uv1.V = thisV; newViewerFace2.uv2.V = lastV; - newViewerFace2.uv3.V = 1.0f - node.percentOfPath; + newViewerFace2.uv3.V = lastV; - newViewerFace1.v1 = this.coords[i]; - newViewerFace1.v2 = this.coords[i - numVerts]; - newViewerFace1.v3 = this.coords[iNext - numVerts]; + newViewerFace1.v1 = this.coords[newFace1.v1]; + newViewerFace1.v2 = this.coords[newFace1.v2]; + newViewerFace1.v3 = this.coords[newFace1.v3]; - newViewerFace2.v1 = this.coords[i]; - newViewerFace2.v2 = this.coords[iNext - numVerts]; - newViewerFace2.v3 = this.coords[iNext]; + newViewerFace2.v1 = this.coords[newFace2.v1]; + newViewerFace2.v2 = this.coords[newFace2.v2]; + newViewerFace2.v3 = this.coords[newFace2.v3]; - newViewerFace1.coordIndex1 = i; - newViewerFace1.coordIndex2 = i - numVerts; - newViewerFace1.coordIndex3 = iNext - numVerts; + newViewerFace1.coordIndex1 = newFace1.v1; + newViewerFace1.coordIndex2 = newFace1.v2; + newViewerFace1.coordIndex3 = newFace1.v3; - newViewerFace2.coordIndex1 = i; - newViewerFace2.coordIndex2 = iNext - numVerts; - newViewerFace2.coordIndex3 = iNext; + newViewerFace2.coordIndex1 = newFace2.v1; + newViewerFace2.coordIndex2 = newFace2.v2; + newViewerFace2.coordIndex3 = newFace2.v3; // profile cut faces if (whichVert == cut1Vert) { + newViewerFace1.primFaceNumber = cut1FaceNumber; + newViewerFace2.primFaceNumber = cut1FaceNumber; newViewerFace1.n1 = newLayer.cutNormal1; newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1; @@ -1947,10 +1977,14 @@ namespace PrimMesher } else if (whichVert == cut2Vert) { + newViewerFace1.primFaceNumber = cut2FaceNumber; + newViewerFace2.primFaceNumber = cut2FaceNumber; newViewerFace1.n1 = newLayer.cutNormal2; - newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2; + newViewerFace1.n2 = lastCutNormal2; + newViewerFace1.n3 = lastCutNormal2; - newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2; + newViewerFace2.n1 = newLayer.cutNormal2; + newViewerFace2.n3 = newLayer.cutNormal2; newViewerFace2.n2 = lastCutNormal2; } @@ -1963,13 +1997,13 @@ namespace PrimMesher } else { - newViewerFace1.n1 = this.normals[i]; - newViewerFace1.n2 = this.normals[i - numVerts]; - newViewerFace1.n3 = this.normals[iNext - numVerts]; + newViewerFace1.n1 = this.normals[newFace1.n1]; + newViewerFace1.n2 = this.normals[newFace1.n2]; + newViewerFace1.n3 = this.normals[newFace1.n3]; - newViewerFace2.n1 = this.normals[i]; - newViewerFace2.n2 = this.normals[iNext - numVerts]; - newViewerFace2.n3 = this.normals[iNext]; + newViewerFace2.n1 = this.normals[newFace2.n1]; + newViewerFace2.n2 = this.normals[newFace2.n2]; + newViewerFace2.n3 = this.normals[newFace2.n3]; } } @@ -1982,14 +2016,13 @@ namespace PrimMesher lastCutNormal1 = newLayer.cutNormal1; lastCutNormal2 = newLayer.cutNormal2; - lastV = 1.0f - node.percentOfPath; + lastV = thisV; if (needEndFaces && nodeIndex == path.pathNodes.Count - 1 && viewerMode) { // add the top faces to the viewerFaces list here Coord faceNormal = newLayer.faceNormal; - ViewerFace newViewerFace = new ViewerFace(); - newViewerFace.primFaceNumber = 0; + ViewerFace newViewerFace = new ViewerFace(0); int numFaces = newLayer.faces.Count; List faces = newLayer.faces; @@ -2012,6 +2045,13 @@ namespace PrimMesher newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen]; newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen]; + if (pathType == PathType.Linear) + { + newViewerFace.uv1.Flip(); + newViewerFace.uv2.Flip(); + newViewerFace.uv3.Flip(); + } + this.viewerFaces.Add(newViewerFace); } } -- cgit v1.1 From ee7478fa16b95352db22e0eba5c4cb90d47dabd5 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Mon, 16 Jul 2012 14:47:03 +0100 Subject: sending more user-friendly messages to the script error window rather than the thrown exceptions. Signed-off-by: Melanie --- .../ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 3654106..4137397 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -1664,9 +1664,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api CheckThreatLevel(ThreatLevel.Low, "osMessageObject"); m_host.AddScriptLPS(1); + UUID objUUID; + if (!UUID.TryParse(objectUUID, out objUUID)) // prior to patching, a thrown exception regarding invalid GUID format would be shouted instead. + { + OSSLShoutError("osMessageObject() cannot send messages to objects with invalid UUIDs"); + return; + } + object[] resobj = new object[] { new LSL_Types.LSLString(m_host.UUID.ToString()), new LSL_Types.LSLString(message) }; - SceneObjectPart sceneOP = World.GetSceneObjectPart(new UUID(objectUUID)); + SceneObjectPart sceneOP = World.GetSceneObjectPart(objUUID); + + if (sceneOP == null) // prior to patching, PostObjectEvent() would cause a throw exception to be shouted instead. + { + OSSLShoutError("osMessageObject() cannot send message to " + objUUID.ToString() + ", object was not found in scene."); + return; + } m_ScriptEngine.PostObjectEvent( sceneOP.LocalId, new EventParams( -- cgit v1.1