diff --git a/.gitignore b/.gitignore index e04c219d90..fae7509131 100644 --- a/.gitignore +++ b/.gitignore @@ -29,9 +29,14 @@ addon-modules/ bin/Debug/*.dll bin/*.dll.mdb bin/*.db +bin/*.db-journal bin/addin-db-* bin/*.dll bin/OpenSim.vshost.exe.config +bin/OpenSim.32BitLaunch.vshost.exe.config +bin/OpenSim.32BitLaunch.log +UpgradeLog.XML +_UpgradeReport_Files/ bin/ScriptEngines/*-*-*-*-* bin/ScriptEngines/*.dll bin/ScriptEngines/*/*.dll @@ -64,6 +69,7 @@ Examples/*.dll OpenSim.build OpenSim.sln OpenSim.suo +OpenSim.userprefs Prebuild/Prebuild.build Prebuild/Prebuild.sln TestResult.xml diff --git a/.nant/local.include b/.nant/local.include index 6d3e97228f..5185717cbc 100644 --- a/.nant/local.include +++ b/.nant/local.include @@ -132,17 +132,38 @@ + + + + + + + + + + - + - - + + - + + + + + + + + + + + + @@ -224,6 +245,16 @@ + + + + + + + + + + @@ -234,6 +265,7 @@ + diff --git a/BUILDING.txt b/BUILDING.md similarity index 58% rename from BUILDING.txt rename to BUILDING.md index 12e5ea53cf..5210b58f1f 100644 --- a/BUILDING.txt +++ b/BUILDING.md @@ -1,6 +1,4 @@ -==== Building OpenSim ==== - -=== Building on Windows === +# Building on Windows Steps: * runprebuild.bat @@ -9,16 +7,15 @@ Steps: * copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include * run OpenSim.exe -=== Building on Linux === +# Building on Linux Prereqs: - * Mono >= 2.4.3 - * Nant >= 0.85 - * On some Linux distributions you may need to install additional packages. - See http://opensimulator.org/wiki/Dependencies for more information. - - * May also use xbuild (included in mono distributions) - * May use Monodevelop, a cross-platform IDE +* Mono >= 2.4.3 +* Nant >= 0.85 +* On some Linux distributions you may need to install additional packages. + See http://opensimulator.org/wiki/Dependencies for more information. +* May also use xbuild (included in mono distributions) +* May use Monodevelop, a cross-platform IDE From the distribution type: * ./runprebuild.sh @@ -27,13 +24,13 @@ From the distribution type: * copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include * run mono OpenSim.exe -=== Using Monodevelop === +# Using Monodevelop From the distribution type: * ./runprebuild.sh * type monodevelop OpenSim.sln -=== References === +# References Helpful resources: * http://opensimulator.org/wiki/Build_Instructions diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 9dd0797411..43dea0bd3b 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -1,5 +1,5 @@ -<<<>>>>The following people have contributed to OpenSim (Thank you -for your effort!) + <<<>>>>The following people have contributed to OpenSim (Thank you +for your effort!) = Current OpenSim Developers (in very rough order of appearance) = These folks represent the current core team for OpenSim, and are the @@ -16,7 +16,7 @@ people that make the day to day of OpenSim happen. * BlueWall (James Hughes) * Nebadon Izumi (Michael Cerquoni, OSgrid) * Snoopy Pfeffer -* Richard Adams (Intel) +* Robert Adams (Intel) = Core Developers Following the White Rabbit = Core developers who have temporarily (we hope) gone chasing the white rabbit. @@ -92,6 +92,8 @@ what it is today. * Flyte Xevious * Garmin Kawaguichi * Gryc Ueusp +* Hiro Lecker +* Iain Oliver * Imaze Rhiano * Intimidated * Jeremy Bongio (IBM) @@ -181,12 +183,14 @@ what it is today. This software uses components from the following developers: * Sleepycat Software (Berkeley DB) +* Aurora-Sim (http://aurora-sim.org) * SQLite (Public Domain) * XmlRpcCS (http://xmlrpccs.sf.net/) * MySQL, Inc. (MySQL Connector/NET) * NUnit (http://www.nunit.org) * AGEIA Inc. (PhysX) * Russel L. Smith (ODE) +* Erwin Coumans (Bullet) * Prebuild (http://sourceforge.net/projects/dnpb/) * LibOpenMetaverse (http://lib.openmetaverse.org/) * DotNetOpenMail v0.5.8b (http://dotnetopenmail.sourceforge.net) @@ -208,3 +212,4 @@ In addition, we would like to thank: * The NANT Developers * Microsoft (.NET, MSSQL-Adapters) *x + diff --git a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs index 00657028e4..fcb6991969 100644 --- a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs +++ b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs @@ -99,12 +99,12 @@ namespace OpenSim.ApplicationPlugins.LoadRegions RegionInfo[] regionsToLoad = regionLoader.LoadRegions(); m_log.Info("[LOAD REGIONS PLUGIN]: Loading specific shared modules..."); - m_log.Info("[LOAD REGIONS PLUGIN]: DynamicTextureModule..."); - m_openSim.ModuleLoader.LoadDefaultSharedModule(new DynamicTextureModule()); - m_log.Info("[LOAD REGIONS PLUGIN]: LoadImageURLModule..."); - m_openSim.ModuleLoader.LoadDefaultSharedModule(new LoadImageURLModule()); - m_log.Info("[LOAD REGIONS PLUGIN]: XMLRPCModule..."); - m_openSim.ModuleLoader.LoadDefaultSharedModule(new XMLRPCModule()); + //m_log.Info("[LOAD REGIONS PLUGIN]: DynamicTextureModule..."); + //m_openSim.ModuleLoader.LoadDefaultSharedModule(new DynamicTextureModule()); + //m_log.Info("[LOAD REGIONS PLUGIN]: LoadImageURLModule..."); + //m_openSim.ModuleLoader.LoadDefaultSharedModule(new LoadImageURLModule()); + //m_log.Info("[LOAD REGIONS PLUGIN]: XMLRPCModule..."); + //m_openSim.ModuleLoader.LoadDefaultSharedModule(new XMLRPCModule()); // m_log.Info("[LOADREGIONSPLUGIN]: AssetTransactionModule..."); // m_openSim.ModuleLoader.LoadDefaultSharedModule(new AssetTransactionModule()); m_log.Info("[LOAD REGIONS PLUGIN]: Done."); @@ -136,9 +136,6 @@ namespace OpenSim.ApplicationPlugins.LoadRegions } } } - - m_openSim.ModuleLoader.PostInitialise(); - m_openSim.ModuleLoader.ClearCache(); } public void Dispose() diff --git a/OpenSim/ApplicationPlugins/LoadRegions/Properties/AssemblyInfo.cs b/OpenSim/ApplicationPlugins/LoadRegions/Properties/AssemblyInfo.cs index 59b8ddaab1..57615ea2d3 100644 --- a/OpenSim/ApplicationPlugins/LoadRegions/Properties/AssemblyInfo.cs +++ b/OpenSim/ApplicationPlugins/LoadRegions/Properties/AssemblyInfo.cs @@ -60,7 +60,7 @@ using System.Runtime.InteropServices; // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: -// [assembly: AssemblyVersion("0.6.5.*")] +// [assembly: AssemblyVersion("0.7.5.*")] -[assembly : AssemblyVersion("0.6.5.*")] +[assembly : AssemblyVersion("0.7.5.*")] [assembly : AssemblyFileVersion("0.6.5.0")] \ No newline at end of file diff --git a/OpenSim/ApplicationPlugins/RegionModulesController/Properties/AssemblyInfo.cs b/OpenSim/ApplicationPlugins/RegionModulesController/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..14527d9ea9 --- /dev/null +++ b/OpenSim/ApplicationPlugins/RegionModulesController/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.ApplicationPlugins.RegionModulesController")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://opensimulator.org")] +[assembly: AssemblyProduct("OpenSim")] +[assembly: AssemblyCopyright("OpenSimulator developers")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("c023816d-194e-40c1-9195-a0f281d4ac5d")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs b/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs index 49bd911baf..633d0055fd 100644 --- a/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs +++ b/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs @@ -215,7 +215,7 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController } } -#region IRegionModulesController implementation +#region Region Module interfacesController implementation /// /// Check that the given module is no disabled in the [Modules] section of the config files. diff --git a/OpenSim/ApplicationPlugins/RemoteController/Properties/AssemblyInfo.cs b/OpenSim/ApplicationPlugins/RemoteController/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..8ad948c9bd --- /dev/null +++ b/OpenSim/ApplicationPlugins/RemoteController/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.ApplicationPlugins.RemoteController")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://opensimulator.org")] +[assembly: AssemblyProduct("OpenSim")] +[assembly: AssemblyCopyright("Copyright OpenSimulator developers © 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("efec6e69-fc4a-4e21-86e6-4a261c12d4db")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 437d150097..3d80eb6899 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -696,7 +696,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController region.ExternalHostName = (string) requestData["external_address"]; - bool persist = Convert.ToBoolean((string) requestData["persist"]); + bool persist = Convert.ToBoolean(requestData["persist"]); if (persist) { // default place for region configuration files is in the @@ -852,7 +852,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController responseData["success"] = true; responseData["region_name"] = region.RegionName; responseData["region_id"] = region.RegionID.ToString(); - responseData["region_uuid"] = region.RegionID.ToString(); //Deprecate July 2012 m_log.Info("[RADMIN]: CreateRegion: request complete"); } @@ -1106,8 +1105,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController string lastName = (string) requestData["user_lastname"]; string password = (string) requestData["user_password"]; - uint regionXLocation = Convert.ToUInt32((Int32) requestData["start_region_x"]); - uint regionYLocation = Convert.ToUInt32((Int32) requestData["start_region_y"]); + uint regionXLocation = Convert.ToUInt32(requestData["start_region_x"]); + uint regionYLocation = Convert.ToUInt32(requestData["start_region_y"]); string email = ""; // empty string for email if (requestData.Contains("user_email")) @@ -1304,9 +1303,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController if (requestData.ContainsKey("user_password")) password = (string) requestData["user_password"]; if (requestData.ContainsKey("start_region_x")) - regionXLocation = Convert.ToUInt32((Int32) requestData["start_region_x"]); + regionXLocation = Convert.ToUInt32(requestData["start_region_x"]); if (requestData.ContainsKey("start_region_y")) - regionYLocation = Convert.ToUInt32((Int32) requestData["start_region_y"]); + regionYLocation = Convert.ToUInt32(requestData["start_region_y"]); // if (requestData.ContainsKey("start_lookat_x")) // ulaX = Convert.ToUInt32((Int32) requestData["start_lookat_x"]); @@ -1493,6 +1492,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController /// profile url /// noassets /// true if no assets should be saved + /// all + /// true to save all the regions in the simulator /// perm /// C and/or T /// @@ -1549,6 +1550,11 @@ namespace OpenSim.ApplicationPlugins.RemoteController options["checkPermissions"] = (string)requestData["perm"]; } + if ((string)requestData["all"] == "true") + { + options["all"] = (string)requestData["all"]; + } + IRegionArchiverModule archiver = scene.RequestModuleInterface(); if (archiver != null) @@ -2008,29 +2014,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController { return; } - #region Deprecate July 2012 - //region_ID, regionid, region_uuid will be deprecated in July 2012!!!!!! - else if (requestData.ContainsKey("regionid") && - !String.IsNullOrEmpty((string)requestData["regionid"])) - { - m_log.WarnFormat("[RADMIN]: Use of parameter regionid will be deprecated as of July 2012. Use region_id instead"); - } - else if (requestData.ContainsKey("region_ID") && - !String.IsNullOrEmpty((string)requestData["region_ID"])) - { - m_log.WarnFormat("[RADMIN]: Use of parameter region_ID will be deprecated as of July 2012. Use region_id instead"); - } - else if (requestData.ContainsKey("regionID") && - !String.IsNullOrEmpty((string)requestData["regionID"])) - { - m_log.WarnFormat("[RADMIN]: Use of parameter regionID will be deprecated as of July 2012. Use region_id instead"); - } - else if (requestData.ContainsKey("region_uuid") && - !String.IsNullOrEmpty((string)requestData["region_uuid"])) - { - m_log.WarnFormat("[RADMIN]: Use of parameter region_uuid will be deprecated as of July 2012. Use region_id instead"); - } - #endregion else { responseData["accepted"] = false; @@ -2052,56 +2035,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController throw new Exception(String.Format("Region ID {0} not found", regionID)); } } - #region Deprecate July 2012 - else if (requestData.ContainsKey("regionid") && - !String.IsNullOrEmpty((string)requestData["regionid"])) - { - m_log.WarnFormat("[RADMIN]: Use of parameter regionid will be deprecated as of July 2012. Use region_id instead"); - - UUID regionID = (UUID)(string)requestData["regionid"]; - if (!m_application.SceneManager.TryGetScene(regionID, out scene)) - { - responseData["error"] = String.Format("Region ID {0} not found", regionID); - throw new Exception(String.Format("Region ID {0} not found", regionID)); - } - } - else if (requestData.ContainsKey("region_ID") && - !String.IsNullOrEmpty((string)requestData["region_ID"])) - { - m_log.WarnFormat("[RADMIN]: Use of parameter region_ID will be deprecated as of July 2012. Use region_id instead"); - - UUID regionID = (UUID)(string)requestData["region_ID"]; - if (!m_application.SceneManager.TryGetScene(regionID, out scene)) - { - responseData["error"] = String.Format("Region ID {0} not found", regionID); - throw new Exception(String.Format("Region ID {0} not found", regionID)); - } - } - else if (requestData.ContainsKey("regionID") && - !String.IsNullOrEmpty((string)requestData["regionID"])) - { - m_log.WarnFormat("[RADMIN]: Use of parameter regionID will be deprecated as of July 2012. Use region_id instead"); - - UUID regionID = (UUID)(string)requestData["regionID"]; - if (!m_application.SceneManager.TryGetScene(regionID, out scene)) - { - responseData["error"] = String.Format("Region ID {0} not found", regionID); - throw new Exception(String.Format("Region ID {0} not found", regionID)); - } - } - else if (requestData.ContainsKey("region_uuid") && - !String.IsNullOrEmpty((string)requestData["region_uuid"])) - { - m_log.WarnFormat("[RADMIN]: Use of parameter region_uuid will be deprecated as of July 2012. Use region_id instead"); - - UUID regionID = (UUID)(string)requestData["region_uuid"]; - if (!m_application.SceneManager.TryGetScene(regionID, out scene)) - { - responseData["error"] = String.Format("Region ID {0} not found", regionID); - throw new Exception(String.Format("Region ID {0} not found", regionID)); - } - } - #endregion else if (requestData.ContainsKey("region_name") && !String.IsNullOrEmpty((string)requestData["region_name"])) { @@ -2515,7 +2448,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController destinationItem.Description = item.Description; destinationItem.InvType = item.InvType; destinationItem.CreatorId = item.CreatorId; - destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid; destinationItem.CreatorData = item.CreatorData; destinationItem.NextPermissions = item.NextPermissions; destinationItem.CurrentPermissions = item.CurrentPermissions; @@ -2570,7 +2502,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController destinationItem.Description = item.Description; destinationItem.InvType = item.InvType; destinationItem.CreatorId = item.CreatorId; - destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid; destinationItem.CreatorData = item.CreatorData; destinationItem.NextPermissions = item.NextPermissions; destinationItem.CurrentPermissions = item.CurrentPermissions; @@ -2683,7 +2614,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController destinationItem.Description = item.Description; destinationItem.InvType = item.InvType; destinationItem.CreatorId = item.CreatorId; - destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid; destinationItem.CreatorData = item.CreatorData; destinationItem.NextPermissions = item.NextPermissions; destinationItem.CurrentPermissions = item.CurrentPermissions; @@ -2989,7 +2919,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController inventoryItem.Description = GetStringAttribute(item,"desc",""); inventoryItem.InvType = GetIntegerAttribute(item,"invtype",-1); inventoryItem.CreatorId = GetStringAttribute(item,"creatorid",""); - inventoryItem.CreatorIdAsUuid = (UUID)GetStringAttribute(item,"creatoruuid",""); inventoryItem.CreatorData = GetStringAttribute(item, "creatordata", ""); inventoryItem.NextPermissions = GetUnsignedAttribute(perms, "next", 0x7fffffff); inventoryItem.CurrentPermissions = GetUnsignedAttribute(perms,"current",0x7fffffff); diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs index cb88695600..072bd6f010 100644 --- a/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs +++ b/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs @@ -312,14 +312,16 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory // Now that everything is setup we can proceed to // add THIS agent to the HTTP server's handler list - if (!AddAgentHandler(Rest.Name,this)) - { - Rest.Log.ErrorFormat("{0} Unable to activate handler interface", MsgId); - foreach (IRest handler in handlers) - { - handler.Close(); - } - } + // FIXME: If this code is ever to be re-enabled (most of it is disabled already) then this will + // have to be handled through the AddHttpHandler interface. +// if (!AddAgentHandler(Rest.Name,this)) +// { +// Rest.Log.ErrorFormat("{0} Unable to activate handler interface", MsgId); +// foreach (IRest handler in handlers) +// { +// handler.Close(); +// } +// } } catch (Exception e) @@ -342,11 +344,13 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory { Rest.Log.InfoFormat("{0} Plugin is terminating", MsgId); - try - { - RemoveAgentHandler(Rest.Name, this); - } - catch (KeyNotFoundException){} + // FIXME: If this code is ever to be re-enabled (most of it is disabled already) then this will + // have to be handled through the AddHttpHandler interface. +// try +// { +// RemoveAgentHandler(Rest.Name, this); +// } +// catch (KeyNotFoundException){} foreach (IRest handler in handlers) { diff --git a/OpenSim/ApplicationPlugins/Rest/RestPlugin.cs b/OpenSim/ApplicationPlugins/Rest/RestPlugin.cs index eb167502b0..a2425b5cf3 100644 --- a/OpenSim/ApplicationPlugins/Rest/RestPlugin.cs +++ b/OpenSim/ApplicationPlugins/Rest/RestPlugin.cs @@ -297,7 +297,9 @@ namespace OpenSim.ApplicationPlugins.Rest { if (!IsEnabled) return false; _agents.Add(agentName, handler); - return _httpd.AddAgentHandler(agentName, handler); +// return _httpd.AddAgentHandler(agentName, handler); + + return false; } /// @@ -316,7 +318,7 @@ namespace OpenSim.ApplicationPlugins.Rest if (_agents[agentName] == handler) { _agents.Remove(agentName); - return _httpd.RemoveAgentHandler(agentName, handler); +// return _httpd.RemoveAgentHandler(agentName, handler); } return false; } @@ -358,10 +360,10 @@ namespace OpenSim.ApplicationPlugins.Rest _httpd.RemoveStreamHandler(h.HttpMethod, h.Path); } _handlers = null; - foreach (KeyValuePair h in _agents) - { - _httpd.RemoveAgentHandler(h.Key, h.Value); - } +// foreach (KeyValuePair h in _agents) +// { +// _httpd.RemoveAgentHandler(h.Key, h.Value); +// } _agents = null; } diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs index 720640e260..ec574a3e62 100644 --- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs @@ -45,16 +45,54 @@ namespace OpenSim.Capabilities.Handlers { public class GetMeshHandler { -// private static readonly ILog m_log = -// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private IAssetService m_assetService; + public const string DefaultFormat = "vnd.ll.mesh"; + public GetMeshHandler(IAssetService assService) { m_assetService = assService; } + public Hashtable Handle(Hashtable request) + { + Hashtable ret = new Hashtable(); + ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; + ret["content_type"] = "text/plain"; + ret["keepalive"] = false; + ret["reusecontext"] = false; + ret["int_bytes"] = 0; + ret["int_lod"] = 0; + string MeshStr = (string)request["mesh_id"]; + + //m_log.DebugFormat("[GETMESH]: called {0}", MeshStr); + + if (m_assetService == null) + { + m_log.Error("[GETMESH]: Cannot fetch mesh " + MeshStr + " without an asset service"); + } + + UUID meshID; + if (!String.IsNullOrEmpty(MeshStr) && UUID.TryParse(MeshStr, out meshID)) + { + // m_log.DebugFormat("[GETMESH]: Received request for mesh id {0}", meshID); + + + ret = ProcessGetMesh(request, UUID.Zero, null); + + + } + else + { + m_log.Warn("[GETMESH]: Failed to parse a mesh_id from GetMesh request: " + (string)request["uri"]); + } + + + return ret; + } public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap) { Hashtable responsedata = new Hashtable(); @@ -62,6 +100,9 @@ namespace OpenSim.Capabilities.Handlers responsedata["content_type"] = "text/plain"; responsedata["keepalive"] = false; responsedata["str_response_string"] = "Request wasn't what was expected"; + responsedata["reusecontext"] = false; + responsedata["int_lod"] = 0; + responsedata["int_bytes"] = 0; string meshStr = string.Empty; @@ -77,6 +118,7 @@ namespace OpenSim.Capabilities.Handlers responsedata["content_type"] = "text/plain"; responsedata["keepalive"] = false; responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh."; + responsedata["reusecontext"] = false; return responsedata; } @@ -86,9 +128,100 @@ namespace OpenSim.Capabilities.Handlers { if (mesh.Type == (SByte)AssetType.Mesh) { - responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); - responsedata["content_type"] = "application/vnd.ll.mesh"; - responsedata["int_response_code"] = 200; + + Hashtable headers = new Hashtable(); + responsedata["headers"] = headers; + + string range = String.Empty; + + if (((Hashtable)request["headers"])["range"] != null) + range = (string)((Hashtable)request["headers"])["range"]; + + else if (((Hashtable)request["headers"])["Range"] != null) + range = (string)((Hashtable)request["headers"])["Range"]; + + if (!String.IsNullOrEmpty(range)) // Mesh Asset LOD // Physics + { + // Range request + int start, end; + if (TryParseRange(range, out start, out end)) + { + // Before clamping start make sure we can satisfy it in order to avoid + // sending back the last byte instead of an error status + if (start >= mesh.Data.Length) + { + responsedata["int_response_code"] = 404; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "This range doesnt exist."; + responsedata["reusecontext"] = false; + responsedata["int_lod"] = 3; + return responsedata; + } + else + { + end = Utils.Clamp(end, 0, mesh.Data.Length - 1); + start = Utils.Clamp(start, 0, end); + int len = end - start + 1; + + //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); + + if (start > 20000) + { + responsedata["int_lod"] = 3; + } + else if (start < 4097) + { + responsedata["int_lod"] = 1; + } + else + { + responsedata["int_lod"] = 2; + } + + + if (start == 0 && len == mesh.Data.Length) // well redudante maybe + { + responsedata["int_response_code"] = (int) System.Net.HttpStatusCode.OK; + responsedata["bin_response_data"] = mesh.Data; + responsedata["int_bytes"] = mesh.Data.Length; + responsedata["reusecontext"] = false; + responsedata["int_lod"] = 3; + + } + else + { + responsedata["int_response_code"] = + (int) System.Net.HttpStatusCode.PartialContent; + headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, + mesh.Data.Length); + + byte[] d = new byte[len]; + Array.Copy(mesh.Data, start, d, 0, len); + responsedata["bin_response_data"] = d; + responsedata["int_bytes"] = len; + responsedata["reusecontext"] = false; + } + } + } + else + { + m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]); + responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); + responsedata["content_type"] = "application/vnd.ll.mesh"; + responsedata["int_response_code"] = 200; + responsedata["reusecontext"] = false; + responsedata["int_lod"] = 3; + } + } + else + { + responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); + responsedata["content_type"] = "application/vnd.ll.mesh"; + responsedata["int_response_code"] = 200; + responsedata["reusecontext"] = false; + responsedata["int_lod"] = 3; + } } // Optionally add additional mesh types here else @@ -97,6 +230,8 @@ namespace OpenSim.Capabilities.Handlers responsedata["content_type"] = "text/plain"; responsedata["keepalive"] = false; responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; + responsedata["reusecontext"] = false; + responsedata["int_lod"] = 1; return responsedata; } } @@ -106,11 +241,28 @@ namespace OpenSim.Capabilities.Handlers responsedata["content_type"] = "text/plain"; responsedata["keepalive"] = false; responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; + responsedata["reusecontext"] = false; + responsedata["int_lod"] = 0; return responsedata; } } return responsedata; } + private bool TryParseRange(string header, out int start, out int end) + { + if (header.StartsWith("bytes=")) + { + string[] rangeValues = header.Substring(6).Split('-'); + if (rangeValues.Length == 2) + { + if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end)) + return true; + } + } + + start = end = 0; + return false; + } } } \ No newline at end of file diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index b3a4d61092..6437d0b7b0 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -68,7 +68,7 @@ namespace OpenSim.Capabilities.Handlers ret["content_type"] = "text/plain"; ret["keepalive"] = false; ret["reusecontext"] = false; - + ret["int_bytes"] = 0; string textureStr = (string)request["texture_id"]; string format = (string)request["format"]; @@ -200,11 +200,25 @@ namespace OpenSim.Capabilities.Handlers int start, end; if (TryParseRange(range, out start, out end)) { - // Before clamping start make sure we can satisfy it in order to avoid // sending back the last byte instead of an error status if (start >= texture.Data.Length) { +// m_log.DebugFormat( +// "[GETTEXTURE]: Client requested range for texture {0} starting at {1} but texture has end of {2}", +// texture.ID, start, texture.Data.Length); + + // Stricly speaking, as per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, we should be sending back + // Requested Range Not Satisfiable (416) here. However, it appears that at least recent implementations + // of the Linden Lab viewer (3.2.1 and 3.3.4 and probably earlier), a viewer that has previously + // received a very small texture may attempt to fetch bytes from the server past the + // range of data that it received originally. Whether this happens appears to depend on whether + // the viewer's estimation of how large a request it needs to make for certain discard levels + // (http://wiki.secondlife.com/wiki/Image_System#Discard_Level_and_Mip_Mapping), chiefly discard + // level 2. If this estimate is greater than the total texture size, returning a RequestedRangeNotSatisfiable + // here will cause the viewer to treat the texture as bad and never display the full resolution + // However, if we return PartialContent (or OK) instead, the viewer will display that resolution. + // response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; // viewers don't seem to handle RequestedRangeNotSatisfiable and keep retrying with same parameters response["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; @@ -215,7 +229,7 @@ namespace OpenSim.Capabilities.Handlers start = Utils.Clamp(start, 0, end); int len = end - start + 1; - //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); +// m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); response["content-type"] = texture.Metadata.ContentType; @@ -223,6 +237,7 @@ namespace OpenSim.Capabilities.Handlers { response["int_response_code"] = (int)System.Net.HttpStatusCode.OK; response["bin_response_data"] = texture.Data; + response["int_bytes"] = texture.Data.Length; } else { @@ -232,6 +247,7 @@ namespace OpenSim.Capabilities.Handlers byte[] d = new byte[len]; Array.Copy(texture.Data, start, d, 0, len); response["bin_response_data"] = d; + response["int_bytes"] = len; } // response.Body.Write(texture.Data, start, len); } @@ -252,6 +268,8 @@ namespace OpenSim.Capabilities.Handlers response["content_type"] = "image/" + format; response["bin_response_data"] = texture.Data; + response["int_bytes"] = texture.Data.Length; + // response.Body.Write(texture.Data, 0, texture.Data.Length); } diff --git a/OpenSim/Capabilities/Handlers/Properties/AssemblyInfo.cs b/OpenSim/Capabilities/Handlers/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..a681fb643f --- /dev/null +++ b/OpenSim/Capabilities/Handlers/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Capabilities.Handlers")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://opensimulator.org")] +[assembly: AssemblyProduct("OpenSim")] +[assembly: AssemblyCopyright("OpenSimulator developers")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("32350823-e1df-45e3-b7fa-0a58b4372433")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Capabilities/Properties/AssemblyInfo.cs b/OpenSim/Capabilities/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..26254f2fcf --- /dev/null +++ b/OpenSim/Capabilities/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Capabilities")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://opensimulator.org")] +[assembly: AssemblyProduct("OpenSim")] +[assembly: AssemblyCopyright("OpenSimulator developers")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("7d1a55b1-8fab-42ff-9c83-066a9cc34d76")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/ConsoleClient/Properties/AssemblyInfo.cs b/OpenSim/ConsoleClient/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..c240f90ca3 --- /dev/null +++ b/OpenSim/ConsoleClient/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.ConsoleClient")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://opensimulator.org")] +[assembly: AssemblyProduct("OpenSim")] +[assembly: AssemblyCopyright("OpenSimulator developers")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("8945df94-2e5e-475b-88fa-35a7cdde6fd7")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Data/IRegionData.cs b/OpenSim/Data/IRegionData.cs index 546b5e8cba..70e10653de 100644 --- a/OpenSim/Data/IRegionData.cs +++ b/OpenSim/Data/IRegionData.cs @@ -85,21 +85,6 @@ namespace OpenSim.Data List GetHyperlinks(UUID scopeID); } - [Flags] - public enum RegionFlags : int - { - DefaultRegion = 1, // Used for new Rez. Random if multiple defined - FallbackRegion = 2, // Regions we redirect to when the destination is down - RegionOnline = 4, // Set when a region comes online, unset when it unregisters and DeleteOnUnregister is false - NoDirectLogin = 8, // Region unavailable for direct logins (by name) - Persistent = 16, // Don't remove on unregister - LockedOut = 32, // Don't allow registration - NoMove = 64, // Don't allow moving this region - Reservation = 128, // This is an inactive reservation - Authenticate = 256, // Require authentication - Hyperlink = 512 // Record represents a HG link - } - public class RegionDataDistanceCompare : IComparer { private Vector2 m_origin; diff --git a/OpenSim/Data/IXInventoryData.cs b/OpenSim/Data/IXInventoryData.cs index 85a5c08d37..ca4750660a 100644 --- a/OpenSim/Data/IXInventoryData.cs +++ b/OpenSim/Data/IXInventoryData.cs @@ -40,6 +40,11 @@ namespace OpenSim.Data public UUID folderID; public UUID agentID; public UUID parentFolderID; + + public XInventoryFolder Clone() + { + return (XInventoryFolder)MemberwiseClone(); + } } public class XInventoryItem @@ -64,6 +69,11 @@ namespace OpenSim.Data public UUID avatarID; public UUID parentFolderID; public int inventoryGroupPermissions; + + public XInventoryItem Clone() + { + return (XInventoryItem)MemberwiseClone(); + } } public interface IXInventoryData @@ -106,7 +116,22 @@ namespace OpenSim.Data /// true if the delete was successful, false if it was not bool DeleteItems(string[] fields, string[] vals); - bool MoveItem(string id, string newParent); + /// + /// Move an item to another folder. + /// + /// /returns> + /// UUID of the item + /// UUID of the new parent folder. + bool MoveItem(string id, string newParentFolderID); + + /// + /// Move a folder to another folder. + /// + /// /returns> + /// UUID of the item + /// UUID of the new parent folder. + bool MoveFolder(string id, string newParentFolderID); + XInventoryItem[] GetActiveGestures(UUID principalID); int GetAssetPermissions(UUID principalID, UUID assetID); } diff --git a/OpenSim/Data/MSSQL/MSSQLRegionData.cs b/OpenSim/Data/MSSQL/MSSQLRegionData.cs index 3ae87c3804..0d89706566 100644 --- a/OpenSim/Data/MSSQL/MSSQLRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLRegionData.cs @@ -37,6 +37,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using RegionFlags = OpenSim.Framework.RegionFlags; namespace OpenSim.Data.MSSQL { diff --git a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs index a1069c69a8..e261aba300 100644 --- a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs +++ b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs @@ -43,12 +43,12 @@ namespace OpenSim.Data.MSSQL private static readonly ILog m_log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); - private MSSQLGenericTableHandler m_Folders; + private MSSQLFolderHandler m_Folders; private MSSQLItemHandler m_Items; public MSSQLXInventoryData(string conn, string realm) { - m_Folders = new MSSQLGenericTableHandler( + m_Folders = new MSSQLFolderHandler( conn, "inventoryfolders", "InventoryStore"); m_Items = new MSSQLItemHandler( conn, "inventoryitems", String.Empty); @@ -85,6 +85,7 @@ namespace OpenSim.Data.MSSQL { return m_Folders.Delete(field, val); } + public bool DeleteFolders(string[] fields, string[] vals) { return m_Folders.Delete(fields, vals); @@ -94,15 +95,22 @@ namespace OpenSim.Data.MSSQL { return m_Items.Delete(field, val); } + public bool DeleteItems(string[] fields, string[] vals) { return m_Items.Delete(fields, vals); } + public bool MoveItem(string id, string newParent) { return m_Items.MoveItem(id, newParent); } + public bool MoveFolder(string id, string newParent) + { + return m_Folders.MoveFolder(id, newParent); + } + public XInventoryItem[] GetActiveGestures(UUID principalID) { return m_Items.GetActiveGestures(principalID); @@ -114,7 +122,7 @@ namespace OpenSim.Data.MSSQL } } - public class MSSQLItemHandler : MSSQLGenericTableHandler + public class MSSQLItemHandler : MSSQLInventoryHandler { public MSSQLItemHandler(string c, string t, string m) : base(c, t, m) @@ -123,70 +131,163 @@ namespace OpenSim.Data.MSSQL public bool MoveItem(string id, string newParent) { - using (SqlConnection conn = new SqlConnection(m_ConnectionString)) - using (SqlCommand cmd = new SqlCommand()) - { + XInventoryItem[] retrievedItems = Get(new string[] { "inventoryID" }, new string[] { id }); + if (retrievedItems.Length == 0) + return false; - cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where inventoryID = @InventoryID", m_Realm); - cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParent)); - cmd.Parameters.Add(m_database.CreateParameter("@InventoryID", id)); - cmd.Connection = conn; - conn.Open(); - return cmd.ExecuteNonQuery() == 0 ? false : true; + UUID oldParent = retrievedItems[0].parentFolderID; + + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + { + using (SqlCommand cmd = new SqlCommand()) + { + + cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where inventoryID = @InventoryID", m_Realm); + cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParent)); + cmd.Parameters.Add(m_database.CreateParameter("@InventoryID", id)); + cmd.Connection = conn; + conn.Open(); + + if (cmd.ExecuteNonQuery() == 0) + return false; + } } + + IncrementFolderVersion(oldParent); + IncrementFolderVersion(newParent); + + return true; } public XInventoryItem[] GetActiveGestures(UUID principalID) { using (SqlConnection conn = new SqlConnection(m_ConnectionString)) - using (SqlCommand cmd = new SqlCommand()) { - cmd.CommandText = String.Format("select * from inventoryitems where avatarId = @uuid and assetType = @type and flags = 1", m_Realm); + using (SqlCommand cmd = new SqlCommand()) + { + cmd.CommandText = String.Format("select * from inventoryitems where avatarId = @uuid and assetType = @type and flags = 1", m_Realm); - cmd.Parameters.Add(m_database.CreateParameter("@uuid", principalID.ToString())); - cmd.Parameters.Add(m_database.CreateParameter("@type", (int)AssetType.Gesture)); - cmd.Connection = conn; - conn.Open(); - return DoQuery(cmd); + cmd.Parameters.Add(m_database.CreateParameter("@uuid", principalID.ToString())); + cmd.Parameters.Add(m_database.CreateParameter("@type", (int)AssetType.Gesture)); + cmd.Connection = conn; + conn.Open(); + return DoQuery(cmd); + } } } public int GetAssetPermissions(UUID principalID, UUID assetID) { using (SqlConnection conn = new SqlConnection(m_ConnectionString)) - using (SqlCommand cmd = new SqlCommand()) { - cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = @PrincipalID and assetID = @AssetID group by assetID", m_Realm); - cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString())); - cmd.Parameters.Add(m_database.CreateParameter("@AssetID", assetID.ToString())); - cmd.Connection = conn; - conn.Open(); - using (SqlDataReader reader = cmd.ExecuteReader()) + using (SqlCommand cmd = new SqlCommand()) { - - int perms = 0; - - if (reader.Read()) + cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = @PrincipalID and assetID = @AssetID group by assetID", m_Realm); + cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString())); + cmd.Parameters.Add(m_database.CreateParameter("@AssetID", assetID.ToString())); + cmd.Connection = conn; + conn.Open(); + using (SqlDataReader reader = cmd.ExecuteReader()) { - perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]); + + int perms = 0; + + if (reader.Read()) + { + perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]); + } + + return perms; } - return perms; } - } } + public override bool Store(XInventoryItem item) { if (!base.Store(item)) return false; - string sql = "update inventoryfolders set version=version+1 where folderID = @folderID"; - using (SqlConnection conn = new SqlConnection(m_ConnectionString)) - using (SqlCommand cmd = new SqlCommand(sql, conn)) - { - conn.Open(); - cmd.Parameters.AddWithValue("@folderID", item.parentFolderID.ToString()); + IncrementFolderVersion(item.parentFolderID); + + return true; + } + } + + public class MSSQLFolderHandler : MSSQLInventoryHandler + { + public MSSQLFolderHandler(string c, string t, string m) : + base(c, t, m) + { + } + + public bool MoveFolder(string id, string newParentFolderID) + { + XInventoryFolder[] folders = Get(new string[] { "folderID" }, new string[] { id }); + + if (folders.Length == 0) + return false; + + UUID oldParentFolderUUID = folders[0].parentFolderID; + + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + { + using (SqlCommand cmd = new SqlCommand()) + { + + cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where folderID = @folderID", m_Realm); + cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParentFolderID)); + cmd.Parameters.Add(m_database.CreateParameter("@folderID", id)); + cmd.Connection = conn; + conn.Open(); + + if (cmd.ExecuteNonQuery() == 0) + return false; + } + } + + IncrementFolderVersion(oldParentFolderUUID); + IncrementFolderVersion(newParentFolderID); + + return true; + } + + public override bool Store(XInventoryFolder folder) + { + if (!base.Store(folder)) + return false; + + IncrementFolderVersion(folder.parentFolderID); + + return true; + } + } + + public class MSSQLInventoryHandler : MSSQLGenericTableHandler where T: class, new() + { + public MSSQLInventoryHandler(string c, string t, string m) : base(c, t, m) {} + + protected bool IncrementFolderVersion(UUID folderID) + { + return IncrementFolderVersion(folderID.ToString()); + } + + protected bool IncrementFolderVersion(string folderID) + { +// m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID); +// Util.PrintCallStack(); + + string sql = "update inventoryfolders set version=version+1 where folderID = ?folderID"; + + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + { + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + conn.Open(); + + cmd.Parameters.AddWithValue("@folderID", folderID); + try { cmd.ExecuteNonQuery(); @@ -194,9 +295,11 @@ namespace OpenSim.Data.MSSQL catch (Exception) { return false; - } + } + } } + return true; } } -} +} \ No newline at end of file diff --git a/OpenSim/Data/MSSQL/Properties/AssemblyInfo.cs b/OpenSim/Data/MSSQL/Properties/AssemblyInfo.cs index e045d75d12..1a67e704e5 100644 --- a/OpenSim/Data/MSSQL/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/MSSQL/Properties/AssemblyInfo.cs @@ -61,5 +61,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly : AssemblyVersion("0.6.5.*")] +[assembly : AssemblyVersion("0.7.5.*")] [assembly : AssemblyFileVersion("0.6.5.0")] diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index 86367a130a..f6731c0fa1 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs @@ -224,6 +224,8 @@ namespace OpenSim.Data.MySQL public virtual bool Store(T row) { +// m_log.DebugFormat("[MYSQL GENERIC TABLE HANDLER]: Store(T row) invoked"); + using (MySqlCommand cmd = new MySqlCommand()) { string query = ""; @@ -278,6 +280,10 @@ namespace OpenSim.Data.MySQL public virtual bool Delete(string[] fields, string[] keys) { +// m_log.DebugFormat( +// "[MYSQL GENERIC TABLE HANDLER]: Delete(string[] fields, string[] keys) invoked with {0}:{1}", +// string.Join(",", fields), string.Join(",", keys)); + if (fields.Length != keys.Length) return false; diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index 0614879061..a2d4ae4647 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -30,11 +30,11 @@ using System.Collections; using System.Collections.Generic; using System.Data; using System.Reflection; - +using MySql.Data.MySqlClient; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Data; -using MySql.Data.MySqlClient; +using RegionFlags = OpenSim.Framework.RegionFlags; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 4d7c0c937c..12c979aa50 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -747,95 +747,99 @@ namespace OpenSim.Data.MySQL RegionLightShareData nWP = new RegionLightShareData(); nWP.OnSave += StoreRegionWindlightSettings; - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + lock (m_dbLock) { - dbcon.Open(); - - string command = "select * from `regionwindlight` where region_id = ?regionID"; - - using (MySqlCommand cmd = new MySqlCommand(command)) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.Connection = dbcon; - - cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString()); - - IDataReader result = ExecuteReader(cmd); - if (!result.Read()) + dbcon.Open(); + + string command = "select * from `regionwindlight` where region_id = ?regionID"; + + using (MySqlCommand cmd = new MySqlCommand(command)) { - //No result, so store our default windlight profile and return it - nWP.regionID = regionUUID; - // StoreRegionWindlightSettings(nWP); - return nWP; - } - else - { - nWP.regionID = DBGuid.FromDB(result["region_id"]); - nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); - nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); - nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); - nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); - nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); - nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); - nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); - nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); - nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); - nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); - nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); - nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); - nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); - nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); - nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); - nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); - nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); - UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture); - nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); - nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); - nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); - nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); - nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); - nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); - nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); - nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); - nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); - nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); - nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); - nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); - nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); - nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); - nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); - nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); - nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); - nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); - nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); - nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); - nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); - nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); - nWP.eastAngle = Convert.ToSingle(result["east_angle"]); - nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); - nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); - nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); - nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); - nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); - nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); - nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); - nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); - nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); - nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); - nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); - nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); - nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); - nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); - nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); - nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); - nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); - nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); - nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); - nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); - nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); - nWP.valid = true; + cmd.Connection = dbcon; + + cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString()); + + IDataReader result = ExecuteReader(cmd); + if (!result.Read()) + { + //No result, so store our default windlight profile and return it + nWP.regionID = regionUUID; +// StoreRegionWindlightSettings(nWP); + return nWP; + } + else + { + nWP.regionID = DBGuid.FromDB(result["region_id"]); + nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); + nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); + nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); + nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); + nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); + nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); + nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); + nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); + nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); + nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); + nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); + nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); + nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); + nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); + nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); + nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); + nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); + UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture); + nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); + nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); + nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); + nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); + nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); + nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); + nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); + nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); + nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); + nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); + nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); + nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); + nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); + nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); + nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); + nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); + nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); + nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); + nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); + nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); + nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); + nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); + nWP.eastAngle = Convert.ToSingle(result["east_angle"]); + nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); + nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); + nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); + nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); + nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); + nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); + nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); + nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); + nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); + nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); + nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); + nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); + nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); + nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); + nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); + nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); + nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); + nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); + nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); + nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); + nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); + nWP.valid = true; + } } } } + return nWP; } @@ -881,118 +885,124 @@ namespace OpenSim.Data.MySQL public virtual void StoreRegionWindlightSettings(RegionLightShareData wl) { - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + lock (m_dbLock) { - dbcon.Open(); - - using (MySqlCommand cmd = dbcon.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, "; - cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, "; - cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, "; - cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, "; - cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, "; - cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, "; - cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, "; - cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, "; - cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, "; - cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, "; - cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, "; - cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, "; - cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, "; - cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, "; - cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, "; - cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, "; - cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, "; - cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, "; - cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, "; - cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, "; - cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, "; - cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, "; - cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, "; - cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, "; - cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)"; - - cmd.Parameters.AddWithValue("region_id", wl.regionID); - cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X); - cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y); - cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z); - cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent); - cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier); - cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X); - cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y); - cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z); - cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale); - cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset); - cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove); - cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow); - cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier); - cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X); - cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y); - cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X); - cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y); - cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture); - cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X); - cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y); - cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z); - cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W); - cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon); - cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X); - cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y); - cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z); - cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W); - cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity); - cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier); - cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier); - cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude); - cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X); - cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y); - cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z); - cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W); - cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition); - cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X); - cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y); - cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z); - cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W); - cmd.Parameters.AddWithValue("east_angle", wl.eastAngle); - cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus); - cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize); - cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma); - cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness); - cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X); - cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y); - cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z); - cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W); - cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X); - cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y); - cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z); - cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage); - cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale); - cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X); - cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y); - cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z); - cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX); - cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock); - cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY); - cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock); - cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds); - - ExecuteNonQuery(cmd); + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, "; + cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, "; + cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, "; + cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, "; + cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, "; + cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, "; + cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, "; + cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, "; + cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, "; + cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, "; + cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, "; + cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, "; + cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, "; + cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, "; + cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, "; + cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, "; + cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, "; + cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, "; + cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, "; + cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, "; + cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, "; + cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, "; + cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, "; + cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, "; + cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)"; + + cmd.Parameters.AddWithValue("region_id", wl.regionID); + cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X); + cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y); + cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z); + cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent); + cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier); + cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X); + cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y); + cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z); + cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale); + cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset); + cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove); + cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow); + cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier); + cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X); + cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y); + cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X); + cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y); + cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture); + cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X); + cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y); + cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z); + cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W); + cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon); + cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X); + cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y); + cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z); + cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W); + cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity); + cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier); + cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier); + cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude); + cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X); + cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y); + cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z); + cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W); + cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition); + cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X); + cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y); + cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z); + cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W); + cmd.Parameters.AddWithValue("east_angle", wl.eastAngle); + cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus); + cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize); + cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma); + cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness); + cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X); + cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y); + cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z); + cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W); + cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X); + cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y); + cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z); + cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage); + cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale); + cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X); + cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y); + cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z); + cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX); + cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock); + cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY); + cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock); + cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds); + + ExecuteNonQuery(cmd); + } } } } public virtual void RemoveRegionWindlightSettings(UUID regionID) { - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + lock (m_dbLock) { - dbcon.Open(); - - using (MySqlCommand cmd = dbcon.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID"; - cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); - ExecuteNonQuery(cmd); + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID"; + cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); + ExecuteNonQuery(cmd); + } } } } @@ -1000,26 +1010,29 @@ namespace OpenSim.Data.MySQL #region RegionEnvironmentSettings public string LoadRegionEnvironmentSettings(UUID regionUUID) { - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + lock (m_dbLock) { - dbcon.Open(); - - string command = "select * from `regionenvironment` where region_id = ?region_id"; - - using (MySqlCommand cmd = new MySqlCommand(command)) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.Connection = dbcon; - - cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); - - IDataReader result = ExecuteReader(cmd); - if (!result.Read()) + dbcon.Open(); + + string command = "select * from `regionenvironment` where region_id = ?region_id"; + + using (MySqlCommand cmd = new MySqlCommand(command)) { - return String.Empty; - } - else - { - return Convert.ToString(result["llsd_settings"]); + 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"]); + } } } } @@ -1027,33 +1040,39 @@ namespace OpenSim.Data.MySQL public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) { - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + lock (m_dbLock) { - dbcon.Open(); - - using (MySqlCommand cmd = dbcon.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - 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); + 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)) + lock (m_dbLock) { - dbcon.Open(); - - using (MySqlCommand cmd = dbcon.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id"; - cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); - ExecuteNonQuery(cmd); + 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); + } } } } diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs index caf18a4780..c74033eefc 100644 --- a/OpenSim/Data/MySQL/MySQLXInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs @@ -26,9 +26,10 @@ */ using System; -using System.Data; -using System.Reflection; using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Reflection; using log4net; using MySql.Data.MySqlClient; using OpenMetaverse; @@ -41,12 +42,12 @@ namespace OpenSim.Data.MySQL /// public class MySQLXInventoryData : IXInventoryData { - private MySQLGenericTableHandler m_Folders; + private MySqlFolderHandler m_Folders; private MySqlItemHandler m_Items; public MySQLXInventoryData(string conn, string realm) { - m_Folders = new MySQLGenericTableHandler( + m_Folders = new MySqlFolderHandler( conn, "inventoryfolders", "InventoryStore"); m_Items = new MySqlItemHandler( conn, "inventoryitems", String.Empty); @@ -105,6 +106,11 @@ namespace OpenSim.Data.MySQL return m_Items.MoveItem(id, newParent); } + public bool MoveFolder(string id, string newParent) + { + return m_Folders.MoveFolder(id, newParent); + } + public XInventoryItem[] GetActiveGestures(UUID principalID) { return m_Items.GetActiveGestures(principalID); @@ -116,24 +122,71 @@ namespace OpenSim.Data.MySQL } } - public class MySqlItemHandler : MySQLGenericTableHandler + public class MySqlItemHandler : MySqlInventoryHandler { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public MySqlItemHandler(string c, string t, string m) : base(c, t, m) { } + public override bool Delete(string field, string val) + { + XInventoryItem[] retrievedItems = Get(new string[] { field }, new string[] { val }); + if (retrievedItems.Length == 0) + return false; + + if (!base.Delete(field, val)) + return false; + + // Don't increment folder version here since Delete(string, string) calls Delete(string[], string[]) +// IncrementFolderVersion(retrievedItems[0].parentFolderID); + + return true; + } + + public override bool Delete(string[] fields, string[] vals) + { + XInventoryItem[] retrievedItems = Get(fields, vals); + if (retrievedItems.Length == 0) + return false; + + if (!base.Delete(fields, vals)) + return false; + + HashSet deletedItemFolderUUIDs = new HashSet(); + + Array.ForEach(retrievedItems, i => deletedItemFolderUUIDs.Add(i.parentFolderID)); + + foreach (UUID deletedItemFolderUUID in deletedItemFolderUUIDs) + IncrementFolderVersion(deletedItemFolderUUID); + + return true; + } + public bool MoveItem(string id, string newParent) { + XInventoryItem[] retrievedItems = Get(new string[] { "inventoryID" }, new string[] { id }); + if (retrievedItems.Length == 0) + return false; + + UUID oldParent = retrievedItems[0].parentFolderID; + using (MySqlCommand cmd = new MySqlCommand()) { - cmd.CommandText = String.Format("update {0} set parentFolderID = ?ParentFolderID where inventoryID = ?InventoryID", m_Realm); cmd.Parameters.AddWithValue("?ParentFolderID", newParent); cmd.Parameters.AddWithValue("?InventoryID", id); - return ExecuteNonQuery(cmd) == 0 ? false : true; + if (ExecuteNonQuery(cmd) == 0) + return false; } + + IncrementFolderVersion(oldParent); + IncrementFolderVersion(newParent); + + return true; } public XInventoryItem[] GetActiveGestures(UUID principalID) @@ -184,6 +237,73 @@ namespace OpenSim.Data.MySQL if (!base.Store(item)) return false; + IncrementFolderVersion(item.parentFolderID); + + return true; + } + } + + public class MySqlFolderHandler : MySqlInventoryHandler + { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public MySqlFolderHandler(string c, string t, string m) : + base(c, t, m) + { + } + + public bool MoveFolder(string id, string newParentFolderID) + { + XInventoryFolder[] folders = Get(new string[] { "folderID" }, new string[] { id }); + + if (folders.Length == 0) + return false; + + UUID oldParentFolderUUID = folders[0].parentFolderID; + + using (MySqlCommand cmd = new MySqlCommand()) + { + cmd.CommandText + = String.Format( + "update {0} set parentFolderID = ?ParentFolderID where folderID = ?folderID", m_Realm); + cmd.Parameters.AddWithValue("?ParentFolderID", newParentFolderID); + cmd.Parameters.AddWithValue("?folderID", id); + + if (ExecuteNonQuery(cmd) == 0) + return false; + } + + IncrementFolderVersion(oldParentFolderUUID); + IncrementFolderVersion(newParentFolderID); + + return true; + } + + public override bool Store(XInventoryFolder folder) + { + if (!base.Store(folder)) + return false; + + IncrementFolderVersion(folder.parentFolderID); + + return true; + } + } + + public class MySqlInventoryHandler : MySQLGenericTableHandler where T: class, new() + { + public MySqlInventoryHandler(string c, string t, string m) : base(c, t, m) {} + + protected bool IncrementFolderVersion(UUID folderID) + { + return IncrementFolderVersion(folderID.ToString()); + } + + protected bool IncrementFolderVersion(string folderID) + { +// m_log.DebugFormat("[MYSQL FOLDER HANDLER]: Incrementing version on folder {0}", folderID); +// Util.PrintCallStack(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); @@ -193,7 +313,7 @@ namespace OpenSim.Data.MySQL cmd.Connection = dbcon; cmd.CommandText = String.Format("update inventoryfolders set version=version+1 where folderID = ?folderID"); - cmd.Parameters.AddWithValue("?folderID", item.parentFolderID.ToString()); + cmd.Parameters.AddWithValue("?folderID", folderID); try { @@ -205,9 +325,11 @@ namespace OpenSim.Data.MySQL } cmd.Dispose(); } + dbcon.Close(); } + return true; } } -} +} \ No newline at end of file diff --git a/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs b/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs index c28829caa3..ab3fe36e52 100644 --- a/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs @@ -61,5 +61,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly : AssemblyVersion("0.6.5.*")] +[assembly : AssemblyVersion("0.7.5.*")] [assembly : AssemblyFileVersion("0.6.5.0")] diff --git a/OpenSim/Data/MySQL/Resources/GridUserStore.migrations b/OpenSim/Data/MySQL/Resources/GridUserStore.migrations index 32b85ee8c1..d08e096364 100644 --- a/OpenSim/Data/MySQL/Resources/GridUserStore.migrations +++ b/OpenSim/Data/MySQL/Resources/GridUserStore.migrations @@ -17,3 +17,8 @@ CREATE TABLE `GridUser` ( ) ENGINE=InnoDB; COMMIT; + +:VERSION 2 # -------------------------- +BEGIN; + +COMMIT; diff --git a/OpenSim/Data/Null/NullRegionData.cs b/OpenSim/Data/Null/NullRegionData.cs index deb50cb4df..b4d701af50 100644 --- a/OpenSim/Data/Null/NullRegionData.cs +++ b/OpenSim/Data/Null/NullRegionData.cs @@ -33,6 +33,7 @@ using OpenSim.Framework; using OpenSim.Data; using System.Reflection; using log4net; +using RegionFlags = OpenSim.Framework.RegionFlags; namespace OpenSim.Data.Null { diff --git a/OpenSim/Data/Null/Properties/AssemblyInfo.cs b/OpenSim/Data/Null/Properties/AssemblyInfo.cs index 4b644363dc..43b0bb3214 100644 --- a/OpenSim/Data/Null/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/Null/Properties/AssemblyInfo.cs @@ -61,5 +61,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly : AssemblyVersion("0.6.5.*")] +[assembly : AssemblyVersion("0.7.5.*")] [assembly : AssemblyFileVersion("0.6.5.0")] diff --git a/OpenSim/Data/Properties/AssemblyInfo.cs b/OpenSim/Data/Properties/AssemblyInfo.cs index 6940d2579b..0da1a6b799 100644 --- a/OpenSim/Data/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/Properties/AssemblyInfo.cs @@ -61,5 +61,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly : AssemblyVersion("0.6.5.*")] +[assembly : AssemblyVersion("0.7.5.*")] [assembly : AssemblyFileVersion("0.6.5.0")] diff --git a/OpenSim/Data/SQLite/Properties/AssemblyInfo.cs b/OpenSim/Data/SQLite/Properties/AssemblyInfo.cs index d45ab5092a..c9a8553de6 100644 --- a/OpenSim/Data/SQLite/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/SQLite/Properties/AssemblyInfo.cs @@ -61,5 +61,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly : AssemblyVersion("0.6.5.*")] +[assembly : AssemblyVersion("0.7.5.*")] [assembly : AssemblyFileVersion("0.6.5.0")] diff --git a/OpenSim/Data/SQLite/SQLiteAssetData.cs b/OpenSim/Data/SQLite/SQLiteAssetData.cs index 7f7059b0d9..b94a58cc3d 100644 --- a/OpenSim/Data/SQLite/SQLiteAssetData.cs +++ b/OpenSim/Data/SQLite/SQLiteAssetData.cs @@ -204,7 +204,8 @@ namespace OpenSim.Data.SQLite /// True if exist, or false. override public bool ExistsAsset(UUID uuid) { - lock (this) { + lock (this) + { using (SqliteCommand cmd = new SqliteCommand(SelectAssetSQL, m_conn)) { cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString())); @@ -355,12 +356,13 @@ namespace OpenSim.Data.SQLite { lock (this) { - using (SqliteCommand cmd = new SqliteCommand(DeleteAssetSQL, m_conn)) - { - cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString())); - cmd.ExecuteNonQuery(); - } + using (SqliteCommand cmd = new SqliteCommand(DeleteAssetSQL, m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString())); + cmd.ExecuteNonQuery(); + } } + return true; } diff --git a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs index 5120453d1b..0428c11f76 100644 --- a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs +++ b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs @@ -82,11 +82,14 @@ namespace OpenSim.Data.SQLite { AuthenticationData ret = new AuthenticationData(); ret.Data = new Dictionary(); + IDataReader result; - SqliteCommand cmd = new SqliteCommand("select * from `" + m_Realm + "` where UUID = :PrincipalID"); - cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString())); + using (SqliteCommand cmd = new SqliteCommand("select * from `" + m_Realm + "` where UUID = :PrincipalID")) + { + cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString())); - IDataReader result = ExecuteReader(cmd, m_Connection); + result = ExecuteReader(cmd, m_Connection); + } try { @@ -121,10 +124,6 @@ namespace OpenSim.Data.SQLite catch { } - finally - { - //CloseCommand(cmd); - } return null; } @@ -140,84 +139,81 @@ namespace OpenSim.Data.SQLite foreach (object o in data.Data.Values) values[i++] = o.ToString(); - SqliteCommand cmd = new SqliteCommand(); - - if (Get(data.PrincipalID) != null) + using (SqliteCommand cmd = new SqliteCommand()) { - - - string update = "update `" + m_Realm + "` set "; - bool first = true; - foreach (string field in fields) + if (Get(data.PrincipalID) != null) { - if (!first) - update += ", "; - update += "`" + field + "` = :" + field; - cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field])); - first = false; - } - update += " where UUID = :UUID"; - cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString())); - - cmd.CommandText = update; - try - { - if (ExecuteNonQuery(cmd, m_Connection) < 1) + string update = "update `" + m_Realm + "` set "; + bool first = true; + foreach (string field in fields) { + if (!first) + update += ", "; + update += "`" + field + "` = :" + field; + cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field])); + + first = false; + } + + update += " where UUID = :UUID"; + cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString())); + + cmd.CommandText = update; + try + { + if (ExecuteNonQuery(cmd, m_Connection) < 1) + { + //CloseCommand(cmd); + return false; + } + } + catch (Exception e) + { + m_log.Error("[SQLITE]: Exception storing authentication data", e); //CloseCommand(cmd); return false; } } - catch (Exception e) + else { - m_log.Error("[SQLITE]: Exception storing authentication data", e); - //CloseCommand(cmd); - return false; - } - } + string insert = "insert into `" + m_Realm + "` (`UUID`, `" + + String.Join("`, `", fields) + + "`) values (:UUID, :" + String.Join(", :", fields) + ")"; - else - { - string insert = "insert into `" + m_Realm + "` (`UUID`, `" + - String.Join("`, `", fields) + - "`) values (:UUID, :" + String.Join(", :", fields) + ")"; + cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString())); + foreach (string field in fields) + cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field])); - cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString())); - foreach (string field in fields) - cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field])); + cmd.CommandText = insert; - cmd.CommandText = insert; - - try - { - if (ExecuteNonQuery(cmd, m_Connection) < 1) + try { - //CloseCommand(cmd); + if (ExecuteNonQuery(cmd, m_Connection) < 1) + { + return false; + } + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); return false; } } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - //CloseCommand(cmd); - return false; - } } - //CloseCommand(cmd); - return true; } public bool SetDataItem(UUID principalID, string item, string value) { - SqliteCommand cmd = new SqliteCommand("update `" + m_Realm + - "` set `" + item + "` = " + value + " where UUID = '" + principalID.ToString() + "'"); - - if (ExecuteNonQuery(cmd, m_Connection) > 0) - return true; + using (SqliteCommand cmd = new SqliteCommand("update `" + m_Realm + + "` set `" + item + "` = " + value + " where UUID = '" + principalID.ToString() + "'")) + { + if (ExecuteNonQuery(cmd, m_Connection) > 0) + return true; + } return false; } @@ -227,16 +223,13 @@ namespace OpenSim.Data.SQLite if (System.Environment.TickCount - m_LastExpire > 30000) DoExpire(); - SqliteCommand cmd = new SqliteCommand("insert into tokens (UUID, token, validity) values ('" + principalID.ToString() + - "', '" + token + "', datetime('now', 'localtime', '+" + lifetime.ToString() + " minutes'))"); - - if (ExecuteNonQuery(cmd, m_Connection) > 0) + using (SqliteCommand cmd = new SqliteCommand("insert into tokens (UUID, token, validity) values ('" + principalID.ToString() + + "', '" + token + "', datetime('now', 'localtime', '+" + lifetime.ToString() + " minutes'))")) { - cmd.Dispose(); - return true; + if (ExecuteNonQuery(cmd, m_Connection) > 0) + return true; } - cmd.Dispose(); return false; } @@ -245,28 +238,22 @@ namespace OpenSim.Data.SQLite if (System.Environment.TickCount - m_LastExpire > 30000) DoExpire(); - SqliteCommand cmd = new SqliteCommand("update tokens set validity = datetime('now', 'localtime', '+" + lifetime.ToString() + - " minutes') where UUID = '" + principalID.ToString() + "' and token = '" + token + "' and validity > datetime('now', 'localtime')"); - - if (ExecuteNonQuery(cmd, m_Connection) > 0) + using (SqliteCommand cmd = new SqliteCommand("update tokens set validity = datetime('now', 'localtime', '+" + lifetime.ToString() + + " minutes') where UUID = '" + principalID.ToString() + "' and token = '" + token + "' and validity > datetime('now', 'localtime')")) { - cmd.Dispose(); - return true; + if (ExecuteNonQuery(cmd, m_Connection) > 0) + return true; } - cmd.Dispose(); - return false; } private void DoExpire() { - SqliteCommand cmd = new SqliteCommand("delete from tokens where validity < datetime('now', 'localtime')"); - ExecuteNonQuery(cmd, m_Connection); - - cmd.Dispose(); + using (SqliteCommand cmd = new SqliteCommand("delete from tokens where validity < datetime('now', 'localtime')")) + ExecuteNonQuery(cmd, m_Connection); m_LastExpire = System.Environment.TickCount; } } -} +} \ No newline at end of file diff --git a/OpenSim/Data/SQLite/SQLiteAvatarData.cs b/OpenSim/Data/SQLite/SQLiteAvatarData.cs index faf34da573..c6d615be14 100644 --- a/OpenSim/Data/SQLite/SQLiteAvatarData.cs +++ b/OpenSim/Data/SQLite/SQLiteAvatarData.cs @@ -56,23 +56,17 @@ namespace OpenSim.Data.SQLite public bool Delete(UUID principalID, string name) { - SqliteCommand cmd = new SqliteCommand(); - - 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); - - try + using (SqliteCommand cmd = new SqliteCommand()) { + 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, m_Connection) > 0) return true; + } - return false; - } - finally - { - //CloseCommand(cmd); - } + return false; } } -} +} \ No newline at end of file diff --git a/OpenSim/Data/SQLite/SQLiteEstateData.cs b/OpenSim/Data/SQLite/SQLiteEstateData.cs index c042ba2bd3..d51f2d413d 100644 --- a/OpenSim/Data/SQLite/SQLiteEstateData.cs +++ b/OpenSim/Data/SQLite/SQLiteEstateData.cs @@ -104,12 +104,13 @@ namespace OpenSim.Data.SQLite { string sql = "select estate_settings."+String.Join(",estate_settings.", FieldList)+" from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = :RegionID"; - SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); + using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) + { + cmd.CommandText = sql; + cmd.Parameters.AddWithValue(":RegionID", regionID.ToString()); - cmd.CommandText = sql; - cmd.Parameters.AddWithValue(":RegionID", regionID.ToString()); - - return DoLoad(cmd, regionID, create); + return DoLoad(cmd, regionID, create); + } } private EstateSettings DoLoad(SqliteCommand cmd, UUID regionID, bool create) @@ -186,38 +187,40 @@ namespace OpenSim.Data.SQLite { List names = new List(FieldList); - SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); IDataReader r = null; - names.Remove("EstateID"); + using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) + { + names.Remove("EstateID"); - string sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")"; + string sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")"; - cmd.CommandText = sql; - cmd.Parameters.Clear(); + cmd.CommandText = sql; + cmd.Parameters.Clear(); - foreach (string name in FieldList) - { - if (m_FieldMap[name].GetValue(es) is bool) + foreach (string name in FieldList) { - if ((bool)m_FieldMap[name].GetValue(es)) - cmd.Parameters.AddWithValue(":"+name, "1"); + if (m_FieldMap[name].GetValue(es) is bool) + { + if ((bool)m_FieldMap[name].GetValue(es)) + cmd.Parameters.AddWithValue(":"+name, "1"); + else + cmd.Parameters.AddWithValue(":"+name, "0"); + } else - cmd.Parameters.AddWithValue(":"+name, "0"); - } - else - { - cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString()); + { + cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString()); + } } + + cmd.ExecuteNonQuery(); + + cmd.CommandText = "select LAST_INSERT_ROWID() as id"; + cmd.Parameters.Clear(); + + r = cmd.ExecuteReader(); } - cmd.ExecuteNonQuery(); - - cmd.CommandText = "select LAST_INSERT_ROWID() as id"; - cmd.Parameters.Clear(); - - r = cmd.ExecuteReader(); - r.Read(); es.EstateID = Convert.ToUInt32(r["id"]); @@ -239,26 +242,27 @@ namespace OpenSim.Data.SQLite string sql = "update estate_settings set "+String.Join(", ", terms.ToArray())+" where EstateID = :EstateID"; - SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); - - cmd.CommandText = sql; - - foreach (string name in FieldList) + using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) { - if (m_FieldMap[name].GetValue(es) is bool) - { - if ((bool)m_FieldMap[name].GetValue(es)) - cmd.Parameters.AddWithValue(":"+name, "1"); - else - cmd.Parameters.AddWithValue(":"+name, "0"); - } - else - { - cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString()); - } - } + cmd.CommandText = sql; - cmd.ExecuteNonQuery(); + foreach (string name in FieldList) + { + if (m_FieldMap[name].GetValue(es) is bool) + { + if ((bool)m_FieldMap[name].GetValue(es)) + cmd.Parameters.AddWithValue(":"+name, "1"); + else + cmd.Parameters.AddWithValue(":"+name, "0"); + } + else + { + cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString()); + } + } + + cmd.ExecuteNonQuery(); + } SaveBanList(es); SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers); @@ -270,12 +274,15 @@ namespace OpenSim.Data.SQLite { es.ClearBans(); - SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); + IDataReader r; - cmd.CommandText = "select bannedUUID from estateban where EstateID = :EstateID"; - cmd.Parameters.AddWithValue(":EstateID", es.EstateID); + using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) + { + cmd.CommandText = "select bannedUUID from estateban where EstateID = :EstateID"; + cmd.Parameters.AddWithValue(":EstateID", es.EstateID); - IDataReader r = cmd.ExecuteReader(); + r = cmd.ExecuteReader(); + } while (r.Read()) { @@ -294,60 +301,64 @@ namespace OpenSim.Data.SQLite private void SaveBanList(EstateSettings es) { - SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); - - cmd.CommandText = "delete from estateban where EstateID = :EstateID"; - cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString()); - - cmd.ExecuteNonQuery(); - - cmd.Parameters.Clear(); - - cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( :EstateID, :bannedUUID, '', '', '' )"; - - foreach (EstateBan b in es.EstateBans) + using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) { + cmd.CommandText = "delete from estateban where EstateID = :EstateID"; cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString()); - cmd.Parameters.AddWithValue(":bannedUUID", b.BannedUserID.ToString()); cmd.ExecuteNonQuery(); + cmd.Parameters.Clear(); + + cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( :EstateID, :bannedUUID, '', '', '' )"; + + foreach (EstateBan b in es.EstateBans) + { + cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString()); + cmd.Parameters.AddWithValue(":bannedUUID", b.BannedUserID.ToString()); + + cmd.ExecuteNonQuery(); + cmd.Parameters.Clear(); + } } } void SaveUUIDList(uint EstateID, string table, UUID[] data) { - SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); - - cmd.CommandText = "delete from "+table+" where EstateID = :EstateID"; - cmd.Parameters.AddWithValue(":EstateID", EstateID.ToString()); - - cmd.ExecuteNonQuery(); - - cmd.Parameters.Clear(); - - cmd.CommandText = "insert into "+table+" (EstateID, uuid) values ( :EstateID, :uuid )"; - - foreach (UUID uuid in data) + using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) { + cmd.CommandText = "delete from "+table+" where EstateID = :EstateID"; cmd.Parameters.AddWithValue(":EstateID", EstateID.ToString()); - cmd.Parameters.AddWithValue(":uuid", uuid.ToString()); cmd.ExecuteNonQuery(); + cmd.Parameters.Clear(); + + cmd.CommandText = "insert into "+table+" (EstateID, uuid) values ( :EstateID, :uuid )"; + + foreach (UUID uuid in data) + { + cmd.Parameters.AddWithValue(":EstateID", EstateID.ToString()); + cmd.Parameters.AddWithValue(":uuid", uuid.ToString()); + + cmd.ExecuteNonQuery(); + cmd.Parameters.Clear(); + } } } UUID[] LoadUUIDList(uint EstateID, string table) { List uuids = new List(); + IDataReader r; - SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); + using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) + { + cmd.CommandText = "select uuid from "+table+" where EstateID = :EstateID"; + cmd.Parameters.AddWithValue(":EstateID", EstateID); - cmd.CommandText = "select uuid from "+table+" where EstateID = :EstateID"; - cmd.Parameters.AddWithValue(":EstateID", EstateID); - - IDataReader r = cmd.ExecuteReader(); + r = cmd.ExecuteReader(); + } while (r.Read()) { @@ -367,12 +378,13 @@ namespace OpenSim.Data.SQLite { string sql = "select estate_settings."+String.Join(",estate_settings.", FieldList)+" from estate_settings where estate_settings.EstateID = :EstateID"; - SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); + using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) + { + cmd.CommandText = sql; + cmd.Parameters.AddWithValue(":EstateID", estateID.ToString()); - cmd.CommandText = sql; - cmd.Parameters.AddWithValue(":EstateID", estateID.ToString()); - - return DoLoad(cmd, UUID.Zero, false); + return DoLoad(cmd, UUID.Zero, false); + } } public List LoadEstateSettingsAll() @@ -391,13 +403,15 @@ namespace OpenSim.Data.SQLite List result = new List(); string sql = "select EstateID from estate_settings where estate_settings.EstateName = :EstateName"; + IDataReader r; - SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); + using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) + { + cmd.CommandText = sql; + cmd.Parameters.AddWithValue(":EstateName", search); - cmd.CommandText = sql; - cmd.Parameters.AddWithValue(":EstateName", search); - - IDataReader r = cmd.ExecuteReader(); + r = cmd.ExecuteReader(); + } while (r.Read()) { @@ -413,12 +427,14 @@ namespace OpenSim.Data.SQLite List result = new List(); string sql = "select EstateID from estate_settings"; + IDataReader r; - SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); + using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) + { + cmd.CommandText = sql; - cmd.CommandText = sql; - - IDataReader r = cmd.ExecuteReader(); + r = cmd.ExecuteReader(); + } while (r.Read()) { @@ -434,13 +450,15 @@ namespace OpenSim.Data.SQLite List result = new List(); string sql = "select EstateID from estate_settings where estate_settings.EstateOwner = :EstateOwner"; + IDataReader r; - SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); + using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) + { + cmd.CommandText = sql; + cmd.Parameters.AddWithValue(":EstateOwner", ownerID); - cmd.CommandText = sql; - cmd.Parameters.AddWithValue(":EstateOwner", ownerID); - - IDataReader r = cmd.ExecuteReader(); + r = cmd.ExecuteReader(); + } while (r.Read()) { diff --git a/OpenSim/Data/SQLite/SQLiteFramework.cs b/OpenSim/Data/SQLite/SQLiteFramework.cs index 159471723e..35b9a2fe31 100644 --- a/OpenSim/Data/SQLite/SQLiteFramework.cs +++ b/OpenSim/Data/SQLite/SQLiteFramework.cs @@ -90,12 +90,5 @@ namespace OpenSim.Data.SQLite return cmd.ExecuteReader(); } } - - protected void CloseCommand(SqliteCommand cmd) - { - cmd.Connection.Close(); - cmd.Connection.Dispose(); - cmd.Dispose(); - } } -} +} \ No newline at end of file diff --git a/OpenSim/Data/SQLite/SQLiteFriendsData.cs b/OpenSim/Data/SQLite/SQLiteFriendsData.cs index 5f68977c1f..cab85eb703 100644 --- a/OpenSim/Data/SQLite/SQLiteFriendsData.cs +++ b/OpenSim/Data/SQLite/SQLiteFriendsData.cs @@ -53,13 +53,13 @@ namespace OpenSim.Data.SQLite public FriendsData[] GetFriends(string userID) { - SqliteCommand cmd = new SqliteCommand(); - - 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", userID.ToString()); - - return DoQuery(cmd); + using (SqliteCommand cmd = new SqliteCommand()) + { + 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", userID.ToString()); + return DoQuery(cmd); + } } public bool Delete(UUID principalID, string friend) @@ -69,13 +69,14 @@ namespace OpenSim.Data.SQLite public bool Delete(string principalID, string friend) { - SqliteCommand cmd = new SqliteCommand(); + using (SqliteCommand cmd = new SqliteCommand()) + { + 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, m_Connection); + ExecuteNonQuery(cmd, m_Connection); + } return true; } diff --git a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs index 4f977a80e8..9fbeb100ce 100644 --- a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs +++ b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs @@ -120,34 +120,35 @@ namespace OpenSim.Data.SQLite } } - public T[] Get(string field, string key) + public virtual T[] Get(string field, string key) { return Get(new string[] { field }, new string[] { key }); } - public T[] Get(string[] fields, string[] keys) + public virtual T[] Get(string[] fields, string[] keys) { if (fields.Length != keys.Length) return new T[0]; List terms = new List(); - SqliteCommand cmd = new SqliteCommand(); - - for (int i = 0 ; i < fields.Length ; i++) + using (SqliteCommand cmd = new SqliteCommand()) { - cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i])); - terms.Add("`" + fields[i] + "` = :" + fields[i]); + for (int i = 0 ; i < fields.Length ; i++) + { + cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i])); + terms.Add("`" + fields[i] + "` = :" + fields[i]); + } + + string where = String.Join(" and ", terms.ToArray()); + + string query = String.Format("select * from {0} where {1}", + m_Realm, where); + + cmd.CommandText = query; + + return DoQuery(cmd); } - - string where = String.Join(" and ", terms.ToArray()); - - string query = String.Format("select * from {0} where {1}", - m_Realm, where); - - cmd.CommandText = query; - - return DoQuery(cmd); } protected T[] DoQuery(SqliteCommand cmd) @@ -212,53 +213,55 @@ namespace OpenSim.Data.SQLite return result.ToArray(); } - public T[] Get(string where) + public virtual T[] Get(string where) { - SqliteCommand cmd = new SqliteCommand(); + using (SqliteCommand cmd = new SqliteCommand()) + { + string query = String.Format("select * from {0} where {1}", + m_Realm, where); - string query = String.Format("select * from {0} where {1}", - m_Realm, where); + cmd.CommandText = query; - cmd.CommandText = query; - - return DoQuery(cmd); + return DoQuery(cmd); + } } - public bool Store(T row) + public virtual bool Store(T row) { - SqliteCommand cmd = new SqliteCommand(); - - string query = ""; - List names = new List(); - List values = new List(); - - foreach (FieldInfo fi in m_Fields.Values) + using (SqliteCommand cmd = new SqliteCommand()) { - names.Add(fi.Name); - values.Add(":" + fi.Name); - cmd.Parameters.Add(new SqliteParameter(":" + fi.Name, fi.GetValue(row).ToString())); - } + string query = ""; + List names = new List(); + List values = new List(); - if (m_DataField != null) - { - Dictionary data = - (Dictionary)m_DataField.GetValue(row); - - foreach (KeyValuePair kvp in data) + foreach (FieldInfo fi in m_Fields.Values) { - names.Add(kvp.Key); - values.Add(":" + kvp.Key); - cmd.Parameters.Add(new SqliteParameter(":" + kvp.Key, kvp.Value)); + names.Add(fi.Name); + values.Add(":" + fi.Name); + cmd.Parameters.Add(new SqliteParameter(":" + fi.Name, fi.GetValue(row).ToString())); } + + if (m_DataField != null) + { + Dictionary data = + (Dictionary)m_DataField.GetValue(row); + + foreach (KeyValuePair kvp in data) + { + names.Add(kvp.Key); + values.Add(":" + kvp.Key); + cmd.Parameters.Add(new SqliteParameter(":" + kvp.Key, kvp.Value)); + } + } + + query = String.Format("replace into {0} (`", m_Realm) + String.Join("`,`", names.ToArray()) + "`) values (" + String.Join(",", values.ToArray()) + ")"; + + cmd.CommandText = query; + + if (ExecuteNonQuery(cmd, m_Connection) > 0) + return true; } - query = String.Format("replace into {0} (`", m_Realm) + String.Join("`,`", names.ToArray()) + "`) values (" + String.Join(",", values.ToArray()) + ")"; - - cmd.CommandText = query; - - if (ExecuteNonQuery(cmd, m_Connection) > 0) - return true; - return false; } @@ -267,28 +270,29 @@ namespace OpenSim.Data.SQLite return Delete(new string[] { field }, new string[] { key }); } - public bool Delete(string[] fields, string[] keys) + public virtual bool Delete(string[] fields, string[] keys) { if (fields.Length != keys.Length) return false; List terms = new List(); - SqliteCommand cmd = new SqliteCommand(); - - for (int i = 0 ; i < fields.Length ; i++) + using (SqliteCommand cmd = new SqliteCommand()) { - cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i])); - terms.Add("`" + fields[i] + "` = :" + fields[i]); + for (int i = 0 ; i < fields.Length ; i++) + { + cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i])); + terms.Add("`" + fields[i] + "` = :" + fields[i]); + } + + string where = String.Join(" and ", terms.ToArray()); + + string query = String.Format("delete from {0} where {1}", m_Realm, where); + + cmd.CommandText = query; + + return ExecuteNonQuery(cmd, m_Connection) > 0; } - - string where = String.Join(" and ", terms.ToArray()); - - string query = String.Format("delete from {0} where {1}", m_Realm, where); - - cmd.CommandText = query; - - return ExecuteNonQuery(cmd, m_Connection) > 0; } } } diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index 431709f8d5..42cd59de31 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs @@ -1366,6 +1366,13 @@ namespace OpenSim.Data.SQLite createCol(land, "UserLookAtZ", typeof(Double)); createCol(land, "AuthbuyerID", typeof(String)); createCol(land, "OtherCleanTime", typeof(Int32)); + createCol(land, "Dwell", typeof(Int32)); + createCol(land, "MediaType", typeof(String)); + createCol(land, "MediaDescription", typeof(String)); + createCol(land, "MediaSize", typeof(String)); + createCol(land, "MediaLoop", typeof(Boolean)); + createCol(land, "ObscureMedia", typeof(Boolean)); + createCol(land, "ObscureMusic", typeof(Boolean)); land.PrimaryKey = new DataColumn[] { land.Columns["UUID"] }; @@ -1781,9 +1788,16 @@ namespace OpenSim.Data.SQLite newData.PassHours = Convert.ToSingle(row["PassHours"]); newData.PassPrice = Convert.ToInt32(row["PassPrice"]); newData.SnapshotID = (UUID)(String)row["SnapshotUUID"]; + newData.Dwell = Convert.ToInt32(row["Dwell"]); + newData.MediaType = (String)row["MediaType"]; + newData.MediaDescription = (String)row["MediaDescription"]; + newData.MediaWidth = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[0]); + newData.MediaHeight = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[1]); + newData.MediaLoop = Convert.ToBoolean(row["MediaLoop"]); + newData.ObscureMedia = Convert.ToBoolean(row["ObscureMedia"]); + newData.ObscureMusic = Convert.ToBoolean(row["ObscureMusic"]); try { - newData.UserLocation = new Vector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]), Convert.ToSingle(row["UserLocationZ"])); @@ -2195,12 +2209,13 @@ namespace OpenSim.Data.SQLite row["UserLookAtZ"] = land.UserLookAt.Z; row["AuthbuyerID"] = land.AuthBuyerID.ToString(); row["OtherCleanTime"] = land.OtherCleanTime; + row["Dwell"] = land.Dwell; row["MediaType"] = land.MediaType; row["MediaDescription"] = land.MediaDescription; - row["MediaSize"] = land.MediaWidth.ToString() + "," + land.MediaHeight.ToString(); - row["MediaLoop"] = land.MediaLoop.ToString(); - row["ObscureMusic"] = land.ObscureMusic.ToString(); - row["ObscureMedia"] = land.ObscureMedia.ToString(); + row["MediaSize"] = String.Format("{0},{1}", land.MediaWidth, land.MediaHeight); + row["MediaLoop"] = land.MediaLoop; + row["ObscureMusic"] = land.ObscureMusic; + row["ObscureMedia"] = land.ObscureMedia; } /// diff --git a/OpenSim/Data/SQLite/SQLiteUserAccountData.cs b/OpenSim/Data/SQLite/SQLiteUserAccountData.cs index 4d580c08cc..91d62cea4e 100644 --- a/OpenSim/Data/SQLite/SQLiteUserAccountData.cs +++ b/OpenSim/Data/SQLite/SQLiteUserAccountData.cs @@ -66,20 +66,21 @@ namespace OpenSim.Data.SQLite if (words.Length > 2) return new UserAccountData[0]; - SqliteCommand cmd = new SqliteCommand(); - - if (words.Length == 1) + using (SqliteCommand cmd = new SqliteCommand()) { - cmd.CommandText = String.Format("select * from {0} where (ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{2}%')", - m_Realm, scopeID.ToString(), words[0]); - } - else - { - cmd.CommandText = String.Format("select * from {0} where (ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{3}%')", - m_Realm, scopeID.ToString(), words[0], words[1]); - } + if (words.Length == 1) + { + cmd.CommandText = String.Format("select * from {0} where (ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{2}%')", + m_Realm, scopeID.ToString(), words[0]); + } + else + { + cmd.CommandText = String.Format("select * from {0} where (ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{3}%')", + m_Realm, scopeID.ToString(), words[0], words[1]); + } - return DoQuery(cmd); + return DoQuery(cmd); + } } public UserAccountData[] GetUsersWhere(UUID scopeID, string where) diff --git a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs index 1f369867ce..2a0a8f6cc9 100644 --- a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs +++ b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs @@ -47,7 +47,7 @@ namespace OpenSim.Data.SQLite { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private SQLiteGenericTableHandler m_Folders; + private SqliteFolderHandler m_Folders; private SqliteItemHandler m_Items; public SQLiteXInventoryData(string conn, string realm) @@ -55,7 +55,7 @@ namespace OpenSim.Data.SQLite if (Util.IsWindows()) Util.LoadArchSpecificWindowsDll("sqlite3.dll"); - m_Folders = new SQLiteGenericTableHandler( + m_Folders = new SqliteFolderHandler( conn, "inventoryfolders", "XInventoryStore"); m_Items = new SqliteItemHandler( conn, "inventoryitems", String.Empty); @@ -114,6 +114,11 @@ namespace OpenSim.Data.SQLite return m_Items.MoveItem(id, newParent); } + public bool MoveFolder(string id, string newParent) + { + return m_Folders.MoveFolder(id, newParent); + } + public XInventoryItem[] GetActiveGestures(UUID principalID) { return m_Items.GetActiveGestures(principalID); @@ -125,44 +130,106 @@ namespace OpenSim.Data.SQLite } } - public class SqliteItemHandler : SQLiteGenericTableHandler + public class SqliteItemHandler : SqliteInventoryHandler { public SqliteItemHandler(string c, string t, string m) : base(c, t, m) { } + public override bool Store(XInventoryItem item) + { + if (!base.Store(item)) + return false; + + IncrementFolderVersion(item.parentFolderID); + + return true; + } + + public override bool Delete(string field, string val) + { + XInventoryItem[] retrievedItems = Get(new string[] { field }, new string[] { val }); + if (retrievedItems.Length == 0) + return false; + + if (!base.Delete(field, val)) + return false; + + // Don't increment folder version here since Delete(string, string) calls Delete(string[], string[]) +// IncrementFolderVersion(retrievedItems[0].parentFolderID); + + return true; + } + + public override bool Delete(string[] fields, string[] vals) + { + XInventoryItem[] retrievedItems = Get(fields, vals); + if (retrievedItems.Length == 0) + return false; + + if (!base.Delete(fields, vals)) + return false; + + HashSet deletedItemFolderUUIDs = new HashSet(); + + Array.ForEach(retrievedItems, i => deletedItemFolderUUIDs.Add(i.parentFolderID)); + + foreach (UUID deletedItemFolderUUID in deletedItemFolderUUIDs) + IncrementFolderVersion(deletedItemFolderUUID); + + return true; + } + public bool MoveItem(string id, string newParent) { - SqliteCommand cmd = new SqliteCommand(); + XInventoryItem[] retrievedItems = Get(new string[] { "inventoryID" }, new string[] { id }); + if (retrievedItems.Length == 0) + return false; - cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where inventoryID = :InventoryID", m_Realm); - cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParent)); - cmd.Parameters.Add(new SqliteParameter(":InventoryID", id)); + UUID oldParent = retrievedItems[0].parentFolderID; - return ExecuteNonQuery(cmd, m_Connection) == 0 ? false : true; + using (SqliteCommand cmd = new SqliteCommand()) + { + cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where inventoryID = :InventoryID", m_Realm); + cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParent)); + cmd.Parameters.Add(new SqliteParameter(":InventoryID", id)); + + if (ExecuteNonQuery(cmd, m_Connection) == 0) + return false; + } + + IncrementFolderVersion(oldParent); + IncrementFolderVersion(newParent); + + return true; } public XInventoryItem[] GetActiveGestures(UUID principalID) { - SqliteCommand cmd = new SqliteCommand(); - cmd.CommandText = String.Format("select * from inventoryitems where avatarId = :uuid and assetType = :type and flags = 1", m_Realm); + using (SqliteCommand cmd = new SqliteCommand()) + { + cmd.CommandText = String.Format("select * from inventoryitems where avatarId = :uuid and assetType = :type and flags = 1", m_Realm); - cmd.Parameters.Add(new SqliteParameter(":uuid", principalID.ToString())); - cmd.Parameters.Add(new SqliteParameter(":type", (int)AssetType.Gesture)); + cmd.Parameters.Add(new SqliteParameter(":uuid", principalID.ToString())); + cmd.Parameters.Add(new SqliteParameter(":type", (int)AssetType.Gesture)); - return DoQuery(cmd); + return DoQuery(cmd); + } } public int GetAssetPermissions(UUID principalID, UUID assetID) { - SqliteCommand cmd = new SqliteCommand(); + IDataReader reader; - cmd.CommandText = String.Format("select inventoryCurrentPermissions from inventoryitems where avatarID = :PrincipalID and assetID = :AssetID", m_Realm); - cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString())); - cmd.Parameters.Add(new SqliteParameter(":AssetID", assetID.ToString())); + using (SqliteCommand cmd = new SqliteCommand()) + { + cmd.CommandText = String.Format("select inventoryCurrentPermissions from inventoryitems where avatarID = :PrincipalID and assetID = :AssetID", m_Realm); + cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString())); + cmd.Parameters.Add(new SqliteParameter(":AssetID", assetID.ToString())); - IDataReader reader = ExecuteReader(cmd, m_Connection); + reader = ExecuteReader(cmd, m_Connection); + } int perms = 0; @@ -177,4 +244,81 @@ namespace OpenSim.Data.SQLite return perms; } } -} + + public class SqliteFolderHandler : SqliteInventoryHandler + { + public SqliteFolderHandler(string c, string t, string m) : + base(c, t, m) + { + } + + public override bool Store(XInventoryFolder folder) + { + if (!base.Store(folder)) + return false; + + IncrementFolderVersion(folder.parentFolderID); + + return true; + } + + public bool MoveFolder(string id, string newParentFolderID) + { + XInventoryFolder[] folders = Get(new string[] { "folderID" }, new string[] { id }); + + if (folders.Length == 0) + return false; + + UUID oldParentFolderUUID = folders[0].parentFolderID; + + using (SqliteCommand cmd = new SqliteCommand()) + { + cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where folderID = :FolderID", m_Realm); + cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParentFolderID)); + cmd.Parameters.Add(new SqliteParameter(":FolderID", id)); + + if (ExecuteNonQuery(cmd, m_Connection) == 0) + return false; + } + + IncrementFolderVersion(oldParentFolderUUID); + IncrementFolderVersion(newParentFolderID); + + return true; + } + + } + + public class SqliteInventoryHandler : SQLiteGenericTableHandler where T: class, new() + { + public SqliteInventoryHandler(string c, string t, string m) : base(c, t, m) {} + + protected bool IncrementFolderVersion(UUID folderID) + { + return IncrementFolderVersion(folderID.ToString()); + } + + protected bool IncrementFolderVersion(string folderID) + { +// m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID); +// Util.PrintCallStack(); + + using (SqliteCommand cmd = new SqliteCommand()) + { + cmd.CommandText = "update inventoryfolders set version=version+1 where folderID = ?folderID"; + cmd.Parameters.Add(new SqliteParameter(":folderID", folderID)); + + try + { + cmd.ExecuteNonQuery(); + } + catch (Exception) + { + return false; + } + } + + return true; + } + } +} \ No newline at end of file diff --git a/OpenSim/Framework/AssemblyInfo.cs b/OpenSim/Framework/AssemblyInfo.cs index adeaeb221a..02986d5d2a 100644 --- a/OpenSim/Framework/AssemblyInfo.cs +++ b/OpenSim/Framework/AssemblyInfo.cs @@ -59,5 +59,5 @@ using System.Runtime.InteropServices; // Revision // -[assembly : AssemblyVersion("0.6.5.*")] +[assembly : AssemblyVersion("0.7.5.*")] [assembly : AssemblyFileVersion("0.6.5.0")] \ No newline at end of file diff --git a/OpenSim/Framework/AssetLoader/Filesystem/Properties/AssemblyInfo.cs b/OpenSim/Framework/AssetLoader/Filesystem/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..0498ed4888 --- /dev/null +++ b/OpenSim/Framework/AssetLoader/Filesystem/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Framework.AssetLoader.Filesystem")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://opensimulator.org")] +[assembly: AssemblyProduct("OpenSim")] +[assembly: AssemblyCopyright("OpenSimulator developers")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("8cb9cf69-4771-4d3a-a2ba-bac7230de326")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/AssetPermissions.cs b/OpenSim/Framework/AssetPermissions.cs new file mode 100644 index 0000000000..4a905c2f5d --- /dev/null +++ b/OpenSim/Framework/AssetPermissions.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +using Nini.Config; +using log4net; + +using OpenMetaverse; + +namespace OpenSim.Framework +{ + public class AssetPermissions + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private bool[] m_DisallowExport, m_DisallowImport; + private string[] m_AssetTypeNames; + + public AssetPermissions(IConfig config) + { + Type enumType = typeof(AssetType); + m_AssetTypeNames = Enum.GetNames(enumType); + for (int i = 0; i < m_AssetTypeNames.Length; i++) + m_AssetTypeNames[i] = m_AssetTypeNames[i].ToLower(); + int n = Enum.GetValues(enumType).Length; + m_DisallowExport = new bool[n]; + m_DisallowImport = new bool[n]; + + LoadPermsFromConfig(config, "DisallowExport", m_DisallowExport); + LoadPermsFromConfig(config, "DisallowImport", m_DisallowImport); + + } + + private void LoadPermsFromConfig(IConfig assetConfig, string variable, bool[] bitArray) + { + if (assetConfig == null) + return; + + string perms = assetConfig.GetString(variable, String.Empty); + string[] parts = perms.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + foreach (string s in parts) + { + int index = Array.IndexOf(m_AssetTypeNames, s.Trim().ToLower()); + if (index >= 0) + bitArray[index] = true; + else + m_log.WarnFormat("[Asset Permissions]: Invalid AssetType {0}", s); + } + + } + + public bool AllowedExport(sbyte type) + { + string assetTypeName = ((AssetType)type).ToString(); + + int index = Array.IndexOf(m_AssetTypeNames, assetTypeName.ToLower()); + if (index >= 0 && m_DisallowExport[index]) + { + m_log.DebugFormat("[Asset Permissions]: Export denied: configuration does not allow export of AssetType {0}", assetTypeName); + return false; + } + + return true; + } + + public bool AllowedImport(sbyte type) + { + string assetTypeName = ((AssetType)type).ToString(); + + int index = Array.IndexOf(m_AssetTypeNames, assetTypeName.ToLower()); + if (index >= 0 && m_DisallowImport[index]) + { + m_log.DebugFormat("[Asset Permissions]: Import denied: configuration does not allow import of AssetType {0}", assetTypeName); + return false; + } + + return true; + } + + + } +} diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index c5d9641da7..16385417e6 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs @@ -358,6 +358,9 @@ namespace OpenSim.Framework SetVisualParams(visualParams); } + /// + /// Set avatar height by a calculation based on their visual parameters. + /// public virtual void SetHeight() { // Start with shortest possible female avatar height diff --git a/OpenSim/Framework/Cache.cs b/OpenSim/Framework/Cache.cs index 79e20fc88e..31cab4a021 100644 --- a/OpenSim/Framework/Cache.cs +++ b/OpenSim/Framework/Cache.cs @@ -199,7 +199,14 @@ namespace OpenSim.Framework // public class Cache { + /// + /// Must only be accessed under lock. + /// private List m_Index = new List(); + + /// + /// Must only be accessed under m_Index lock. + /// private Dictionary m_Lookup = new Dictionary(); @@ -320,19 +327,19 @@ namespace OpenSim.Framework { if (m_Lookup.ContainsKey(index)) item = m_Lookup[index]; - } - if (item == null) - { + if (item == null) + { + Expire(true); + return null; + } + + item.hits++; + item.lastUsed = DateTime.Now; + Expire(true); - return null; } - item.hits++; - item.lastUsed = DateTime.Now; - - Expire(true); - return item; } @@ -385,7 +392,10 @@ namespace OpenSim.Framework // public Object Find(Predicate d) { - CacheItemBase item = m_Index.Find(d); + CacheItemBase item; + + lock (m_Index) + item = m_Index.Find(d); if (item == null) return null; @@ -419,12 +429,12 @@ namespace OpenSim.Framework public virtual void Store(string index, Object data, Type container, Object[] parameters) { - Expire(false); - CacheItemBase item; lock (m_Index) { + Expire(false); + if (m_Index.Contains(new CacheItemBase(index))) { if ((m_Flags & CacheFlags.AllowUpdate) != 0) @@ -450,9 +460,17 @@ namespace OpenSim.Framework m_Index.Add(item); m_Lookup[index] = item; } + item.Store(data); } + /// + /// Expire items as appropriate. + /// + /// + /// Callers must lock m_Index. + /// + /// protected virtual void Expire(bool getting) { if (getting && (m_Strategy == CacheStrategy.Aggressive)) @@ -475,12 +493,10 @@ namespace OpenSim.Framework switch (m_Strategy) { - case CacheStrategy.Aggressive: - if (Count < Size) - return; + case CacheStrategy.Aggressive: + if (Count < Size) + return; - lock (m_Index) - { m_Index.Sort(new SortLRU()); m_Index.Reverse(); @@ -490,7 +506,7 @@ namespace OpenSim.Framework ExpireDelegate doExpire = OnExpire; - if (doExpire != null) + if (doExpire != null) { List candidates = m_Index.GetRange(target, Count - target); @@ -513,27 +529,34 @@ namespace OpenSim.Framework foreach (CacheItemBase item in m_Index) m_Lookup[item.uuid] = item; } - } - break; - default: - break; + + break; + + default: + break; } } public void Invalidate(string uuid) { - if (!m_Lookup.ContainsKey(uuid)) - return; + lock (m_Index) + { + if (!m_Lookup.ContainsKey(uuid)) + return; - CacheItemBase item = m_Lookup[uuid]; - m_Lookup.Remove(uuid); - m_Index.Remove(item); + CacheItemBase item = m_Lookup[uuid]; + m_Lookup.Remove(uuid); + m_Index.Remove(item); + } } public void Clear() { - m_Index.Clear(); - m_Lookup.Clear(); + lock (m_Index) + { + m_Index.Clear(); + m_Lookup.Clear(); + } } } -} +} \ No newline at end of file diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index e718aa6c47..8c32734980 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -312,6 +312,7 @@ namespace OpenSim.Framework public AgentGroupData[] Groups; public Animation[] Anims; public Animation DefaultAnim = null; + public Animation AnimState = null; public UUID GranterID; public UUID ParentPart; @@ -403,6 +404,11 @@ namespace OpenSim.Framework args["default_animation"] = DefaultAnim.PackUpdateMessage(); } + if (AnimState != null) + { + args["animation_state"] = AnimState.PackUpdateMessage(); + } + if (Appearance != null) args["packed_appearance"] = Appearance.Pack(); @@ -612,6 +618,18 @@ namespace OpenSim.Framework } } + if (args["animation_state"] != null) + { + try + { + AnimState = new Animation((OSDMap)args["animation_state"]); + } + catch + { + AnimState = null; + } + } + //if ((args["agent_textures"] != null) && (args["agent_textures"]).Type == OSDType.Array) //{ // OSDArray textures = (OSDArray)(args["agent_textures"]); diff --git a/OpenSim/Framework/Client/IClientChat.cs b/OpenSim/Framework/Client/IClientChat.cs index 078ea9b668..86b1faa8f6 100644 --- a/OpenSim/Framework/Client/IClientChat.cs +++ b/OpenSim/Framework/Client/IClientChat.cs @@ -33,7 +33,8 @@ namespace OpenSim.Framework.Client { event ChatMessage OnChatFromClient; - void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, byte source, - byte audible); + void SendChatMessage( + string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, UUID ownerID, byte source, + byte audible); } -} +} \ No newline at end of file diff --git a/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs b/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs index 2df6aceb08..6d1c03ad4b 100644 --- a/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs @@ -32,12 +32,12 @@ using System.Runtime.InteropServices; // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly : AssemblyTitle("OpenGrid.Framework.Communications")] +[assembly : AssemblyTitle("OpenSim.Framework.Communications")] [assembly : AssemblyDescription("")] [assembly : AssemblyConfiguration("")] [assembly : AssemblyCompany("http://opensimulator.org")] -[assembly : AssemblyProduct("OpenGrid.Framework.Communications")] -[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")] +[assembly : AssemblyProduct("OpenSim")] +[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers")] [assembly : AssemblyTrademark("")] [assembly : AssemblyCulture("")] @@ -61,5 +61,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly : AssemblyVersion("0.6.5.*")] +[assembly : AssemblyVersion("0.7.5.*")] [assembly : AssemblyFileVersion("0.6.5.0")] diff --git a/OpenSim/Framework/Configuration/HTTP/Properties/AssemblyInfo.cs b/OpenSim/Framework/Configuration/HTTP/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..0674656c75 --- /dev/null +++ b/OpenSim/Framework/Configuration/HTTP/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Framework.Configuration.HTTP")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://opensimulator.org")] +[assembly: AssemblyProduct("OpenSim")] +[assembly: AssemblyCopyright("OpenSimulator develoeprs")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("cb78b672-d000-4f93-88f9-dae151cc0061")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Configuration/XML/Properties/AssemblyInfo.cs b/OpenSim/Framework/Configuration/XML/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..1095b232e2 --- /dev/null +++ b/OpenSim/Framework/Configuration/XML/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Framework.Configuration.XML")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://opensimulator.org")] +[assembly: AssemblyProduct("OpenSim")] +[assembly: AssemblyCopyright("OpenSimulator developers")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("eeb880df-0112-4c3d-87ed-b2108d614c55")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Console/AssemblyInfo.cs b/OpenSim/Framework/Console/AssemblyInfo.cs index 75e35bf688..37c7304424 100644 --- a/OpenSim/Framework/Console/AssemblyInfo.cs +++ b/OpenSim/Framework/Console/AssemblyInfo.cs @@ -39,7 +39,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("http://opensimulator.org")] [assembly : AssemblyProduct("ServerConsole")] -[assembly: AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")] +[assembly: AssemblyCopyright("Copyright (c) OpenSimulator.org Developers")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -55,4 +55,4 @@ using System.Runtime.InteropServices; // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly : AssemblyVersion("0.6.5.*")] +[assembly : AssemblyVersion("0.7.5.*")] diff --git a/OpenSim/Framework/Console/CommandConsole.cs b/OpenSim/Framework/Console/CommandConsole.cs index bd23d1cb62..d703d78b55 100644 --- a/OpenSim/Framework/Console/CommandConsole.cs +++ b/OpenSim/Framework/Console/CommandConsole.cs @@ -83,7 +83,8 @@ namespace OpenSim.Framework.Console = "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:"; += @"For more information, type 'help' to get a list of all commands, + or type help ' where is one of the following:"; /// /// Commands organized by keyword in a tree @@ -111,6 +112,12 @@ namespace OpenSim.Framework.Console // General help if (helpParts.Count == 0) + { + help.Add(""); // Will become a newline. + help.Add(GeneralHelpText); + help.AddRange(CollectAllCommandsHelp()); + } + else if (helpParts.Count == 1 && helpParts[0] == "categories") { help.Add(""); // Will become a newline. help.Add(GeneralHelpText); @@ -124,6 +131,31 @@ namespace OpenSim.Framework.Console return help; } + + /// + /// Collects the help from all commands and return in alphabetical order. + /// + /// + private List CollectAllCommandsHelp() + { + List help = new List(); + + lock (m_modulesCommands) + { + foreach (List commands in m_modulesCommands.Values) + { + foreach (CommandInfo c in commands) + { + if (c.long_help != String.Empty) + help.Add(string.Format("{0} - {1}", c.help_text, c.long_help)); + } + } + } + + help.Sort(); + + return help; + } /// /// See if we can find the requested command in order to display longer help @@ -711,7 +743,7 @@ namespace OpenSim.Framework.Console /// public void Prompt() { - string line = ReadLine(m_defaultPrompt + "# ", true, true); + string line = ReadLine(DefaultPrompt + "# ", true, true); if (line != String.Empty) Output("Invalid command"); diff --git a/OpenSim/Framework/Console/ConsoleBase.cs b/OpenSim/Framework/Console/ConsoleBase.cs index 4b375d9963..2d8e723af2 100755 --- a/OpenSim/Framework/Console/ConsoleBase.cs +++ b/OpenSim/Framework/Console/ConsoleBase.cs @@ -43,15 +43,7 @@ namespace OpenSim.Framework.Console public object ConsoleScene { get; set; } - /// - /// The default prompt text. - /// - public string DefaultPrompt - { - set { m_defaultPrompt = value; } - get { return m_defaultPrompt; } - } - protected string m_defaultPrompt; + public string DefaultPrompt { get; set; } public ConsoleBase(string defaultPrompt) { diff --git a/OpenSim/Framework/Console/ConsoleUtil.cs b/OpenSim/Framework/Console/ConsoleUtil.cs new file mode 100644 index 0000000000..16a63e0ca5 --- /dev/null +++ b/OpenSim/Framework/Console/ConsoleUtil.cs @@ -0,0 +1,228 @@ +/* + * 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.IO; +using System.Linq; +using System.Reflection; +using log4net; +using OpenMetaverse; + +namespace OpenSim.Framework.Console +{ + public class ConsoleUtil + { + // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public const int LocalIdNotFound = 0; + + /// + /// Used by modules to display stock co-ordinate help, though possibly this should be under some general section + /// rather than in each help summary. + /// + public const string CoordHelp + = @"Each component of the coord is comma separated. There must be no spaces between the commas. + If you don't care about the z component you can simply omit it. + If you don't care about the x or y components then you can leave them blank (though a comma is still required) + If you want to specify the maxmimum value of a component then you can use ~ instead of a number + If you want to specify the minimum value of a component then you can use -~ instead of a number + e.g. + delete object pos 20,20,20 to 40,40,40 + delete object pos 20,20 to 40,40 + delete object pos ,20,20 to ,40,40 + delete object pos ,,30 to ,,~ + delete object pos ,,-~ to ,,30"; + + public const string MinRawConsoleVectorValue = "-~"; + public const string MaxRawConsoleVectorValue = "~"; + + public const string VectorSeparator = ","; + public static char[] VectorSeparatorChars = VectorSeparator.ToCharArray(); + + /// + /// Check if the given file path exists. + /// + /// If not, warning is printed to the given console. + /// true if the file does not exist, false otherwise. + /// + /// + public static bool CheckFileDoesNotExist(ICommandConsole console, string path) + { + if (File.Exists(path)) + { + console.OutputFormat("File {0} already exists. Please move or remove it.", path); + return false; + } + + return true; + } + + /// + /// Try to parse a console UUID from the console. + /// + /// + /// Will complain to the console if parsing fails. + /// + /// + /// If null then no complaint is printed. + /// + /// + public static bool TryParseConsoleUuid(ICommandConsole console, string rawUuid, out UUID uuid) + { + if (!UUID.TryParse(rawUuid, out uuid)) + { + if (console != null) + console.OutputFormat("{0} is not a valid uuid", rawUuid); + + return false; + } + + return true; + } + + public static bool TryParseConsoleLocalId(ICommandConsole console, string rawLocalId, out uint localId) + { + if (!uint.TryParse(rawLocalId, out localId)) + { + if (console != null) + console.OutputFormat("{0} is not a valid local id", localId); + + return false; + } + + if (localId == 0) + { + if (console != null) + console.OutputFormat("{0} is not a valid local id - it must be greater than 0", localId); + + return false; + } + + return true; + } + + /// + /// Tries to parse the input as either a UUID or a local ID. + /// + /// true if parsing succeeded, false otherwise. + /// + /// + /// + /// + /// Will be set to ConsoleUtil.LocalIdNotFound if parsing result was a UUID or no parse succeeded. + /// + public static bool TryParseConsoleId(ICommandConsole console, string rawId, out UUID uuid, out uint localId) + { + if (TryParseConsoleUuid(null, rawId, out uuid)) + { + localId = LocalIdNotFound; + return true; + } + + if (TryParseConsoleLocalId(null, rawId, out localId)) + { + return true; + } + + if (console != null) + console.OutputFormat("{0} is not a valid UUID or local id", rawId); + + return false; + } + + /// + /// Convert a minimum vector input from the console to an OpenMetaverse.Vector3 + /// + /// /param> + /// + /// + public static bool TryParseConsoleMinVector(string rawConsoleVector, out Vector3 vector) + { + return TryParseConsoleVector(rawConsoleVector, c => float.MinValue.ToString(), out vector); + } + + /// + /// Convert a maximum vector input from the console to an OpenMetaverse.Vector3 + /// + /// /param> + /// + /// + public static bool TryParseConsoleMaxVector(string rawConsoleVector, out Vector3 vector) + { + return TryParseConsoleVector(rawConsoleVector, c => float.MaxValue.ToString(), out vector); + } + + /// + /// Convert a vector input from the console to an OpenMetaverse.Vector3 + /// + /// + /// A string in the form ,, where there is no space between values. + /// Any component can be missing (e.g. ,,40). blankComponentFunc is invoked to replace the blank with a suitable value + /// Also, if the blank component is at the end, then the comma can be missed off entirely (e.g. 40,30 or 40) + /// The strings "~" and "-~" are valid in components. The first substitutes float.MaxValue whilst the second is float.MinValue + /// Other than that, component values must be numeric. + /// + /// + /// + /// + public static bool TryParseConsoleVector( + string rawConsoleVector, Func blankComponentFunc, out Vector3 vector) + { + List components = rawConsoleVector.Split(VectorSeparatorChars).ToList(); + + if (components.Count < 1 || components.Count > 3) + { + vector = Vector3.Zero; + return false; + } + + for (int i = components.Count; i < 3; i++) + components.Add(""); + + List semiDigestedComponents + = components.ConvertAll( + c => + { + if (c == "") + return blankComponentFunc.Invoke(c); + else if (c == MaxRawConsoleVectorValue) + return float.MaxValue.ToString(); + else if (c == MinRawConsoleVectorValue) + return float.MinValue.ToString(); + else + return c; + }); + + string semiDigestedConsoleVector = string.Join(VectorSeparator, semiDigestedComponents.ToArray()); + + // m_log.DebugFormat("[CONSOLE UTIL]: Parsing {0} into OpenMetaverse.Vector3", semiDigestedConsoleVector); + + return Vector3.TryParse(semiDigestedConsoleVector, out vector); + } + } +} \ No newline at end of file diff --git a/OpenSim/Framework/Console/MockConsole.cs b/OpenSim/Framework/Console/MockConsole.cs index b489f93b69..8ba58e4cc6 100644 --- a/OpenSim/Framework/Console/MockConsole.cs +++ b/OpenSim/Framework/Console/MockConsole.cs @@ -46,13 +46,18 @@ namespace OpenSim.Framework.Console public ICommands Commands { get { return m_commands; } } + public string DefaultPrompt { get; set; } + public void Prompt() {} public void RunCommand(string cmd) {} public string ReadLine(string p, bool isCommand, bool e) { return ""; } - public object ConsoleScene { get { return null; } } + public object ConsoleScene { + get { return null; } + set {} + } public void Output(string text, string level) {} public void Output(string text) {} diff --git a/OpenSim/Framework/Constants.cs b/OpenSim/Framework/Constants.cs index 1b1aaf2bc4..a2eb5ee18e 100644 --- a/OpenSim/Framework/Constants.cs +++ b/OpenSim/Framework/Constants.cs @@ -31,6 +31,7 @@ namespace OpenSim.Framework public class Constants { public const uint RegionSize = 256; + public const uint RegionHeight = 4096; public const byte TerrainPatchSize = 16; public const string DefaultTexture = "89556747-24cb-43ed-920b-47caed15465f"; diff --git a/OpenSim/Framework/EstateSettings.cs b/OpenSim/Framework/EstateSettings.cs index 9020761cad..e03750bcc5 100644 --- a/OpenSim/Framework/EstateSettings.cs +++ b/OpenSim/Framework/EstateSettings.cs @@ -419,11 +419,11 @@ namespace OpenSim.Framework public void SetFromFlags(ulong regionFlags) { - ResetHomeOnTeleport = ((regionFlags & (ulong)RegionFlags.ResetHomeOnTeleport) == (ulong)RegionFlags.ResetHomeOnTeleport); - BlockDwell = ((regionFlags & (ulong)RegionFlags.BlockDwell) == (ulong)RegionFlags.BlockDwell); - AllowLandmark = ((regionFlags & (ulong)RegionFlags.AllowLandmark) == (ulong)RegionFlags.AllowLandmark); - AllowParcelChanges = ((regionFlags & (ulong)RegionFlags.AllowParcelChanges) == (ulong)RegionFlags.AllowParcelChanges); - AllowSetHome = ((regionFlags & (ulong)RegionFlags.AllowSetHome) == (ulong)RegionFlags.AllowSetHome); + ResetHomeOnTeleport = ((regionFlags & (ulong)OpenMetaverse.RegionFlags.ResetHomeOnTeleport) == (ulong)OpenMetaverse.RegionFlags.ResetHomeOnTeleport); + BlockDwell = ((regionFlags & (ulong)OpenMetaverse.RegionFlags.BlockDwell) == (ulong)OpenMetaverse.RegionFlags.BlockDwell); + AllowLandmark = ((regionFlags & (ulong)OpenMetaverse.RegionFlags.AllowLandmark) == (ulong)OpenMetaverse.RegionFlags.AllowLandmark); + AllowParcelChanges = ((regionFlags & (ulong)OpenMetaverse.RegionFlags.AllowParcelChanges) == (ulong)OpenMetaverse.RegionFlags.AllowParcelChanges); + AllowSetHome = ((regionFlags & (ulong)OpenMetaverse.RegionFlags.AllowSetHome) == (ulong)OpenMetaverse.RegionFlags.AllowSetHome); } public bool GroupAccess(UUID groupID) diff --git a/OpenSim/Framework/GridInstantMessage.cs b/OpenSim/Framework/GridInstantMessage.cs index a6bf6e3c32..6ae0488fc2 100644 --- a/OpenSim/Framework/GridInstantMessage.cs +++ b/OpenSim/Framework/GridInstantMessage.cs @@ -44,7 +44,6 @@ namespace OpenSim.Framework public Vector3 Position; public byte[] binaryBucket; - public uint ParentEstateID; public Guid RegionID; public uint timestamp; @@ -58,7 +57,7 @@ namespace OpenSim.Framework string _fromAgentName, UUID _toAgentID, byte _dialog, bool _fromGroup, string _message, UUID _imSessionID, bool _offline, Vector3 _position, - byte[] _binaryBucket) + byte[] _binaryBucket, bool addTimestamp) { fromAgentID = _fromAgentID.Guid; fromAgentName = _fromAgentName; @@ -79,7 +78,9 @@ namespace OpenSim.Framework ParentEstateID = scene.RegionInfo.EstateSettings.ParentEstateID; RegionID = scene.RegionInfo.RegionSettings.RegionUUID.Guid; } - timestamp = (uint)Util.UnixTimeSinceEpoch(); + + if (addTimestamp) + timestamp = (uint)Util.UnixTimeSinceEpoch(); } public GridInstantMessage(IScene scene, UUID _fromAgentID, @@ -87,7 +88,7 @@ namespace OpenSim.Framework string _message, bool _offline, Vector3 _position) : this(scene, _fromAgentID, _fromAgentName, _toAgentID, _dialog, false, _message, - _fromAgentID ^ _toAgentID, _offline, _position, new byte[0]) + _fromAgentID ^ _toAgentID, _offline, _position, new byte[0], true) { } } diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 5909ce1af9..f686c6035d 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -815,8 +815,23 @@ namespace OpenSim.Framework event Action OnRegionHandShakeReply; event GenericCall1 OnRequestWearables; event Action OnCompleteMovementToRegion; + + /// + /// Called when an AgentUpdate message is received and before OnAgentUpdate. + /// + /// + /// Listeners must not retain a reference to AgentUpdateArgs since this object may be reused for subsequent AgentUpdates. + /// event UpdateAgent OnPreAgentUpdate; + + /// + /// Called when an AgentUpdate message is received and after OnPreAgentUpdate. + /// + /// + /// Listeners must not retain a reference to AgentUpdateArgs since this object may be reused for subsequent AgentUpdates. + /// event UpdateAgent OnAgentUpdate; + event AgentRequestSit OnAgentRequestSit; event AgentSit OnAgentSit; event AvatarPickerRequest OnAvatarPickerRequest; @@ -1038,7 +1053,7 @@ namespace OpenSim.Framework event MuteListEntryRemove OnRemoveMuteListEntry; event GodlikeMessage onGodlikeMessage; event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; - + event GenericCall2 OnUpdateThrottles; /// /// Set the debug level at which packet output should be printed to console. /// @@ -1046,8 +1061,21 @@ namespace OpenSim.Framework void InPacket(object NewPack); void ProcessInPacket(Packet NewPack); + + /// + /// Close this client + /// void Close(); - void Close(bool sendStop); + + /// + /// Close this client + /// + /// + /// If true, attempts the close without checking active status. You do not want to try this except as a last + /// ditch attempt where Active == false but the ScenePresence still exists. + /// + void Close(bool sendStop, bool force); + void Kick(string message); /// @@ -1084,8 +1112,20 @@ namespace OpenSim.Framework void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs); void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args); - void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, byte source, - byte audible); + /// + /// Send chat to the viewer. + /// + /// + /// + /// + /// + /// + /// + /// + /// + void SendChatMessage( + string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, UUID ownerID, byte source, + byte audible); void SendInstantMessage(GridInstantMessage im); @@ -1135,6 +1175,8 @@ namespace OpenSim.Framework void SetChildAgentThrottle(byte[] throttle); + void SetAgentThrottleSilent(int throttle, int setting); + void SendAvatarDataImmediate(ISceneEntity avatar); /// diff --git a/OpenSim/Framework/ICommandConsole.cs b/OpenSim/Framework/ICommandConsole.cs index 8cd20da4ee..a6573f8843 100644 --- a/OpenSim/Framework/ICommandConsole.cs +++ b/OpenSim/Framework/ICommandConsole.cs @@ -82,6 +82,11 @@ namespace OpenSim.Framework ICommands Commands { get; } + /// + /// The default prompt text. + /// + string DefaultPrompt { get; set; } + /// /// Display a command prompt on the console and wait for user input /// diff --git a/OpenSim/Framework/IConsole.cs b/OpenSim/Framework/IConsole.cs index 33024b2076..79560d805b 100644 --- a/OpenSim/Framework/IConsole.cs +++ b/OpenSim/Framework/IConsole.cs @@ -32,7 +32,7 @@ namespace OpenSim.Framework { public interface IConsole { - object ConsoleScene { get; } + object ConsoleScene { get; set; } void Output(string text, string level); void Output(string text); diff --git a/OpenSim/Framework/IMoneyModule.cs b/OpenSim/Framework/IMoneyModule.cs index 71de93a192..7378d2ef3f 100644 --- a/OpenSim/Framework/IMoneyModule.cs +++ b/OpenSim/Framework/IMoneyModule.cs @@ -33,7 +33,7 @@ namespace OpenSim.Framework public interface IMoneyModule { bool ObjectGiveMoney(UUID objectID, UUID fromID, UUID toID, - int amount); + int amount, UUID txn); int GetBalance(UUID agentID); bool UploadCovered(UUID agentID, int amount); diff --git a/OpenSim/Framework/InventoryFolderBase.cs b/OpenSim/Framework/InventoryFolderBase.cs index a12183c535..b3457a65b9 100644 --- a/OpenSim/Framework/InventoryFolderBase.cs +++ b/OpenSim/Framework/InventoryFolderBase.cs @@ -73,33 +73,27 @@ namespace OpenSim.Framework { } - public InventoryFolderBase(UUID id) + public InventoryFolderBase(UUID id) : this() { ID = id; } - public InventoryFolderBase(UUID id, UUID owner) + public InventoryFolderBase(UUID id, UUID owner) : this(id) { - ID = id; Owner = owner; } - public InventoryFolderBase(UUID id, string name, UUID owner, UUID parent) + public InventoryFolderBase(UUID id, string name, UUID owner, UUID parent) : this(id, owner) { - ID = id; Name = name; - Owner = owner; ParentID = parent; } - public InventoryFolderBase(UUID id, string name, UUID owner, short type, UUID parent, ushort version) + public InventoryFolderBase( + UUID id, string name, UUID owner, short type, UUID parent, ushort version) : this(id, name, owner, parent) { - ID = id; - Name = name; - Owner = owner; Type = type; - ParentID = parent; Version = version; } } -} +} \ No newline at end of file diff --git a/OpenSim/Framework/InventoryItemBase.cs b/OpenSim/Framework/InventoryItemBase.cs index a663680a78..3d45e76698 100644 --- a/OpenSim/Framework/InventoryItemBase.cs +++ b/OpenSim/Framework/InventoryItemBase.cs @@ -87,16 +87,7 @@ namespace OpenSim.Framework protected string m_creatorId; /// - /// The UUID for the creator. This may be different from the canonical CreatorId. This property is used - /// for communication with the client over the Second Life protocol, since that protocol can only understand - /// UUIDs. As this is a basic framework class, this means that both the string creator id and the uuid - /// reference have to be settable separately - /// - /// Database plugins don't need to set this, it will be set by - /// upstream code (or set by the get accessor if left unset). - /// - /// XXX: An alternative to having a separate uuid property would be to hash the CreatorId appropriately - /// every time there was communication with a UUID-only client. This may be much more expensive. + /// The CreatorId expressed as a UUID.tely /// public UUID CreatorIdAsUuid { @@ -109,20 +100,18 @@ namespace OpenSim.Framework return m_creatorIdAsUuid; } - - set - { - m_creatorIdAsUuid = value; - } } protected UUID m_creatorIdAsUuid = UUID.Zero; - protected string m_creatorData = string.Empty; + /// + /// Extended creator information of the form ; + /// public string CreatorData // = ; { get { return m_creatorData; } set { m_creatorData = value; } } + protected string m_creatorData = string.Empty; /// /// Used by the DB layer to retrieve / store the entire user identification. @@ -162,7 +151,6 @@ namespace OpenSim.Framework name = parts[2]; m_creatorData += ';' + name; - } } } diff --git a/OpenSim/Framework/LandData.cs b/OpenSim/Framework/LandData.cs index dcaa46d960..4dffd3f22d 100644 --- a/OpenSim/Framework/LandData.cs +++ b/OpenSim/Framework/LandData.cs @@ -49,8 +49,8 @@ namespace OpenSim.Framework // use only one serializer to give the runtime a chance to // optimize it (it won't do that if you use a new instance // every time) - private static XmlSerializer serializer = new XmlSerializer(typeof (LandData)); - + private static XmlSerializer serializer = new XmlSerializer(typeof(LandData)); + private Vector3 _AABBMax = new Vector3(); private Vector3 _AABBMin = new Vector3(); private int _area = 0; @@ -65,11 +65,11 @@ namespace OpenSim.Framework private byte[] _bitmap = new byte[512]; private string _description = String.Empty; - private uint _flags = (uint) ParcelFlags.AllowFly | (uint) ParcelFlags.AllowLandmark | - (uint) ParcelFlags.AllowAPrimitiveEntry | - (uint) ParcelFlags.AllowDeedToGroup | - (uint) ParcelFlags.CreateObjects | (uint) ParcelFlags.AllowOtherScripts | - (uint) ParcelFlags.SoundLocal | (uint) ParcelFlags.AllowVoiceChat; + private uint _flags = (uint)ParcelFlags.AllowFly | (uint)ParcelFlags.AllowLandmark | + (uint)ParcelFlags.AllowAPrimitiveEntry | + (uint)ParcelFlags.AllowDeedToGroup | + (uint)ParcelFlags.CreateObjects | (uint)ParcelFlags.AllowOtherScripts | + (uint)ParcelFlags.AllowVoiceChat; private byte _landingType = 0; private string _name = "Your Parcel"; @@ -97,16 +97,36 @@ namespace OpenSim.Framework private bool _mediaLoop = false; private bool _obscureMusic = false; private bool _obscureMedia = false; + private float _dwell = 0; + + /// + /// Traffic count of parcel + /// + [XmlIgnore] + public float Dwell + { + get + { + return _dwell; + } + set + { + _dwell = value; + } + } /// /// Whether to obscure parcel media URL /// [XmlIgnore] - public bool ObscureMedia { - get { + public bool ObscureMedia + { + get + { return _obscureMedia; } - set { + set + { _obscureMedia = value; } } @@ -115,11 +135,14 @@ namespace OpenSim.Framework /// Whether to obscure parcel music URL /// [XmlIgnore] - public bool ObscureMusic { - get { + public bool ObscureMusic + { + get + { return _obscureMusic; } - set { + set + { _obscureMusic = value; } } @@ -128,11 +151,14 @@ namespace OpenSim.Framework /// Whether to loop parcel media /// [XmlIgnore] - public bool MediaLoop { - get { + public bool MediaLoop + { + get + { return _mediaLoop; } - set { + set + { _mediaLoop = value; } } @@ -141,11 +167,14 @@ namespace OpenSim.Framework /// Height of parcel media render /// [XmlIgnore] - public int MediaHeight { - get { + public int MediaHeight + { + get + { return _mediaHeight; } - set { + set + { _mediaHeight = value; } } @@ -154,11 +183,14 @@ namespace OpenSim.Framework /// Width of parcel media render /// [XmlIgnore] - public int MediaWidth { - get { + public int MediaWidth + { + get + { return _mediaWidth; } - set { + set + { _mediaWidth = value; } } @@ -167,11 +199,14 @@ namespace OpenSim.Framework /// Upper corner of the AABB for the parcel /// [XmlIgnore] - public Vector3 AABBMax { - get { + public Vector3 AABBMax + { + get + { return _AABBMax; } - set { + set + { _AABBMax = value; } } @@ -179,11 +214,14 @@ namespace OpenSim.Framework /// Lower corner of the AABB for the parcel /// [XmlIgnore] - public Vector3 AABBMin { - get { + public Vector3 AABBMin + { + get + { return _AABBMin; } - set { + set + { _AABBMin = value; } } @@ -191,11 +229,14 @@ namespace OpenSim.Framework /// /// Area in meters^2 the parcel contains /// - public int Area { - get { + public int Area + { + get + { return _area; } - set { + set + { _area = value; } } @@ -203,11 +244,14 @@ namespace OpenSim.Framework /// /// ID of auction (3rd Party Integration) when parcel is being auctioned /// - public uint AuctionID { - get { + public uint AuctionID + { + get + { return _auctionID; } - set { + set + { _auctionID = value; } } @@ -215,11 +259,14 @@ namespace OpenSim.Framework /// /// UUID of authorized buyer of parcel. This is UUID.Zero if anyone can buy it. /// - public UUID AuthBuyerID { - get { + public UUID AuthBuyerID + { + get + { return _authBuyerID; } - set { + set + { _authBuyerID = value; } } @@ -227,11 +274,14 @@ namespace OpenSim.Framework /// /// Category of parcel. Used for classifying the parcel in classified listings /// - public ParcelCategory Category { - get { + public ParcelCategory Category + { + get + { return _category; } - set { + set + { _category = value; } } @@ -239,11 +289,14 @@ namespace OpenSim.Framework /// /// Date that the current owner purchased or claimed the parcel /// - public int ClaimDate { - get { + public int ClaimDate + { + get + { return _claimDate; } - set { + set + { _claimDate = value; } } @@ -251,11 +304,14 @@ namespace OpenSim.Framework /// /// The last price that the parcel was sold at /// - public int ClaimPrice { - get { + public int ClaimPrice + { + get + { return _claimPrice; } - set { + set + { _claimPrice = value; } } @@ -263,11 +319,14 @@ namespace OpenSim.Framework /// /// Global ID for the parcel. (3rd Party Integration) /// - public UUID GlobalID { - get { + public UUID GlobalID + { + get + { return _globalID; } - set { + set + { _globalID = value; } } @@ -275,11 +334,14 @@ namespace OpenSim.Framework /// /// Unique ID of the Group that owns /// - public UUID GroupID { - get { + public UUID GroupID + { + get + { return _groupID; } - set { + set + { _groupID = value; } } @@ -287,11 +349,14 @@ namespace OpenSim.Framework /// /// Returns true if the Land Parcel is owned by a group /// - public bool IsGroupOwned { - get { + public bool IsGroupOwned + { + get + { return _isGroupOwned; } - set { + set + { _isGroupOwned = value; } } @@ -299,11 +364,14 @@ namespace OpenSim.Framework /// /// jp2 data for the image representative of the parcel in the parcel dialog /// - public byte[] Bitmap { - get { + public byte[] Bitmap + { + get + { return _bitmap; } - set { + set + { _bitmap = value; } } @@ -311,11 +379,14 @@ namespace OpenSim.Framework /// /// Parcel Description /// - public string Description { - get { + public string Description + { + get + { return _description; } - set { + set + { _description = value; } } @@ -323,11 +394,14 @@ namespace OpenSim.Framework /// /// Parcel settings. Access flags, Fly, NoPush, Voice, Scripts allowed, etc. ParcelFlags /// - public uint Flags { - get { + public uint Flags + { + get + { return _flags; } - set { + set + { _flags = value; } } @@ -336,11 +410,14 @@ namespace OpenSim.Framework /// Determines if people are able to teleport where they please on the parcel or if they /// get constrainted to a specific point on teleport within the parcel /// - public byte LandingType { - get { + public byte LandingType + { + get + { return _landingType; } - set { + set + { _landingType = value; } } @@ -348,11 +425,14 @@ namespace OpenSim.Framework /// /// Parcel Name /// - public string Name { - get { + public string Name + { + get + { return _name; } - set { + set + { _name = value; } } @@ -360,11 +440,14 @@ namespace OpenSim.Framework /// /// Status of Parcel, Leased, Abandoned, For Sale /// - public ParcelStatus Status { - get { + public ParcelStatus Status + { + get + { return _status; } - set { + set + { _status = value; } } @@ -372,11 +455,14 @@ namespace OpenSim.Framework /// /// Internal ID of the parcel. Sometimes the client will try to use this value /// - public int LocalID { - get { + public int LocalID + { + get + { return _localID; } - set { + set + { _localID = value; } } @@ -384,11 +470,14 @@ namespace OpenSim.Framework /// /// Determines if we scale the media based on the surface it's on /// - public byte MediaAutoScale { - get { + public byte MediaAutoScale + { + get + { return _mediaAutoScale; } - set { + set + { _mediaAutoScale = value; } } @@ -396,11 +485,14 @@ namespace OpenSim.Framework /// /// Texture Guid to replace with the output of the media stream /// - public UUID MediaID { - get { + public UUID MediaID + { + get + { return _mediaID; } - set { + set + { _mediaID = value; } } @@ -408,11 +500,14 @@ namespace OpenSim.Framework /// /// URL to the media file to display /// - public string MediaURL { - get { + public string MediaURL + { + get + { return _mediaURL; } - set { + set + { _mediaURL = value; } } @@ -432,11 +527,14 @@ namespace OpenSim.Framework /// /// URL to the shoutcast music stream to play on the parcel /// - public string MusicURL { - get { + public string MusicURL + { + get + { return _musicURL; } - set { + set + { _musicURL = value; } } @@ -445,11 +543,14 @@ namespace OpenSim.Framework /// Owner Avatar or Group of the parcel. Naturally, all land masses must be /// owned by someone /// - public UUID OwnerID { - get { + public UUID OwnerID + { + get + { return _ownerID; } - set { + set + { _ownerID = value; } } @@ -457,11 +558,14 @@ namespace OpenSim.Framework /// /// List of access data for the parcel. User data, some bitflags, and a time /// - public List ParcelAccessList { - get { + public List ParcelAccessList + { + get + { return _parcelAccessList; } - set { + set + { _parcelAccessList = value; } } @@ -469,11 +573,14 @@ namespace OpenSim.Framework /// /// How long in hours a Pass to the parcel is given /// - public float PassHours { - get { + public float PassHours + { + get + { return _passHours; } - set { + set + { _passHours = value; } } @@ -481,11 +588,14 @@ namespace OpenSim.Framework /// /// Price to purchase a Pass to a restricted parcel /// - public int PassPrice { - get { + public int PassPrice + { + get + { return _passPrice; } - set { + set + { _passPrice = value; } } @@ -493,11 +603,14 @@ namespace OpenSim.Framework /// /// When the parcel is being sold, this is the price to purchase the parcel /// - public int SalePrice { - get { + public int SalePrice + { + get + { return _salePrice; } - set { + set + { _salePrice = value; } } @@ -506,11 +619,14 @@ namespace OpenSim.Framework /// Number of meters^2 in the Simulator /// [XmlIgnore] - public int SimwideArea { - get { + public int SimwideArea + { + get + { return _simwideArea; } - set { + set + { _simwideArea = value; } } @@ -519,11 +635,14 @@ namespace OpenSim.Framework /// Number of SceneObjectPart in the Simulator /// [XmlIgnore] - public int SimwidePrims { - get { + public int SimwidePrims + { + get + { return _simwidePrims; } - set { + set + { _simwidePrims = value; } } @@ -531,11 +650,14 @@ namespace OpenSim.Framework /// /// ID of the snapshot used in the client parcel dialog of the parcel /// - public UUID SnapshotID { - get { + public UUID SnapshotID + { + get + { return _snapshotID; } - set { + set + { _snapshotID = value; } } @@ -544,11 +666,14 @@ namespace OpenSim.Framework /// When teleporting is restricted to a certain point, this is the location /// that the user will be redirected to /// - public Vector3 UserLocation { - get { + public Vector3 UserLocation + { + get + { return _userLocation; } - set { + set + { _userLocation = value; } } @@ -557,11 +682,14 @@ namespace OpenSim.Framework /// When teleporting is restricted to a certain point, this is the rotation /// that the user will be positioned /// - public Vector3 UserLookAt { - get { + public Vector3 UserLookAt + { + get + { return _userLookAt; } - set { + set + { _userLookAt = value; } } @@ -570,11 +698,14 @@ namespace OpenSim.Framework /// Autoreturn number of minutes to return SceneObjectGroup that are owned by someone who doesn't own /// the parcel and isn't set to the same 'group' as the parcel. /// - public int OtherCleanTime { - get { + public int OtherCleanTime + { + get + { return _otherCleanTime; } - set { + set + { _otherCleanTime = value; } } @@ -582,11 +713,14 @@ namespace OpenSim.Framework /// /// parcel media description /// - public string MediaDescription { - get { + public string MediaDescription + { + get + { return _mediaDescription; } - set { + set + { _mediaDescription = value; } } @@ -622,7 +756,7 @@ namespace OpenSim.Framework landData._mediaURL = _mediaURL; landData._musicURL = _musicURL; landData._ownerID = _ownerID; - landData._bitmap = (byte[]) _bitmap.Clone(); + landData._bitmap = (byte[])_bitmap.Clone(); landData._description = _description; landData._flags = _flags; landData._name = _name; @@ -643,6 +777,7 @@ namespace OpenSim.Framework landData._obscureMedia = _obscureMedia; landData._simwideArea = _simwideArea; landData._simwidePrims = _simwidePrims; + landData._dwell = _dwell; landData._parcelAccessList.Clear(); foreach (LandAccessEntry entry in _parcelAccessList) diff --git a/OpenSim/Framework/Monitoring/BaseStatsCollector.cs b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs index 9ee087694b..446e3c0697 100644 --- a/OpenSim/Framework/Monitoring/BaseStatsCollector.cs +++ b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs @@ -43,27 +43,32 @@ namespace OpenSim.Framework.Monitoring StringBuilder sb = new StringBuilder(Environment.NewLine); sb.Append("MEMORY STATISTICS"); sb.Append(Environment.NewLine); - sb.Append( - string.Format( + sb.AppendFormat( "Allocated to OpenSim objects: {0} MB\n", - Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0))); + Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0)); + + sb.AppendFormat( + "OpenSim last object memory churn : {0} MB/s\n", + Math.Round((MemoryWatchdog.LastMemoryChurn * 1000) / 1024.0 / 1024, 3)); + + sb.AppendFormat( + "OpenSim average object memory churn : {0} MB/s\n", + Math.Round((MemoryWatchdog.AverageMemoryChurn * 1000) / 1024.0 / 1024, 3)); Process myprocess = Process.GetCurrentProcess(); if (!myprocess.HasExited) { myprocess.Refresh(); - sb.Append( - string.Format( + sb.AppendFormat( "Process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n", Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0), Math.Round(Process.GetCurrentProcess().PagedMemorySize64 / 1024.0 / 1024.0), - Math.Round(Process.GetCurrentProcess().VirtualMemorySize64 / 1024.0 / 1024.0))); - sb.Append( - string.Format( + Math.Round(Process.GetCurrentProcess().VirtualMemorySize64 / 1024.0 / 1024.0)); + sb.AppendFormat( "Peak process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n", Math.Round(Process.GetCurrentProcess().PeakWorkingSet64 / 1024.0 / 1024.0), Math.Round(Process.GetCurrentProcess().PeakPagedMemorySize64 / 1024.0 / 1024.0), - Math.Round(Process.GetCurrentProcess().PeakVirtualMemorySize64 / 1024.0 / 1024.0))); + Math.Round(Process.GetCurrentProcess().PeakVirtualMemorySize64 / 1024.0 / 1024.0)); } else sb.Append("Process reported as Exited \n"); diff --git a/OpenSim/Framework/Monitoring/MemoryWatchdog.cs b/OpenSim/Framework/Monitoring/MemoryWatchdog.cs index a23cf1fea8..c6010cd092 100644 --- a/OpenSim/Framework/Monitoring/MemoryWatchdog.cs +++ b/OpenSim/Framework/Monitoring/MemoryWatchdog.cs @@ -60,13 +60,21 @@ namespace OpenSim.Framework.Monitoring private static bool m_enabled; /// - /// Average memory churn in bytes per millisecond. + /// Last memory churn in bytes per millisecond. /// public static double AverageMemoryChurn { get { if (m_samples.Count > 0) return m_samples.Average(); else return 0; } } + /// + /// Average memory churn in bytes per millisecond. + /// + public static double LastMemoryChurn + { + get { if (m_samples.Count > 0) return m_samples.Last(); else return 0; } + } + /// /// Maximum number of statistical samples. /// diff --git a/OpenSim/Framework/Monitoring/Properties/AssemblyInfo.cs b/OpenSim/Framework/Monitoring/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..1f2bb4087a --- /dev/null +++ b/OpenSim/Framework/Monitoring/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Framework.Monitoring")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://opensimulator.org")] +[assembly: AssemblyProduct("OpenSim")] +[assembly: AssemblyCopyright("OpenSimulator developers")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("74506fe3-2f9d-44c1-94c9-a30f79d9e0cb")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs index cdd7cc711e..aa862027b8 100644 --- a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs +++ b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs @@ -355,10 +355,25 @@ Asset service request failures: {3}" + Environment.NewLine, sb.Append(Environment.NewLine); sb.Append( string.Format( - "{0,6:0} {1,6:0} {2,6:0} {3,6:0} {4,6:0} {5,6:0.0} {6,6:0.0} {7,6:0.0} {8,6:0.0} {9,6:0.0} {10,6:0.0}", + "{0,6:0} {1,6:0} {2,6:0} {3,6:0} {4,6:0} {5,6:0.0} {6,6:0.0} {7,6:0.0} {8,6:0.0} {9,6:0.0} {10,6:0.0}\n\n", inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime, netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime)); - sb.Append(Environment.NewLine); + + Dictionary> sceneStats; + + if (StatsManager.TryGetStats("scene", out sceneStats)) + { + foreach (KeyValuePair> kvp in sceneStats) + { + foreach (Stat stat in kvp.Value.Values) + { + if (stat.Verbosity == StatVerbosity.Info) + { + sb.AppendFormat("{0} ({1}): {2}{3}\n", stat.Name, stat.Container, stat.Value, stat.UnitName); + } + } + } + } /* sb.Append(Environment.NewLine); diff --git a/OpenSim/Framework/Monitoring/Stats/PercentageStat.cs b/OpenSim/Framework/Monitoring/Stats/PercentageStat.cs new file mode 100644 index 0000000000..60bed55500 --- /dev/null +++ b/OpenSim/Framework/Monitoring/Stats/PercentageStat.cs @@ -0,0 +1,88 @@ +/* + * 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.Text; + +namespace OpenSim.Framework.Monitoring +{ + public class PercentageStat : Stat + { + public long Antecedent { get; set; } + public long Consequent { get; set; } + + public override double Value + { + get + { + // Asking for an update here means that the updater cannot access this value without infinite recursion. + // XXX: A slightly messy but simple solution may be to flick a flag so we can tell if this is being + // called by the pull action and just return the value. + if (StatType == StatType.Pull) + PullAction(this); + + long c = Consequent; + + // Avoid any chance of a multi-threaded divide-by-zero + if (c == 0) + return 0; + + return (double)Antecedent / c * 100; + } + + set + { + throw new InvalidOperationException("Cannot set value on a PercentageStat"); + } + } + + public PercentageStat( + string shortName, + string name, + string description, + string category, + string container, + StatType type, + Action pullAction, + StatVerbosity verbosity) + : base(shortName, name, description, "%", category, container, type, pullAction, verbosity) {} + + public override string ToConsoleString() + { + StringBuilder sb = new StringBuilder(); + + sb.AppendFormat( + "{0}.{1}.{2} : {3:0.##}{4} ({5}/{6})", + Category, Container, ShortName, Value, UnitName, Antecedent, Consequent); + + AppendMeasuresOfInterest(sb); + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/OpenSim/Framework/Monitoring/Stats/Stat.cs b/OpenSim/Framework/Monitoring/Stats/Stat.cs new file mode 100644 index 0000000000..f91251b6ea --- /dev/null +++ b/OpenSim/Framework/Monitoring/Stats/Stat.cs @@ -0,0 +1,238 @@ +/* + * 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.Text; + +namespace OpenSim.Framework.Monitoring +{ + /// + /// Holds individual statistic details + /// + public class Stat + { + /// + /// Category of this stat (e.g. cache, scene, etc). + /// + public string Category { get; private set; } + + /// + /// Containing name for this stat. + /// FIXME: In the case of a scene, this is currently the scene name (though this leaves + /// us with a to-be-resolved problem of non-unique region names). + /// + /// + /// The container. + /// + public string Container { get; private set; } + + public StatType StatType { get; private set; } + + public MeasuresOfInterest MeasuresOfInterest { get; private set; } + + /// + /// Action used to update this stat when the value is requested if it's a pull type. + /// + public Action PullAction { get; private set; } + + public StatVerbosity Verbosity { get; private set; } + public string ShortName { get; private set; } + public string Name { get; private set; } + public string Description { get; private set; } + public virtual string UnitName { get; private set; } + + public virtual double Value + { + get + { + // Asking for an update here means that the updater cannot access this value without infinite recursion. + // XXX: A slightly messy but simple solution may be to flick a flag so we can tell if this is being + // called by the pull action and just return the value. + if (StatType == StatType.Pull) + PullAction(this); + + return m_value; + } + + set + { + m_value = value; + } + } + + private double m_value; + + /// + /// Historical samples for calculating measures of interest average. + /// + /// + /// Will be null if no measures of interest require samples. + /// + private static Queue m_samples; + + /// + /// Maximum number of statistical samples. + /// + /// + /// At the moment this corresponds to 1 minute since the sampling rate is every 2.5 seconds as triggered from + /// the main Watchdog. + /// + private static int m_maxSamples = 24; + + public Stat( + string shortName, + string name, + string description, + string unitName, + string category, + string container, + StatType type, + Action pullAction, + StatVerbosity verbosity) + : this( + shortName, + name, + description, + unitName, + category, + container, + type, + MeasuresOfInterest.None, + pullAction, + verbosity) + { + } + + /// + /// Constructor + /// + /// Short name for the stat. Must not contain spaces. e.g. "LongFrames" + /// Human readable name for the stat. e.g. "Long frames" + /// Description of stat + /// + /// Unit name for the stat. Should be preceeded by a space if the unit name isn't normally appeneded immediately to the value. + /// e.g. " frames" + /// + /// Category under which this stat should appear, e.g. "scene". Do not capitalize. + /// Entity to which this stat relates. e.g. scene name if this is a per scene stat. + /// Push or pull + /// Pull stats need an action to update the stat on request. Push stats should set null here. + /// Measures of interest + /// Verbosity of stat. Controls whether it will appear in short stat display or only full display. + public Stat( + string shortName, + string name, + string description, + string unitName, + string category, + string container, + StatType type, + MeasuresOfInterest moi, + Action pullAction, + StatVerbosity verbosity) + { + if (StatsManager.SubCommands.Contains(category)) + throw new Exception( + string.Format("Stat cannot be in category '{0}' since this is reserved for a subcommand", category)); + + ShortName = shortName; + Name = name; + Description = description; + UnitName = unitName; + Category = category; + Container = container; + StatType = type; + + if (StatType == StatType.Push && pullAction != null) + throw new Exception("A push stat cannot have a pull action"); + else + PullAction = pullAction; + + MeasuresOfInterest = moi; + + if ((moi & MeasuresOfInterest.AverageChangeOverTime) == MeasuresOfInterest.AverageChangeOverTime) + m_samples = new Queue(m_maxSamples); + + Verbosity = verbosity; + } + + /// + /// Record a value in the sample set. + /// + /// + /// Do not call this if MeasuresOfInterest.None + /// + public void RecordValue() + { + double newValue = Value; + + lock (m_samples) + { + if (m_samples.Count >= m_maxSamples) + m_samples.Dequeue(); + + m_samples.Enqueue(newValue); + } + } + + public virtual string ToConsoleString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendFormat("{0}.{1}.{2} : {3}{4}", Category, Container, ShortName, Value, UnitName); + + AppendMeasuresOfInterest(sb); + + return sb.ToString(); + } + + protected void AppendMeasuresOfInterest(StringBuilder sb) + { + if ((MeasuresOfInterest & MeasuresOfInterest.AverageChangeOverTime) + == MeasuresOfInterest.AverageChangeOverTime) + { + double totalChange = 0; + double? lastSample = null; + + lock (m_samples) + { + foreach (double s in m_samples) + { + if (lastSample != null) + totalChange += s - (double)lastSample; + + lastSample = s; + } + } + + int divisor = m_samples.Count <= 1 ? 1 : m_samples.Count - 1; + + sb.AppendFormat(", {0:0.##}{1}/s", totalChange / divisor / (Watchdog.WATCHDOG_INTERVAL_MS / 1000), UnitName); + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs index d78fa6a1f0..0762b01c7d 100644 --- a/OpenSim/Framework/Monitoring/StatsManager.cs +++ b/OpenSim/Framework/Monitoring/StatsManager.cs @@ -25,6 +25,10 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; +using System.Collections.Generic; +using System.Text; + namespace OpenSim.Framework.Monitoring { /// @@ -32,6 +36,24 @@ namespace OpenSim.Framework.Monitoring /// public class StatsManager { + // Subcommand used to list other stats. + public const string AllSubCommand = "all"; + + // Subcommand used to list other stats. + public const string ListSubCommand = "list"; + + // All subcommands + public static HashSet SubCommands = new HashSet { AllSubCommand, ListSubCommand }; + + /// + /// Registered stats categorized by category/container/shortname + /// + /// + /// Do not add or remove directly from this dictionary. + /// + public static Dictionary>> RegisteredStats + = new Dictionary>>(); + private static AssetStatsCollector assetStats; private static UserStatsCollector userStats; private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector(); @@ -40,6 +62,75 @@ namespace OpenSim.Framework.Monitoring public static UserStatsCollector UserStats { get { return userStats; } } public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } } + public static void RegisterConsoleCommands(ICommandConsole console) + { + console.Commands.AddCommand( + "General", + false, + "show stats", + "show stats [list|all|]", + "Show statistical information for this server", + "If no final argument is specified then legacy statistics information is currently shown.\n" + + "If list is specified then statistic categories are shown.\n" + + "If all is specified then all registered statistics are shown.\n" + + "If a category name is specified then only statistics from that category are shown.\n" + + "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS", + HandleShowStatsCommand); + } + + public static void HandleShowStatsCommand(string module, string[] cmd) + { + ICommandConsole con = MainConsole.Instance; + + if (cmd.Length > 2) + { + var categoryName = cmd[2]; + + if (categoryName == AllSubCommand) + { + foreach (var category in RegisteredStats.Values) + { + OutputCategoryStatsToConsole(con, category); + } + } + else if (categoryName == ListSubCommand) + { + con.Output("Statistic categories available are:"); + foreach (string category in RegisteredStats.Keys) + con.OutputFormat(" {0}", category); + } + else + { + Dictionary> category; + if (!RegisteredStats.TryGetValue(categoryName, out category)) + { + con.OutputFormat("No such category as {0}", categoryName); + } + else + { + OutputCategoryStatsToConsole(con, category); + } + } + } + else + { + // Legacy + con.Output(SimExtraStats.Report()); + } + } + + private static void OutputCategoryStatsToConsole( + ICommandConsole con, Dictionary> category) + { + foreach (var container in category.Values) + { + foreach (Stat stat in container.Values) + { + con.Output(stat.ToConsoleString()); + } + } + } + /// /// Start collecting statistics related to assets. /// Should only be called once. @@ -61,5 +152,153 @@ namespace OpenSim.Framework.Monitoring return userStats; } + + /// + /// Registers a statistic. + /// + /// + /// + public static bool RegisterStat(Stat stat) + { + Dictionary> category = null, newCategory; + Dictionary container = null, newContainer; + + lock (RegisteredStats) + { + // Stat name is not unique across category/container/shortname key. + // XXX: For now just return false. This is to avoid problems in regression tests where all tests + // in a class are run in the same instance of the VM. + if (TryGetStat(stat, out category, out container)) + return false; + + // We take a copy-on-write approach here of replacing dictionaries when keys are added or removed. + // This means that we don't need to lock or copy them on iteration, which will be a much more + // common operation after startup. + if (container != null) + newContainer = new Dictionary(container); + else + newContainer = new Dictionary(); + + if (category != null) + newCategory = new Dictionary>(category); + else + newCategory = new Dictionary>(); + + newContainer[stat.ShortName] = stat; + newCategory[stat.Container] = newContainer; + RegisteredStats[stat.Category] = newCategory; + } + + return true; + } + + /// + /// Deregister a statistic + /// > + /// + /// > category = null, newCategory; + Dictionary container = null, newContainer; + + lock (RegisteredStats) + { + if (!TryGetStat(stat, out category, out container)) + return false; + + newContainer = new Dictionary(container); + newContainer.Remove(stat.ShortName); + + newCategory = new Dictionary>(category); + newCategory.Remove(stat.Container); + + newCategory[stat.Container] = newContainer; + RegisteredStats[stat.Category] = newCategory; + + return true; + } + } + + public static bool TryGetStats(string category, out Dictionary> stats) + { + return RegisteredStats.TryGetValue(category, out stats); + } + + public static bool TryGetStat( + Stat stat, + out Dictionary> category, + out Dictionary container) + { + category = null; + container = null; + + lock (RegisteredStats) + { + if (RegisteredStats.TryGetValue(stat.Category, out category)) + { + if (category.TryGetValue(stat.Container, out container)) + { + if (container.ContainsKey(stat.ShortName)) + return true; + } + } + } + + return false; + } + + public static void RecordStats() + { + lock (RegisteredStats) + { + foreach (Dictionary> category in RegisteredStats.Values) + { + foreach (Dictionary container in category.Values) + { + foreach (Stat stat in container.Values) + { + if (stat.MeasuresOfInterest != MeasuresOfInterest.None) + stat.RecordValue(); + } + } + } + } + } + } + + /// + /// Stat type. + /// + /// + /// A push stat is one which is continually updated and so it's value can simply by read. + /// A pull stat is one where reading the value triggers a collection method - the stat is not continually updated. + /// + public enum StatType + { + Push, + Pull + } + + /// + /// Measures of interest for this stat. + /// + [Flags] + public enum MeasuresOfInterest + { + None, + AverageChangeOverTime + } + + /// + /// Verbosity of stat. + /// + /// + /// Info will always be displayed. + /// + public enum StatVerbosity + { + Debug, + Info } } \ No newline at end of file diff --git a/OpenSim/Framework/Monitoring/Watchdog.cs b/OpenSim/Framework/Monitoring/Watchdog.cs index b709baa3c7..69d2db58ce 100644 --- a/OpenSim/Framework/Monitoring/Watchdog.cs +++ b/OpenSim/Framework/Monitoring/Watchdog.cs @@ -39,7 +39,7 @@ namespace OpenSim.Framework.Monitoring public static class Watchdog { /// Timer interval in milliseconds for the watchdog timer - const double WATCHDOG_INTERVAL_MS = 2500.0d; + public const double WATCHDOG_INTERVAL_MS = 2500.0d; /// Default timeout in milliseconds before a thread is considered dead public const int DEFAULT_WATCHDOG_TIMEOUT_MS = 5000; @@ -89,6 +89,17 @@ namespace OpenSim.Framework.Monitoring FirstTick = Environment.TickCount & Int32.MaxValue; LastTick = FirstTick; } + + public ThreadWatchdogInfo(ThreadWatchdogInfo previousTwi) + { + Thread = previousTwi.Thread; + FirstTick = previousTwi.FirstTick; + LastTick = previousTwi.LastTick; + Timeout = previousTwi.Timeout; + IsTimedOut = previousTwi.IsTimedOut; + AlarmIfTimeout = previousTwi.AlarmIfTimeout; + AlarmMethod = previousTwi.AlarmMethod; + } } /// @@ -220,7 +231,25 @@ namespace OpenSim.Framework.Monitoring private static bool RemoveThread(int threadID) { lock (m_threads) - return m_threads.Remove(threadID); + { + ThreadWatchdogInfo twi; + if (m_threads.TryGetValue(threadID, out twi)) + { + m_log.DebugFormat( + "[WATCHDOG]: Removing thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId); + + m_threads.Remove(threadID); + + return true; + } + else + { + m_log.WarnFormat( + "[WATCHDOG]: Requested to remove thread with ID {0} but this is not being monitored", threadID); + + return false; + } + } } public static bool AbortThread(int threadID) @@ -335,7 +364,9 @@ namespace OpenSim.Framework.Monitoring if (callbackInfos == null) callbackInfos = new List(); - callbackInfos.Add(threadInfo); + // Send a copy of the watchdog info to prevent race conditions where the watchdog + // thread updates the monitoring info after an alarm has been sent out. + callbackInfos.Add(new ThreadWatchdogInfo(threadInfo)); } } } @@ -349,6 +380,8 @@ namespace OpenSim.Framework.Monitoring if (MemoryWatchdog.Enabled) MemoryWatchdog.Update(); + StatsManager.RecordStats(); + m_watchdogTimer.Start(); } } diff --git a/OpenSim/Services/InventoryService/InventoryServiceBase.cs b/OpenSim/Framework/Pool.cs similarity index 50% rename from OpenSim/Services/InventoryService/InventoryServiceBase.cs rename to OpenSim/Framework/Pool.cs index 456e4557db..5484f5c2d5 100644 --- a/OpenSim/Services/InventoryService/InventoryServiceBase.cs +++ b/OpenSim/Framework/Pool.cs @@ -27,56 +27,65 @@ using System; using System.Collections.Generic; -using System.Reflection; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Data; -using OpenSim.Services.Interfaces; -using OpenSim.Services.Base; -namespace OpenSim.Services.InventoryService +namespace OpenSim.Framework { - public class InventoryServiceBase : ServiceBase + /// + /// Naive pool implementation. + /// + /// + /// Currently assumes that objects are in a useable state when returned. + /// + public class Pool { - protected IInventoryDataPlugin m_Database = null; - - public InventoryServiceBase(IConfigSource config) : base(config) + /// + /// Number of objects in the pool. + /// + public int Count { - string dllName = String.Empty; - string connString = String.Empty; - - // - // Try reading the [DatabaseService] section first, if it exists - // - IConfig dbConfig = config.Configs["DatabaseService"]; - if (dbConfig != null) + get { - dllName = dbConfig.GetString("StorageProvider", String.Empty); - connString = dbConfig.GetString("ConnectionString", String.Empty); + lock (m_pool) + return m_pool.Count; } - - // - // Try reading the more specific [InventoryService] section, if it exists - // - IConfig inventoryConfig = config.Configs["InventoryService"]; - if (inventoryConfig != null) - { - dllName = inventoryConfig.GetString("StorageProvider", dllName); - connString = inventoryConfig.GetString("ConnectionString", connString); - } - - // - // We tried, but this doesn't exist. We can't proceed. - // - if (dllName.Equals(String.Empty)) - throw new Exception("No InventoryService configuration"); - - m_Database = LoadPlugin(dllName); - if (m_Database == null) - throw new Exception("Could not find a storage interface in the given module"); - - m_Database.Initialise(connString); } + private Stack m_pool; + + /// + /// Maximum pool size. Beyond this, any returned objects are not pooled. + /// + private int m_maxPoolSize; + + private Func m_createFunction; + + public Pool(Func createFunction, int maxSize) + { + m_maxPoolSize = maxSize; + m_createFunction = createFunction; + m_pool = new Stack(m_maxPoolSize); + } + + public T GetObject() + { + lock (m_pool) + { + if (m_pool.Count > 0) + return m_pool.Pop(); + else + return m_createFunction(); + } + } + + public void ReturnObject(T obj) + { + lock (m_pool) + { + if (m_pool.Count >= m_maxPoolSize) + return; + else + m_pool.Push(obj); + } + } } -} +} \ No newline at end of file diff --git a/OpenSim/Framework/RegionFlags.cs b/OpenSim/Framework/RegionFlags.cs new file mode 100644 index 0000000000..a3089b077d --- /dev/null +++ b/OpenSim/Framework/RegionFlags.cs @@ -0,0 +1,53 @@ +/* + * 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; + +namespace OpenSim.Framework +{ + /// + /// Region flags used internally by OpenSimulator to store installation specific information about regions. + /// + /// + /// Don't confuse with OpenMetaverse.RegionFlags which are client facing flags (i.e. they go over the wire). + /// Returned by IGridService.GetRegionFlags() + /// + [Flags] + public enum RegionFlags : int + { + DefaultRegion = 1, // Used for new Rez. Random if multiple defined + FallbackRegion = 2, // Regions we redirect to when the destination is down + RegionOnline = 4, // Set when a region comes online, unset when it unregisters and DeleteOnUnregister is false + NoDirectLogin = 8, // Region unavailable for direct logins (by name) + Persistent = 16, // Don't remove on unregister + LockedOut = 32, // Don't allow registration + NoMove = 64, // Don't allow moving this region + Reservation = 128, // This is an inactive reservation + Authenticate = 256, // Require authentication + Hyperlink = 512 // Record represents a HG link + } +} \ No newline at end of file diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index 4bde7be2e1..e7bed6aeb0 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -122,10 +122,13 @@ namespace OpenSim.Framework public UUID lastMapUUID = UUID.Zero; public string lastMapRefresh = "0"; + private float m_nonphysPrimMin = 0; private int m_nonphysPrimMax = 0; + private float m_physPrimMin = 0; private int m_physPrimMax = 0; private bool m_clampPrimSize = false; private int m_objectCapacity = 0; + private int m_linksetCapacity = 0; private int m_agentCapacity = 0; private string m_regionType = String.Empty; private RegionLightShareData m_windlight = new RegionLightShareData(); @@ -287,11 +290,21 @@ namespace OpenSim.Framework set { m_windlight = value; } } + public float NonphysPrimMin + { + get { return m_nonphysPrimMin; } + } + public int NonphysPrimMax { get { return m_nonphysPrimMax; } } + public float PhysPrimMin + { + get { return m_physPrimMin; } + } + public int PhysPrimMax { get { return m_physPrimMax; } @@ -307,6 +320,11 @@ namespace OpenSim.Framework get { return m_objectCapacity; } } + public int LinksetCapacity + { + get { return m_linksetCapacity; } + } + public int AgentCapacity { get { return m_agentCapacity; } @@ -625,16 +643,31 @@ namespace OpenSim.Framework m_regionType = config.GetString("RegionType", String.Empty); allKeys.Remove("RegionType"); - // Prim stuff - // - m_nonphysPrimMax = config.GetInt("NonphysicalPrimMax", 0); - allKeys.Remove("NonphysicalPrimMax"); + #region Prim stuff + + m_nonphysPrimMin = config.GetFloat("NonPhysicalPrimMin", 0); + allKeys.Remove("NonPhysicalPrimMin"); + + m_nonphysPrimMax = config.GetInt("NonPhysicalPrimMax", 0); + allKeys.Remove("NonPhysicalPrimMax"); + + m_physPrimMin = config.GetFloat("PhysicalPrimMin", 0); + allKeys.Remove("PhysicalPrimMin"); + m_physPrimMax = config.GetInt("PhysicalPrimMax", 0); allKeys.Remove("PhysicalPrimMax"); + m_clampPrimSize = config.GetBoolean("ClampPrimSize", false); allKeys.Remove("ClampPrimSize"); + m_objectCapacity = config.GetInt("MaxPrims", 15000); allKeys.Remove("MaxPrims"); + + m_linksetCapacity = config.GetInt("LinksetPrims", 0); + allKeys.Remove("LinksetPrims"); + + #endregion + m_agentCapacity = config.GetInt("MaxAgents", 100); allKeys.Remove("MaxAgents"); @@ -673,16 +706,27 @@ namespace OpenSim.Framework config.Set("ExternalHostName", m_externalHostName); - if (m_nonphysPrimMax != 0) + if (m_nonphysPrimMin > 0) + config.Set("NonphysicalPrimMax", m_nonphysPrimMin); + + if (m_nonphysPrimMax > 0) config.Set("NonphysicalPrimMax", m_nonphysPrimMax); - if (m_physPrimMax != 0) + + if (m_physPrimMin > 0) + config.Set("PhysicalPrimMax", m_physPrimMin); + + if (m_physPrimMax > 0) config.Set("PhysicalPrimMax", m_physPrimMax); + config.Set("ClampPrimSize", m_clampPrimSize.ToString()); - if (m_objectCapacity != 0) + if (m_objectCapacity > 0) config.Set("MaxPrims", m_objectCapacity); - if (m_agentCapacity != 0) + if (m_linksetCapacity > 0) + config.Set("LinksetPrims", m_linksetCapacity); + + if (m_agentCapacity > 0) config.Set("MaxAgents", m_agentCapacity); if (ScopeID != UUID.Zero) @@ -759,9 +803,15 @@ namespace OpenSim.Framework configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true); + configMember.addConfigurationOption("nonphysical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, + "Minimum size for nonphysical prims", m_nonphysPrimMin.ToString(), true); + configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, "Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true); + configMember.addConfigurationOption("physical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, + "Minimum size for nonphysical prims", m_physPrimMin.ToString(), true); + configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, "Maximum size for physical prims", m_physPrimMax.ToString(), true); @@ -771,6 +821,9 @@ namespace OpenSim.Framework configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, "Max objects this sim will hold", m_objectCapacity.ToString(), true); + configMember.addConfigurationOption("linkset_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, + "Max prims an object will hold", m_linksetCapacity.ToString(), true); + configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, "Max avatars this sim will hold", m_agentCapacity.ToString(), true); @@ -892,6 +945,9 @@ namespace OpenSim.Framework case "object_capacity": m_objectCapacity = (int)configuration_result; break; + case "linkset_capacity": + m_linksetCapacity = (int)configuration_result; + break; case "agent_capacity": m_agentCapacity = (int)configuration_result; break; diff --git a/OpenSim/Framework/RegionLoader/Filesystem/Properties/AssemblyInfo.cs b/OpenSim/Framework/RegionLoader/Filesystem/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..d670f2f129 --- /dev/null +++ b/OpenSim/Framework/RegionLoader/Filesystem/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Framework.RegionLoader.Filesystem")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://opensimulator.org")] +[assembly: AssemblyProduct("OpenSim")] +[assembly: AssemblyCopyright("OpenSimulator developers")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("4ab5c74b-e886-40a1-b67d-a04df285e706")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/RegionLoader/Web/Properties/AssemblyInfo.cs b/OpenSim/Framework/RegionLoader/Web/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..7309a12e88 --- /dev/null +++ b/OpenSim/Framework/RegionLoader/Web/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Framework.RegionLoader.Web")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://opensimulator.org")] +[assembly: AssemblyProduct("OpenSim")] +[assembly: AssemblyCopyright("OpenSimulator developers")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("985afff8-e7ed-4056-acce-39abf7a43d33")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Serialization/ArchiveConstants.cs b/OpenSim/Framework/Serialization/ArchiveConstants.cs index 2c5e0018ec..48f1c4f94f 100644 --- a/OpenSim/Framework/Serialization/ArchiveConstants.cs +++ b/OpenSim/Framework/Serialization/ArchiveConstants.cs @@ -52,6 +52,11 @@ namespace OpenSim.Framework.Serialization /// public const string INVENTORY_PATH = "inventory/"; + /// + /// Path for regions in a multi-region archive + /// + public const string REGIONS_PATH = "regions/"; + /// /// Path for the prims file /// diff --git a/OpenSim/Framework/Serialization/External/OspResolver.cs b/OpenSim/Framework/Serialization/External/OspResolver.cs index d31d27c4a6..fa7160f874 100644 --- a/OpenSim/Framework/Serialization/External/OspResolver.cs +++ b/OpenSim/Framework/Serialization/External/OspResolver.cs @@ -65,9 +65,14 @@ namespace OpenSim.Framework.Serialization UserAccount account = userService.GetUserAccount(UUID.Zero, userId); if (account != null) + { return MakeOspa(account.FirstName, account.LastName); + } // else +// { // m_log.WarnFormat("[OSP RESOLVER]: No user account for {0}", userId); +// System.Console.WriteLine("[OSP RESOLVER]: No user account for {0}", userId); +// } return null; } @@ -79,10 +84,13 @@ namespace OpenSim.Framework.Serialization /// public static string MakeOspa(string firstName, string lastName) { -// m_log.DebugFormat("[OSP RESOLVER]: Making OSPA for {0} {1}", firstName, lastName); + string ospa + = OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName; + +// m_log.DebugFormat("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName); +// System.Console.WriteLine("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName); - return - OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName; + return ospa; } /// diff --git a/OpenSim/Framework/Serialization/Properties/AssemblyInfo.cs b/OpenSim/Framework/Serialization/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..11efa4beb7 --- /dev/null +++ b/OpenSim/Framework/Serialization/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Framework.Serialization")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://opensimulator.org")] +[assembly: AssemblyProduct("OpenSim")] +[assembly: AssemblyCopyright("OpenSimulator developers")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("919db41e-4ac0-4f24-9992-81d62c0ee183")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index cf19002baf..2c21800bbd 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -38,6 +38,8 @@ using log4net; using log4net.Appender; using log4net.Core; using log4net.Repository; +using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Framework.Console; using OpenSim.Framework.Monitoring; @@ -45,16 +47,12 @@ using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using Timer=System.Timers.Timer; -using OpenMetaverse; -using OpenMetaverse.StructuredData; - - namespace OpenSim.Framework.Servers { /// /// Common base for the main OpenSimServers (user, grid, inventory, region, etc) /// - public abstract class BaseOpenSimServer + public abstract class BaseOpenSimServer : ServerBase { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -63,27 +61,6 @@ namespace OpenSim.Framework.Servers /// server. /// private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000); - - protected CommandConsole m_console; - protected OpenSimAppender m_consoleAppender; - protected IAppender m_logFileAppender = null; - - /// - /// Time at which this server was started - /// - protected DateTime m_startuptime; - - /// - /// Record the initial startup directory for info purposes - /// - protected string m_startupDirectory = Environment.CurrentDirectory; - - /// - /// Server version information. Usually VersionInfo + information about git commit, operating system, etc. - /// - protected string m_version; - - protected string m_pidFile = String.Empty; /// /// Random uuid for private data @@ -96,35 +73,13 @@ namespace OpenSim.Framework.Servers get { return m_httpServer; } } - /// - /// Holds the non-viewer statistics collection object for this service/server - /// - protected IStatsCollector m_stats; - - public BaseOpenSimServer() + public BaseOpenSimServer() : base() { - m_startuptime = DateTime.Now; - m_version = VersionInfo.Version; - // Random uuid for private data m_osSecret = UUID.Random().ToString(); m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics); m_periodicDiagnosticsTimer.Enabled = true; - - // This thread will go on to become the console listening thread - Thread.CurrentThread.Name = "ConsoleThread"; - - ILoggerRepository repository = LogManager.GetRepository(); - IAppender[] appenders = repository.GetAppenders(); - - foreach (IAppender appender in appenders) - { - if (appender.Name == "LogFileAppender") - { - m_logFileAppender = appender; - } - } } /// @@ -132,76 +87,46 @@ namespace OpenSim.Framework.Servers /// protected virtual void StartupSpecific() { - if (m_console != null) - { - ILoggerRepository repository = LogManager.GetRepository(); - IAppender[] appenders = repository.GetAppenders(); + if (m_console == null) + return; - foreach (IAppender appender in appenders) - { - if (appender.Name == "Console") - { - m_consoleAppender = (OpenSimAppender)appender; - break; - } - } + RegisterCommonCommands(); + + m_console.Commands.AddCommand("General", false, "quit", + "quit", + "Quit the application", HandleQuit); - if (null == m_consoleAppender) - { - Notice("No appender named Console found (see the log4net config file for this executable)!"); - } - else - { - m_consoleAppender.Console = m_console; - - // If there is no threshold set then the threshold is effectively everything. - if (null == m_consoleAppender.Threshold) - m_consoleAppender.Threshold = Level.All; - - Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); - } - - m_console.Commands.AddCommand("General", false, "quit", - "quit", - "Quit the application", HandleQuit); + m_console.Commands.AddCommand("General", false, "shutdown", + "shutdown", + "Quit the application", HandleQuit); - m_console.Commands.AddCommand("General", false, "shutdown", - "shutdown", - "Quit the application", HandleQuit); + m_console.Commands.AddCommand("General", false, "show threads", + "show threads", + "Show thread status", HandleShow); - m_console.Commands.AddCommand("General", false, "set log level", - "set log level ", - "Set the console logging level", HandleLogLevel); + m_console.Commands.AddCommand("General", false, "show version", + "show version", + "Show server version", HandleShow); - m_console.Commands.AddCommand("General", false, "show info", - "show info", - "Show general information about the server", HandleShow); + m_console.Commands.AddCommand("General", false, "threads abort", + "threads abort ", + "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort); - m_console.Commands.AddCommand("General", false, "show stats", - "show stats", - "Show statistics", HandleShow); + m_console.Commands.AddCommand("General", false, "threads show", + "threads show", + "Show thread status. Synonym for \"show threads\"", + (string module, string[] args) => Notice(GetThreadsReport())); - m_console.Commands.AddCommand("General", false, "show threads", - "show threads", - "Show thread status", HandleShow); + m_console.Commands.AddCommand("General", false, "force gc", + "force gc", + "Manually invoke runtime garbage collection. For debugging purposes", + HandleForceGc); + } - m_console.Commands.AddCommand("General", false, "show uptime", - "show uptime", - "Show server uptime", HandleShow); - - m_console.Commands.AddCommand("General", false, "show version", - "show version", - "Show server version", HandleShow); - - m_console.Commands.AddCommand("General", false, "threads abort", - "threads abort ", - "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort); - - m_console.Commands.AddCommand("General", false, "threads show", - "threads show", - "Show thread status. Synonym for \"show threads\"", - (string module, string[] args) => Notice(GetThreadsReport())); - } + private void HandleForceGc(string module, string[] args) + { + MainConsole.Instance.Output("Manually invoking runtime garbage collection"); + GC.Collect(); } /// @@ -226,12 +151,7 @@ namespace OpenSim.Framework.Servers { StringBuilder sb = new StringBuilder("DIAGNOSTICS\n\n"); sb.Append(GetUptimeReport()); - - if (m_stats != null) - { - sb.Append(m_stats.Report()); - } - + sb.Append(StatsManager.SimExtraStats.Report()); sb.Append(Environment.NewLine); sb.Append(GetThreadsReport()); @@ -286,27 +206,12 @@ namespace OpenSim.Framework.Servers return sb.ToString(); } - /// - /// Return a report about the uptime of this server - /// - /// - protected string GetUptimeReport() - { - StringBuilder sb = new StringBuilder(String.Format("Time now is {0}\n", DateTime.Now)); - sb.Append(String.Format("Server has been running since {0}, {1}\n", m_startuptime.DayOfWeek, m_startuptime)); - sb.Append(String.Format("That is an elapsed time of {0}\n", DateTime.Now - m_startuptime)); - - return sb.ToString(); - } - /// /// Performs initialisation of the scene, such as loading configuration from disk. /// public virtual void Startup() { m_log.Info("[STARTUP]: Beginning startup processing"); - - EnhanceVersionInformation(); m_log.Info("[STARTUP]: Careminster version: " + m_version + Environment.NewLine); // clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and @@ -343,60 +248,10 @@ namespace OpenSim.Framework.Servers Shutdown(); } - private void HandleLogLevel(string module, string[] cmd) + public override void HandleShow(string module, string[] cmd) { - if (null == m_consoleAppender) - { - Notice("No appender named Console found (see the log4net config file for this executable)!"); - return; - } - - if (cmd.Length > 3) - { - string rawLevel = cmd[3]; - - ILoggerRepository repository = LogManager.GetRepository(); - Level consoleLevel = repository.LevelMap[rawLevel]; - - if (consoleLevel != null) - m_consoleAppender.Threshold = consoleLevel; - else - Notice( - String.Format( - "{0} is not a valid logging level. Valid logging levels are ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF", - rawLevel)); - } + base.HandleShow(module, cmd); - Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); - } - - /// - /// Show help information - /// - /// - protected virtual void ShowHelp(string[] helpArgs) - { - Notice(""); - - if (helpArgs.Length == 0) - { - Notice("set log level [level] - change the console logging level only. For example, off or debug."); - Notice("show info - show server information (e.g. startup path)."); - - if (m_stats != null) - Notice("show stats - show statistical information for this server"); - - Notice("show threads - list tracked threads"); - Notice("show uptime - show server startup time and uptime."); - Notice("show version - show server version."); - Notice(""); - - return; - } - } - - public virtual void HandleShow(string module, string[] cmd) - { List args = new List(cmd); args.RemoveAt(0); @@ -405,23 +260,10 @@ namespace OpenSim.Framework.Servers switch (showParams[0]) { - case "info": - ShowInfo(); - break; - - case "stats": - if (m_stats != null) - Notice(m_stats.Report()); - break; - case "threads": Notice(GetThreadsReport()); break; - case "uptime": - Notice(GetUptimeReport()); - break; - case "version": Notice(GetVersionText()); break; @@ -447,165 +289,11 @@ namespace OpenSim.Framework.Servers MainConsole.Instance.OutputFormat("Aborted thread with id {0}", threadId); else MainConsole.Instance.OutputFormat("ERROR - Thread with id {0} not found in managed threads", threadId); - } - - protected void ShowInfo() - { - Notice(GetVersionText()); - Notice("Startup directory: " + m_startupDirectory); - if (null != m_consoleAppender) - Notice(String.Format("Console log level: {0}", m_consoleAppender.Threshold)); - } - - protected string GetVersionText() - { - return String.Format("Version: {0} (interface version {1})", m_version, VersionInfo.MajorInterfaceVersion); - } - - /// - /// Console output is only possible if a console has been established. - /// That is something that cannot be determined within this class. So - /// all attempts to use the console MUST be verified. - /// - /// - protected void Notice(string msg) - { - if (m_console != null) - { - m_console.Output(msg); - } - } - - /// - /// Console output is only possible if a console has been established. - /// That is something that cannot be determined within this class. So - /// all attempts to use the console MUST be verified. - /// - /// - /// - protected void Notice(string format, params string[] components) - { - if (m_console != null) - m_console.OutputFormat(format, components); - } - - /// - /// Enhance the version string with extra information if it's available. - /// - protected void EnhanceVersionInformation() - { - string buildVersion = string.Empty; - - // The subversion information is deprecated and will be removed at a later date - // Add subversion revision information if available - // Try file "svn_revision" in the current directory first, then the .svn info. - // This allows to make the revision available in simulators not running from the source tree. - // FIXME: Making an assumption about the directory we're currently in - we do this all over the place - // elsewhere as well - string gitDir = "../.git/"; - string gitRefPointerPath = gitDir + "HEAD"; - - string svnRevisionFileName = "svn_revision"; - string svnFileName = ".svn/entries"; - string manualVersionFileName = ".version"; - string inputLine; - int strcmp; - - if (File.Exists(manualVersionFileName)) - { - using (StreamReader CommitFile = File.OpenText(manualVersionFileName)) - buildVersion = CommitFile.ReadLine(); - - m_version += buildVersion ?? ""; - } - else if (File.Exists(gitRefPointerPath)) - { -// m_log.DebugFormat("[OPENSIM]: Found {0}", gitRefPointerPath); - - string rawPointer = ""; - - using (StreamReader pointerFile = File.OpenText(gitRefPointerPath)) - rawPointer = pointerFile.ReadLine(); - -// m_log.DebugFormat("[OPENSIM]: rawPointer [{0}]", rawPointer); - - Match m = Regex.Match(rawPointer, "^ref: (.+)$"); - - if (m.Success) - { -// m_log.DebugFormat("[OPENSIM]: Matched [{0}]", m.Groups[1].Value); - - string gitRef = m.Groups[1].Value; - string gitRefPath = gitDir + gitRef; - if (File.Exists(gitRefPath)) - { -// m_log.DebugFormat("[OPENSIM]: Found gitRefPath [{0}]", gitRefPath); - - using (StreamReader refFile = File.OpenText(gitRefPath)) - { - string gitHash = refFile.ReadLine(); - m_version += gitHash.Substring(0, 7); - } - } - } - } - else - { - // Remove the else logic when subversion mirror is no longer used - if (File.Exists(svnRevisionFileName)) - { - StreamReader RevisionFile = File.OpenText(svnRevisionFileName); - buildVersion = RevisionFile.ReadLine(); - buildVersion.Trim(); - RevisionFile.Close(); - } - - if (string.IsNullOrEmpty(buildVersion) && File.Exists(svnFileName)) - { - StreamReader EntriesFile = File.OpenText(svnFileName); - inputLine = EntriesFile.ReadLine(); - while (inputLine != null) - { - // using the dir svn revision at the top of entries file - strcmp = String.Compare(inputLine, "dir"); - if (strcmp == 0) - { - buildVersion = EntriesFile.ReadLine(); - break; - } - else - { - inputLine = EntriesFile.ReadLine(); - } - } - EntriesFile.Close(); - } - - m_version += string.IsNullOrEmpty(buildVersion) ? " " : ("." + buildVersion + " ").Substring(0, 6); - } - } - - protected void CreatePIDFile(string path) - { - try - { - string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString(); - FileStream fs = File.Create(path); - - Byte[] buf = Encoding.ASCII.GetBytes(pidstring); - fs.Write(buf, 0, buf.Length); - fs.Close(); - m_pidFile = path; - } - catch (Exception) - { - } - } + } public string osSecret { // Secret uuid for the simulator - get { return m_osSecret; } - + get { return m_osSecret; } } public string StatReport(IOSHttpRequest httpRequest) @@ -613,27 +301,12 @@ namespace OpenSim.Framework.Servers // If we catch a request for "callback", wrap the response in the value for jsonp if (httpRequest.Query.ContainsKey("callback")) { - return httpRequest.Query["callback"].ToString() + "(" + m_stats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");"; + return httpRequest.Query["callback"].ToString() + "(" + StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");"; } else { - return m_stats.XReport((DateTime.Now - m_startuptime).ToString() , m_version); - } - } - - protected void RemovePIDFile() - { - if (m_pidFile != String.Empty) - { - try - { - File.Delete(m_pidFile); - m_pidFile = String.Empty; - } - catch (Exception) - { - } + return StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version); } } } -} +} \ No newline at end of file diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 788a0b95ee..77fce9e6e4 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -54,8 +54,23 @@ namespace OpenSim.Framework.Servers.HttpServer private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private HttpServerLogWriter httpserverlog = new HttpServerLogWriter(); + /// + /// Gets or sets the debug level. + /// + /// + /// See MainServer.DebugLevel. + /// public int DebugLevel { get; set; } + /// + /// Request number for diagnostic purposes. + /// + /// + /// This is an internal number. In some debug situations an external number may also be supplied in the + /// opensim-request-id header but we are not currently logging this. + /// + public int RequestNumber { get; private set; } + private volatile int NotSocketErrors = 0; public volatile bool HTTPDRunning = false; @@ -67,7 +82,7 @@ namespace OpenSim.Framework.Servers.HttpServer protected Dictionary m_llsdHandlers = new Dictionary(); protected Dictionary m_streamHandlers = new Dictionary(); protected Dictionary m_HTTPHandlers = new Dictionary(); - protected Dictionary m_agentHandlers = new Dictionary(); +// protected Dictionary m_agentHandlers = new Dictionary(); protected Dictionary m_pollHandlers = new Dictionary(); @@ -245,29 +260,29 @@ namespace OpenSim.Framework.Servers.HttpServer return new List(m_pollHandlers.Keys); } - // Note that the agent string is provided simply to differentiate - // the handlers - it is NOT required to be an actual agent header - // value. - public bool AddAgentHandler(string agent, IHttpAgentHandler handler) - { - lock (m_agentHandlers) - { - if (!m_agentHandlers.ContainsKey(agent)) - { - m_agentHandlers.Add(agent, handler); - return true; - } - } - - //must already have a handler for that path so return false - return false; - } - - public List GetAgentHandlerKeys() - { - lock (m_agentHandlers) - return new List(m_agentHandlers.Keys); - } +// // Note that the agent string is provided simply to differentiate +// // the handlers - it is NOT required to be an actual agent header +// // value. +// public bool AddAgentHandler(string agent, IHttpAgentHandler handler) +// { +// lock (m_agentHandlers) +// { +// if (!m_agentHandlers.ContainsKey(agent)) +// { +// m_agentHandlers.Add(agent, handler); +// return true; +// } +// } +// +// //must already have a handler for that path so return false +// return false; +// } +// +// public List GetAgentHandlerKeys() +// { +// lock (m_agentHandlers) +// return new List(m_agentHandlers.Keys); +// } public bool AddLLSDHandler(string path, LLSDMethod handler) { @@ -296,6 +311,8 @@ namespace OpenSim.Framework.Servers.HttpServer private void OnRequest(object source, RequestEventArgs args) { + RequestNumber++; + try { IHttpClientContext context = (IHttpClientContext)source; @@ -406,7 +423,6 @@ namespace OpenSim.Framework.Servers.HttpServer string requestMethod = request.HttpMethod; string uriString = request.RawUrl; -// string reqnum = "unknown"; int requestStartTick = Environment.TickCount; // Will be adjusted later on. @@ -423,22 +439,22 @@ namespace OpenSim.Framework.Servers.HttpServer Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true); - // This is the REST agent interface. We require an agent to properly identify - // itself. If the REST handler recognizes the prefix it will attempt to - // satisfy the request. If it is not recognizable, and no damage has occurred - // the request can be passed through to the other handlers. This is a low - // probability event; if a request is matched it is normally expected to be - // handled - IHttpAgentHandler agentHandler; - - if (TryGetAgentHandler(request, response, out agentHandler)) - { - if (HandleAgentRequest(agentHandler, request, response)) - { - requestEndTick = Environment.TickCount; - return; - } - } +// // This is the REST agent interface. We require an agent to properly identify +// // itself. If the REST handler recognizes the prefix it will attempt to +// // satisfy the request. If it is not recognizable, and no damage has occurred +// // the request can be passed through to the other handlers. This is a low +// // probability event; if a request is matched it is normally expected to be +// // handled +// IHttpAgentHandler agentHandler; +// +// if (TryGetAgentHandler(request, response, out agentHandler)) +// { +// if (HandleAgentRequest(agentHandler, request, response)) +// { +// requestEndTick = Environment.TickCount; +// return; +// } +// } //response.KeepAlive = true; response.SendChunked = false; @@ -450,9 +466,7 @@ namespace OpenSim.Framework.Servers.HttpServer if (TryGetStreamHandler(handlerKey, out requestHandler)) { 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); + LogIncomingToStreamHandler(request, requestHandler); response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type. @@ -529,11 +543,8 @@ namespace OpenSim.Framework.Servers.HttpServer { case null: case "text/html": - 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); + LogIncomingToContentTypeHandler(request); buffer = HandleHTTPRequest(request, response); break; @@ -541,11 +552,8 @@ namespace OpenSim.Framework.Servers.HttpServer case "application/llsd+xml": case "application/xml+llsd": case "application/llsd+json": - 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); + LogIncomingToContentTypeHandler(request); buffer = HandleLLSDRequests(request, response); break; @@ -564,9 +572,7 @@ namespace OpenSim.Framework.Servers.HttpServer if (DoWeHaveALLSDHandler(request.RawUrl)) { 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); + LogIncomingToContentTypeHandler(request); buffer = HandleLLSDRequests(request, response); } @@ -574,18 +580,14 @@ namespace OpenSim.Framework.Servers.HttpServer else if (DoWeHaveAHTTPHandler(request.RawUrl)) { 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); + LogIncomingToContentTypeHandler(request); buffer = HandleHTTPRequest(request, response); } else { if (DebugLevel >= 3) - m_log.DebugFormat( - "[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}", - request.HttpMethod, request.Url.PathAndQuery); + LogIncomingToXmlRpcHandler(request); // generic login request. buffer = HandleXmlRpcRequests(request, response); @@ -629,11 +631,11 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (IOException e) { - m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e); + m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.StackTrace), e); } catch (Exception e) { - m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e); + m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.StackTrace), e); SendHTML500(response); } finally @@ -644,14 +646,93 @@ namespace OpenSim.Framework.Servers.HttpServer if (tickdiff > 3000 && (requestHandler == null || requestHandler.Name == null || requestHandler.Name != "GetTexture")) { m_log.InfoFormat( - "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms", + "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms", + RequestNumber, requestMethod, uriString, requestHandler != null ? requestHandler.Name : "", requestHandler != null ? requestHandler.Description : "", - request.RemoteIPEndPoint.ToString(), + request.RemoteIPEndPoint, tickdiff); } + else if (DebugLevel >= 4) + { + m_log.DebugFormat( + "[BASE HTTP SERVER]: HTTP IN {0} :{1} took {2}ms", + RequestNumber, + Port, + tickdiff); + } + } + } + + private void LogIncomingToStreamHandler(OSHttpRequest request, IRequestHandler requestHandler) + { + m_log.DebugFormat( + "[BASE HTTP SERVER]: HTTP IN {0} :{1} stream handler {2} {3} {4} {5} from {6}", + RequestNumber, + Port, + request.HttpMethod, + request.Url.PathAndQuery, + requestHandler.Name, + requestHandler.Description, + request.RemoteIPEndPoint); + + if (DebugLevel >= 5) + LogIncomingInDetail(request); + } + + private void LogIncomingToContentTypeHandler(OSHttpRequest request) + { + m_log.DebugFormat( + "[BASE HTTP SERVER]: HTTP IN {0} :{1} {2} content type handler {3} {4} from {5}", + RequestNumber, + Port, + (request.ContentType == null || request.ContentType == "") ? "not set" : request.ContentType, + request.HttpMethod, + request.Url.PathAndQuery, + request.RemoteIPEndPoint); + + if (DebugLevel >= 5) + LogIncomingInDetail(request); + } + + private void LogIncomingToXmlRpcHandler(OSHttpRequest request) + { + m_log.DebugFormat( + "[BASE HTTP SERVER]: HTTP IN {0} :{1} assumed generic XMLRPC request {2} {3} from {4}", + RequestNumber, + Port, + request.HttpMethod, + request.Url.PathAndQuery, + request.RemoteIPEndPoint); + + if (DebugLevel >= 5) + LogIncomingInDetail(request); + } + + private void LogIncomingInDetail(OSHttpRequest request) + { + using (StreamReader reader = new StreamReader(Util.Copy(request.InputStream), Encoding.UTF8)) + { + string output; + + if (DebugLevel == 5) + { + const int sampleLength = 80; + char[] sampleChars = new char[sampleLength + 3]; + reader.Read(sampleChars, 0, sampleLength); + sampleChars[80] = '.'; + sampleChars[81] = '.'; + sampleChars[82] = '.'; + output = new string(sampleChars); + } + else + { + output = reader.ReadToEnd(); + } + + m_log.DebugFormat("[BASE HTTP SERVER]: {0}", output.Replace("\n", @"\n")); } } @@ -747,24 +828,24 @@ namespace OpenSim.Framework.Servers.HttpServer } } - private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler) - { - agentHandler = null; - - lock (m_agentHandlers) - { - foreach (IHttpAgentHandler handler in m_agentHandlers.Values) - { - if (handler.Match(request, response)) - { - agentHandler = handler; - return true; - } - } - } - - return false; - } +// private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler) +// { +// agentHandler = null; +// +// lock (m_agentHandlers) +// { +// foreach (IHttpAgentHandler handler in m_agentHandlers.Values) +// { +// if (handler.Match(request, response)) +// { +// agentHandler = handler; +// return true; +// } +// } +// } +// +// return false; +// } /// /// Try all the registered xmlrpc handlers when an xmlrpc request is received. @@ -1737,21 +1818,21 @@ namespace OpenSim.Framework.Servers.HttpServer m_pollHandlers.Remove(path); } - public bool RemoveAgentHandler(string agent, IHttpAgentHandler handler) - { - lock (m_agentHandlers) - { - IHttpAgentHandler foundHandler; - - if (m_agentHandlers.TryGetValue(agent, out foundHandler) && foundHandler == handler) - { - m_agentHandlers.Remove(agent); - return true; - } - } - - return false; - } +// public bool RemoveAgentHandler(string agent, IHttpAgentHandler handler) +// { +// lock (m_agentHandlers) +// { +// IHttpAgentHandler foundHandler; +// +// if (m_agentHandlers.TryGetValue(agent, out foundHandler) && foundHandler == handler) +// { +// m_agentHandlers.Remove(agent); +// return true; +// } +// } +// +// return false; +// } public void RemoveXmlRPCHandler(string method) { diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs index db58f6f468..0bd3aae7d5 100644 --- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs @@ -41,10 +41,10 @@ namespace OpenSim.Framework.Servers.HttpServer uint Port { get; } bool UseSSL { get; } - // Note that the agent string is provided simply to differentiate - // the handlers - it is NOT required to be an actual agent header - // value. - bool AddAgentHandler(string agent, IHttpAgentHandler handler); +// // Note that the agent string is provided simply to differentiate +// // the handlers - it is NOT required to be an actual agent header +// // value. +// bool AddAgentHandler(string agent, IHttpAgentHandler handler); /// /// Add a handler for an HTTP request. @@ -106,13 +106,13 @@ namespace OpenSim.Framework.Servers.HttpServer bool SetDefaultLLSDHandler(DefaultLLSDMethod handler); - /// - /// Remove the agent if it is registered. - /// - /// - /// - /// - bool RemoveAgentHandler(string agent, IHttpAgentHandler handler); +// /// +// /// Remove the agent if it is registered. +// /// +// /// +// /// +// /// +// bool RemoveAgentHandler(string agent, IHttpAgentHandler handler); /// /// Remove an HTTP handler diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs index d0a37d0f81..c19ac320da 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs @@ -53,7 +53,8 @@ namespace OpenSim.Framework.Servers.HttpServer Normal = 0, LslHttp = 1, Inventory = 2, - Texture = 3 + Texture = 3, + Mesh = 4 } public PollServiceEventArgs( diff --git a/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs b/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..02ecc250a1 --- /dev/null +++ b/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Framework.Servers.HttpServer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://opensimulator.org")] +[assembly: AssemblyProduct("OpenSim")] +[assembly: AssemblyCopyright("OpenSimulator developers")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("c4ea5baa-81c4-4867-a645-1ec360c1f164")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs index 8dc0e3a71d..ae7d515e13 100644 --- a/OpenSim/Framework/Servers/MainServer.cs +++ b/OpenSim/Framework/Servers/MainServer.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Reflection; using System.Net; +using System.Text; using log4net; using OpenSim.Framework; using OpenSim.Framework.Console; @@ -47,9 +48,12 @@ namespace OpenSim.Framework.Servers /// 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. + /// 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. + /// If DebugLevel >= 4 then the time taken to fulfill the request is logged. + /// If DebugLevel >= 5 then the start of the body of incoming non-poll HTTP requests will be logged. + /// If DebugLevel >= 6 then the entire body of incoming non-poll HTTP requests will be logged. /// public static int DebugLevel { @@ -101,17 +105,28 @@ namespace OpenSim.Framework.Servers get { return new Dictionary(m_Servers); } } - public static void RegisterHttpConsoleCommands(ICommandConsole console) { console.Commands.AddCommand( - "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" - + "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.", + "Comms", false, "show http-handlers", + "show http-handlers", + "Show all registered http handlers", HandleShowHttpHandlersCommand); + + console.Commands.AddCommand( + "Debug", false, "debug http", "debug http []", + "Turn on http request logging.", + "If in or all and\n" + + " level <= 0 then no extra logging is done.\n" + + " level >= 1 then short warnings are logged when receiving bad input data.\n" + + " level >= 2 then long warnings are logged when receiving bad input data.\n" + + " level >= 3 then short notices about all incoming non-poll HTTP requests are logged.\n" + + " level >= 4 then the time taken to fulfill the request is logged.\n" + + " level >= 5 then a sample from the beginning of the incoming data is logged.\n" + + " level >= 6 then the entire incoming data is logged.\n" + + " no level is specified then the current level is returned.\n\n" + + "If out or all and\n" + + " level >= 3 then short notices about all outgoing requests going through WebUtil are logged.\n" + + " level >= 4 then the time taken to fulfill the request is logged.\n", HandleDebugHttpCommand); } @@ -119,25 +134,120 @@ namespace OpenSim.Framework.Servers /// Turn on some debugging values for OpenSim. /// /// - private static void HandleDebugHttpCommand(string module, string[] args) + private static void HandleDebugHttpCommand(string module, string[] cmdparams) { - if (args.Length == 3) + if (cmdparams.Length < 3) { - int newDebug; - if (int.TryParse(args[2], out newDebug)) - { - MainServer.DebugLevel = newDebug; - MainConsole.Instance.OutputFormat("Debug http level set to {0}", newDebug); - } + MainConsole.Instance.Output("Usage: debug http 0..6"); + return; } - else if (args.Length == 2) + + bool inReqs = false; + bool outReqs = false; + bool allReqs = false; + + string subCommand = cmdparams[2]; + + if (subCommand.ToLower() == "in") { - MainConsole.Instance.OutputFormat("Current debug http level is {0}", MainServer.DebugLevel); + inReqs = true; + } + else if (subCommand.ToLower() == "out") + { + outReqs = true; + } + else if (subCommand.ToLower() == "all") + { + allReqs = true; } else { - MainConsole.Instance.Output("Usage: debug http 0..3"); + MainConsole.Instance.Output("You must specify in, out or all"); + return; } + + if (cmdparams.Length >= 4) + { + string rawNewDebug = cmdparams[3]; + int newDebug; + + if (!int.TryParse(rawNewDebug, out newDebug)) + { + MainConsole.Instance.OutputFormat("{0} is not a valid debug level", rawNewDebug); + return; + } + + if (newDebug < 0 || newDebug > 6) + { + MainConsole.Instance.OutputFormat("{0} is outside the valid debug level range of 0..6", newDebug); + return; + } + + if (allReqs || inReqs) + { + MainServer.DebugLevel = newDebug; + MainConsole.Instance.OutputFormat("IN debug level set to {0}", newDebug); + } + + if (allReqs || outReqs) + { + WebUtil.DebugLevel = newDebug; + MainConsole.Instance.OutputFormat("OUT debug level set to {0}", newDebug); + } + } + else + { + if (allReqs || inReqs) + MainConsole.Instance.OutputFormat("Current IN debug level is {0}", MainServer.DebugLevel); + + if (allReqs || outReqs) + MainConsole.Instance.OutputFormat("Current OUT debug level is {0}", WebUtil.DebugLevel); + } + } + + private static void HandleShowHttpHandlersCommand(string module, string[] args) + { + if (args.Length != 2) + { + MainConsole.Instance.Output("Usage: show http-handlers"); + return; + } + + StringBuilder handlers = new StringBuilder(); + + lock (m_Servers) + { + foreach (BaseHttpServer httpServer in m_Servers.Values) + { + handlers.AppendFormat( + "Registered HTTP Handlers for server at {0}:{1}\n", httpServer.ListenIPAddress, httpServer.Port); + + handlers.AppendFormat("* XMLRPC:\n"); + foreach (String s in httpServer.GetXmlRpcHandlerKeys()) + handlers.AppendFormat("\t{0}\n", s); + + handlers.AppendFormat("* HTTP:\n"); + List poll = httpServer.GetPollServiceHandlerKeys(); + foreach (String s in httpServer.GetHTTPHandlerKeys()) + handlers.AppendFormat("\t{0} {1}\n", s, (poll.Contains(s) ? "(poll service)" : string.Empty)); + +// handlers.AppendFormat("* Agent:\n"); +// foreach (String s in httpServer.GetAgentHandlerKeys()) +// handlers.AppendFormat("\t{0}\n", s); + + handlers.AppendFormat("* LLSD:\n"); + foreach (String s in httpServer.GetLLSDHandlerKeys()) + handlers.AppendFormat("\t{0}\n", s); + + handlers.AppendFormat("* StreamHandlers ({0}):\n", httpServer.GetStreamHandlerKeys().Count); + foreach (String s in httpServer.GetStreamHandlerKeys()) + handlers.AppendFormat("\t{0}\n", s); + + handlers.Append("\n"); + } + } + + MainConsole.Instance.Output(handlers.ToString()); } /// diff --git a/OpenSim/Framework/Servers/Properties/AssemblyInfo.cs b/OpenSim/Framework/Servers/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..021f63c632 --- /dev/null +++ b/OpenSim/Framework/Servers/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Framework.Servers")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://opensimulator.org")] +[assembly: AssemblyProduct("OpenSim")] +[assembly: AssemblyCopyright("OpenSimulator developers")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("b48e8b3e-5c5c-4673-b31f-21e13b8e568b")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs new file mode 100644 index 0000000000..c182a3abca --- /dev/null +++ b/OpenSim/Framework/Servers/ServerBase.cs @@ -0,0 +1,566 @@ +/* + * 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.IO; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using log4net; +using log4net.Appender; +using log4net.Core; +using log4net.Repository; +using Nini.Config; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Servers +{ + public class ServerBase + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public IConfigSource Config { get; protected set; } + + /// + /// Console to be used for any command line output. Can be null, in which case there should be no output. + /// + protected ICommandConsole m_console; + + protected OpenSimAppender m_consoleAppender; + protected FileAppender m_logFileAppender; + + protected DateTime m_startuptime; + protected string m_startupDirectory = Environment.CurrentDirectory; + + protected string m_pidFile = String.Empty; + + /// + /// Server version information. Usually VersionInfo + information about git commit, operating system, etc. + /// + protected string m_version; + + public ServerBase() + { + m_startuptime = DateTime.Now; + m_version = VersionInfo.Version; + EnhanceVersionInformation(); + } + + protected void CreatePIDFile(string path) + { + try + { + string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString(); + + using (FileStream fs = File.Create(path)) + { + Byte[] buf = Encoding.ASCII.GetBytes(pidstring); + fs.Write(buf, 0, buf.Length); + } + + m_pidFile = path; + + m_log.InfoFormat("[SERVER BASE]: Created pid file {0}", m_pidFile); + } + catch (Exception e) + { + m_log.Warn(string.Format("[SERVER BASE]: Could not create PID file at {0} ", path), e); + } + } + + protected void RemovePIDFile() + { + if (m_pidFile != String.Empty) + { + try + { + File.Delete(m_pidFile); + } + catch (Exception e) + { + m_log.Error(string.Format("[SERVER BASE]: Error whilst removing {0} ", m_pidFile), e); + } + + m_pidFile = String.Empty; + } + } + + public void RegisterCommonAppenders(IConfig startupConfig) + { + ILoggerRepository repository = LogManager.GetRepository(); + IAppender[] appenders = repository.GetAppenders(); + + foreach (IAppender appender in appenders) + { + if (appender.Name == "Console") + { + m_consoleAppender = (OpenSimAppender)appender; + } + else if (appender.Name == "LogFileAppender") + { + m_logFileAppender = (FileAppender)appender; + } + } + + if (null == m_consoleAppender) + { + Notice("No appender named Console found (see the log4net config file for this executable)!"); + } + else + { + // FIXME: This should be done through an interface rather than casting. + m_consoleAppender.Console = (ConsoleBase)m_console; + + // If there is no threshold set then the threshold is effectively everything. + if (null == m_consoleAppender.Threshold) + m_consoleAppender.Threshold = Level.All; + + Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); + } + + if (m_logFileAppender != null && startupConfig != null) + { + string cfgFileName = startupConfig.GetString("LogFile", null); + if (cfgFileName != null) + { + m_logFileAppender.File = cfgFileName; + m_logFileAppender.ActivateOptions(); + } + + m_log.InfoFormat("[SERVER BASE]: Logging started to file {0}", m_logFileAppender.File); + } + } + + /// + /// Register common commands once m_console has been set if it is going to be set + /// + public void RegisterCommonCommands() + { + if (m_console == null) + return; + + m_console.Commands.AddCommand( + "General", false, "show info", "show info", "Show general information about the server", HandleShow); + + m_console.Commands.AddCommand( + "General", false, "show uptime", "show uptime", "Show server uptime", HandleShow); + + m_console.Commands.AddCommand( + "General", false, "get log level", "get log level", "Get the current console logging level", + (mod, cmd) => ShowLogLevel()); + + m_console.Commands.AddCommand( + "General", false, "set log level", "set log level ", + "Set the console logging level for this session.", HandleSetLogLevel); + + m_console.Commands.AddCommand( + "General", false, "config set", + "config set
", + "Set a config option. In most cases this is not useful since changed parameters are not dynamically reloaded. Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig); + + m_console.Commands.AddCommand( + "General", false, "config get", + "config get [
] []", + "Synonym for config show", + HandleConfig); + + m_console.Commands.AddCommand( + "General", false, "config show", + "config show [
] []", + "Show config information", + "If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine + + "If a section is given but not a field, then all fields in that section are printed.", + HandleConfig); + + m_console.Commands.AddCommand( + "General", false, "config save", + "config save ", + "Save current configuration to a file at the given path", HandleConfig); + + m_console.Commands.AddCommand( + "General", false, "command-script", + "command-script