diff --git a/OpenSim/Client/Linden/LLProxyLoginModule.cs b/OpenSim/Client/Linden/LLProxyLoginModule.cs index 195feaf390..f9cb3a9337 100644 --- a/OpenSim/Client/Linden/LLProxyLoginModule.cs +++ b/OpenSim/Client/Linden/LLProxyLoginModule.cs @@ -148,8 +148,8 @@ namespace OpenSim.Client.Linden protected void AddHttpHandlers() { //we will add our handlers to the first scene we received, as all scenes share a http server. But will this ever change? - MainServer.Instance.AddXmlRPCHandler("expect_user", ExpectUser); - MainServer.Instance.AddXmlRPCHandler("logoff_user", LogOffUser); + MainServer.Instance.AddXmlRPCHandler("expect_user", ExpectUser, false); + MainServer.Instance.AddXmlRPCHandler("logoff_user", LogOffUser, false); } protected void AddScene(Scene scene) diff --git a/OpenSim/Data/MSSQL/MSSQLAuthenticationData.cs b/OpenSim/Data/MSSQL/MSSQLAuthenticationData.cs index 099faea149..9a17e47a19 100644 --- a/OpenSim/Data/MSSQL/MSSQLAuthenticationData.cs +++ b/OpenSim/Data/MSSQL/MSSQLAuthenticationData.cs @@ -43,6 +43,7 @@ namespace OpenSim.Data.MSSQL private List m_ColumnNames = null; private int m_LastExpire = 0; private string m_ConnectionString; + private MSSQLManager m_database; public MSSQLAuthenticationData(string connectionString, string realm) { @@ -61,12 +62,12 @@ namespace OpenSim.Data.MSSQL AuthenticationData ret = new AuthenticationData(); ret.Data = new Dictionary(); - string sql = string.Format("select * from '{0}' where UUID = @principalID", m_Realm); + string sql = string.Format("select * from {0} where UUID = @principalID", m_Realm); using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand(sql, conn)) { - cmd.Parameters.AddWithValue("@principalID", principalID.ToString()); + cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID)); conn.Open(); using (SqlDataReader result = cmd.ExecuteReader()) { @@ -108,34 +109,33 @@ namespace OpenSim.Data.MSSQL using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand()) { - updateBuilder.AppendFormat("update '{0}' set ", m_Realm); + updateBuilder.AppendFormat("update {0} set ", m_Realm); bool first = true; foreach (string field in fields) { if (!first) updateBuilder.Append(", "); - updateBuilder.AppendFormat("'{0}' = @{0}",field); + updateBuilder.AppendFormat("{0} = @{0}",field); first = false; - - cmd.Parameters.AddWithValue("@" + field, data.Data[field]); + cmd.Parameters.Add(m_database.CreateParameter("@" + field, data.Data[field])); } updateBuilder.Append(" where UUID = @principalID"); cmd.CommandText = updateBuilder.ToString(); cmd.Connection = conn; - - cmd.Parameters.AddWithValue("@principalID", data.PrincipalID.ToString()); + cmd.Parameters.Add(m_database.CreateParameter("@principalID", data.PrincipalID)); + conn.Open(); if (cmd.ExecuteNonQuery() < 1) { StringBuilder insertBuilder = new StringBuilder(); - insertBuilder.AppendFormat("insert into '{0}' ('UUID', '", m_Realm); - insertBuilder.Append(String.Join("', '", fields)); - insertBuilder.Append("') values (@principalID, @"); + insertBuilder.AppendFormat("insert into {0} (UUID, ", m_Realm); + insertBuilder.Append(String.Join(", ", fields)); + insertBuilder.Append(") values ( @principalID, @"); insertBuilder.Append(String.Join(", @", fields)); insertBuilder.Append(")"); @@ -152,12 +152,11 @@ namespace OpenSim.Data.MSSQL public bool SetDataItem(UUID principalID, string item, string value) { - string sql = string.Format("update '{0}' set '{1}' = @{1} where UUID = @UUID", m_Realm, item); + string sql = string.Format("update {0} set {1} = @{1} where UUID = @UUID", m_Realm, item); using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand(sql, conn)) { - cmd.Parameters.AddWithValue("@" + item, value); - cmd.Parameters.AddWithValue("@UUID", principalID.ToString()); + cmd.Parameters.Add(m_database.CreateParameter("@" + item, value)); conn.Open(); if (cmd.ExecuteNonQuery() > 0) return true; @@ -173,9 +172,9 @@ namespace OpenSim.Data.MSSQL using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand(sql, conn)) { - cmd.Parameters.AddWithValue("@principalID", principalID.ToString()); - cmd.Parameters.AddWithValue("@token", token); - cmd.Parameters.AddWithValue("@lifetime", lifetime.ToString()); + cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID)); + cmd.Parameters.Add(m_database.CreateParameter("@token", token)); + cmd.Parameters.Add(m_database.CreateParameter("@lifetime", lifetime)); conn.Open(); if (cmd.ExecuteNonQuery() > 0) @@ -194,9 +193,9 @@ namespace OpenSim.Data.MSSQL using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand(sql, conn)) { - cmd.Parameters.AddWithValue("@principalID", principalID.ToString()); - cmd.Parameters.AddWithValue("@token", token); - cmd.Parameters.AddWithValue("@lifetime", lifetime.ToString()); + cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID)); + cmd.Parameters.Add(m_database.CreateParameter("@token", token)); + cmd.Parameters.Add(m_database.CreateParameter("@lifetime", lifetime)); conn.Open(); if (cmd.ExecuteNonQuery() > 0) diff --git a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs new file mode 100644 index 0000000000..e2ae5cb3c5 --- /dev/null +++ b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs @@ -0,0 +1,1531 @@ +/* + * 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.Data; +using System.Data.SqlClient; +using System.Drawing; +using System.IO; +using System.Reflection; +using log4net; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Data.MSSQL +{ + /// + /// A MSSQL Interface for the Region Server. + /// + public class MSSQLRegionDataStore : IRegionDataStore + { + private const string _migrationStore = "RegionStore"; + + // private static FileSystemDataStore Instance = new FileSystemDataStore(); + private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// The database manager + /// + private MSSQLManager _Database; + + /// + /// Initialises the region datastore + /// + /// The connection string. + public void Initialise(string connectionString) + { + if (!string.IsNullOrEmpty(connectionString)) + { + _Database = new MSSQLManager(connectionString); + } + else + { + IniFile iniFile = new IniFile("mssql_connection.ini"); + string settingDataSource = iniFile.ParseFileReadValue("data_source"); + string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog"); + string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info"); + string settingUserId = iniFile.ParseFileReadValue("user_id"); + string settingPassword = iniFile.ParseFileReadValue("password"); + + _Database = new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, settingPassword); + } + + //Migration settings + _Database.CheckMigration(_migrationStore); + } + + /// + /// Dispose the database + /// + public void Dispose() { } + + #region SceneObjectGroup region for loading and Store of the scene. + + /// + /// Loads the objects present in the region. + /// + /// The region UUID. + /// + public List LoadObjects(UUID regionUUID) + { + UUID lastGroupID = UUID.Zero; + + Dictionary prims = new Dictionary(); + Dictionary objects = new Dictionary(); + SceneObjectGroup grp = null; + + + string query = "SELECT *, " + + "sort = CASE WHEN prims.UUID = prims.SceneGroupID THEN 0 ELSE 1 END " + + "FROM prims " + + "LEFT JOIN primshapes ON prims.UUID = primshapes.UUID " + + "WHERE RegionUUID = @RegionUUID " + + "ORDER BY SceneGroupID asc, sort asc, LinkNumber asc"; + + using (AutoClosingSqlCommand command = _Database.Query(query)) + { + command.Parameters.Add(_Database.CreateParameter("@regionUUID", regionUUID)); + + using (SqlDataReader reader = command.ExecuteReader()) + { + while (reader.Read()) + { + SceneObjectPart sceneObjectPart = BuildPrim(reader); + if (reader["Shape"] is DBNull) + sceneObjectPart.Shape = PrimitiveBaseShape.Default; + else + sceneObjectPart.Shape = BuildShape(reader); + + prims[sceneObjectPart.UUID] = sceneObjectPart; + + UUID groupID = new UUID((Guid)reader["SceneGroupID"]); + + if (groupID != lastGroupID) // New SOG + { + if (grp != null) + objects[grp.UUID] = grp; + + lastGroupID = groupID; + + // There sometimes exist OpenSim bugs that 'orphan groups' so that none of the prims are + // recorded as the root prim (for which the UUID must equal the persisted group UUID). In + // this case, force the UUID to be the same as the group UUID so that at least these can be + // deleted (we need to change the UUID so that any other prims in the linkset can also be + // deleted). + if (sceneObjectPart.UUID != groupID && groupID != UUID.Zero) + { + _Log.WarnFormat( + "[REGION DB]: Found root prim {0} {1} at {2} where group was actually {3}. Forcing UUID to group UUID", + sceneObjectPart.Name, sceneObjectPart.UUID, sceneObjectPart.GroupPosition, groupID); + + sceneObjectPart.UUID = groupID; + } + + grp = new SceneObjectGroup(sceneObjectPart); + } + else + { + // Black magic to preserve link numbers + // Why is this needed, fix this in AddPart method. + int link = sceneObjectPart.LinkNum; + + grp.AddPart(sceneObjectPart); + + if (link != 0) + sceneObjectPart.LinkNum = link; + } + } + } + } + + if (grp != null) + objects[grp.UUID] = grp; + + // Instead of attempting to LoadItems on every prim, + // most of which probably have no items... get a + // list from DB of all prims which have items and + // LoadItems only on those + List primsWithInventory = new List(); + string qry = "select distinct primID from primitems"; + using (AutoClosingSqlCommand command = _Database.Query(qry)) + { + using (SqlDataReader itemReader = command.ExecuteReader()) + { + while (itemReader.Read()) + { + if (!(itemReader["primID"] is DBNull)) + { + UUID primID = new UUID(itemReader["primID"].ToString()); + if (prims.ContainsKey(primID)) + { + primsWithInventory.Add(prims[primID]); + } + } + } + } + } + + LoadItems(primsWithInventory); + + _Log.DebugFormat("[REGION DB]: Loaded {0} objects using {1} prims", objects.Count, prims.Count); + + return new List(objects.Values); + } + + /// + /// Load in the prim's persisted inventory. + /// + /// all prims with inventory on a region + private void LoadItems(List allPrimsWithInventory) + { + + using (AutoClosingSqlCommand command = _Database.Query("SELECT * FROM primitems WHERE PrimID = @PrimID")) + { + foreach (SceneObjectPart objectPart in allPrimsWithInventory) + { + command.Parameters.Clear(); + command.Parameters.Add(_Database.CreateParameter("@PrimID", objectPart.UUID)); + + List inventory = new List(); + + using (SqlDataReader reader = command.ExecuteReader()) + { + while (reader.Read()) + { + TaskInventoryItem item = BuildItem(reader); + + item.ParentID = objectPart.UUID; // Values in database are + // often wrong + inventory.Add(item); + } + } + + objectPart.Inventory.RestoreInventoryItems(inventory); + } + } + } + + /// + /// Stores all object's details apart from inventory + /// + /// + /// + public void StoreObject(SceneObjectGroup obj, UUID regionUUID) + { + _Log.InfoFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count); + + using (SqlConnection conn = _Database.DatabaseConnection()) + { + SqlTransaction transaction = conn.BeginTransaction(); + + try + { + foreach (SceneObjectPart sceneObjectPart in obj.Children.Values) + { + //Update prim + using (SqlCommand sqlCommand = conn.CreateCommand()) + { + sqlCommand.Transaction = transaction; + try + { + StoreSceneObjectPrim(sceneObjectPart, sqlCommand, obj.UUID, regionUUID); + } + catch (SqlException sqlEx) + { + _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrim SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber); + throw; + } + } + + //Update primshapes + using (SqlCommand sqlCommand = conn.CreateCommand()) + { + sqlCommand.Transaction = transaction; + try + { + StoreSceneObjectPrimShapes(sceneObjectPart, sqlCommand, obj.UUID, regionUUID); + } + catch (SqlException sqlEx) + { + _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrimShapes SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber); + throw; + } + } + } + + transaction.Commit(); + } + catch (Exception ex) + { + _Log.ErrorFormat("[REGION DB]: Store SceneObjectGroup error: {0}, Rolling back...", ex.Message); + try + { + transaction.Rollback(); + } + catch (Exception ex2) + { + //Show error + _Log.InfoFormat("[REGION DB]: Rollback of SceneObjectGroup store transaction failed with error: {0}", ex2.Message); + + } + } + } + + } + + /// + /// Stores the prim of the sceneobjectpart. + /// + /// The sceneobjectpart or prim. + /// The SQL command with the transaction. + /// The scenegroup UUID. + /// The region UUID. + private void StoreSceneObjectPrim(SceneObjectPart sceneObjectPart, SqlCommand sqlCommand, UUID sceneGroupID, UUID regionUUID) + { + //Big query to update or insert a new prim. + //Note for SQL Server 2008 this could be simplified + string queryPrims = @" +IF EXISTS (SELECT UUID FROM prims WHERE UUID = @UUID) + BEGIN + UPDATE prims SET + CreationDate = @CreationDate, Name = @Name, Text = @Text, Description = @Description, SitName = @SitName, + TouchName = @TouchName, ObjectFlags = @ObjectFlags, OwnerMask = @OwnerMask, NextOwnerMask = @NextOwnerMask, GroupMask = @GroupMask, + EveryoneMask = @EveryoneMask, BaseMask = @BaseMask, PositionX = @PositionX, PositionY = @PositionY, PositionZ = @PositionZ, + GroupPositionX = @GroupPositionX, GroupPositionY = @GroupPositionY, GroupPositionZ = @GroupPositionZ, VelocityX = @VelocityX, + VelocityY = @VelocityY, VelocityZ = @VelocityZ, AngularVelocityX = @AngularVelocityX, AngularVelocityY = @AngularVelocityY, + AngularVelocityZ = @AngularVelocityZ, AccelerationX = @AccelerationX, AccelerationY = @AccelerationY, + AccelerationZ = @AccelerationZ, RotationX = @RotationX, RotationY = @RotationY, RotationZ = @RotationZ, RotationW = @RotationW, + SitTargetOffsetX = @SitTargetOffsetX, SitTargetOffsetY = @SitTargetOffsetY, SitTargetOffsetZ = @SitTargetOffsetZ, + SitTargetOrientW = @SitTargetOrientW, SitTargetOrientX = @SitTargetOrientX, SitTargetOrientY = @SitTargetOrientY, + SitTargetOrientZ = @SitTargetOrientZ, RegionUUID = @RegionUUID, CreatorID = @CreatorID, OwnerID = @OwnerID, GroupID = @GroupID, + LastOwnerID = @LastOwnerID, SceneGroupID = @SceneGroupID, PayPrice = @PayPrice, PayButton1 = @PayButton1, PayButton2 = @PayButton2, + PayButton3 = @PayButton3, PayButton4 = @PayButton4, LoopedSound = @LoopedSound, LoopedSoundGain = @LoopedSoundGain, + TextureAnimation = @TextureAnimation, OmegaX = @OmegaX, OmegaY = @OmegaY, OmegaZ = @OmegaZ, CameraEyeOffsetX = @CameraEyeOffsetX, + CameraEyeOffsetY = @CameraEyeOffsetY, CameraEyeOffsetZ = @CameraEyeOffsetZ, CameraAtOffsetX = @CameraAtOffsetX, + CameraAtOffsetY = @CameraAtOffsetY, CameraAtOffsetZ = @CameraAtOffsetZ, ForceMouselook = @ForceMouselook, + ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice, + SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem, + ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches, + LinkNumber = @LinkNumber + WHERE UUID = @UUID + END +ELSE + BEGIN + INSERT INTO + prims ( + UUID, CreationDate, Name, Text, Description, SitName, TouchName, ObjectFlags, OwnerMask, NextOwnerMask, GroupMask, + EveryoneMask, BaseMask, PositionX, PositionY, PositionZ, GroupPositionX, GroupPositionY, GroupPositionZ, VelocityX, + VelocityY, VelocityZ, AngularVelocityX, AngularVelocityY, AngularVelocityZ, AccelerationX, AccelerationY, AccelerationZ, + RotationX, RotationY, RotationZ, RotationW, SitTargetOffsetX, SitTargetOffsetY, SitTargetOffsetZ, SitTargetOrientW, + SitTargetOrientX, SitTargetOrientY, SitTargetOrientZ, RegionUUID, CreatorID, OwnerID, GroupID, LastOwnerID, SceneGroupID, + PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX, + OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ, + ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA, + ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber + ) VALUES ( + @UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask, + @EveryoneMask, @BaseMask, @PositionX, @PositionY, @PositionZ, @GroupPositionX, @GroupPositionY, @GroupPositionZ, @VelocityX, + @VelocityY, @VelocityZ, @AngularVelocityX, @AngularVelocityY, @AngularVelocityZ, @AccelerationX, @AccelerationY, @AccelerationZ, + @RotationX, @RotationY, @RotationZ, @RotationW, @SitTargetOffsetX, @SitTargetOffsetY, @SitTargetOffsetZ, @SitTargetOrientW, + @SitTargetOrientX, @SitTargetOrientY, @SitTargetOrientZ, @RegionUUID, @CreatorID, @OwnerID, @GroupID, @LastOwnerID, @SceneGroupID, + @PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX, + @OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ, + @ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA, + @ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber + ) + END"; + + //Set commandtext. + sqlCommand.CommandText = queryPrims; + //Add parameters + sqlCommand.Parameters.AddRange(CreatePrimParameters(sceneObjectPart, sceneGroupID, regionUUID)); + + //Execute the query. If it fails then error is trapped in calling function + sqlCommand.ExecuteNonQuery(); + } + + /// + /// Stores the scene object prim shapes. + /// + /// The sceneobjectpart containing prim shape. + /// The SQL command with the transaction. + /// The scenegroup UUID. + /// The region UUID. + private void StoreSceneObjectPrimShapes(SceneObjectPart sceneObjectPart, SqlCommand sqlCommand, UUID sceneGroupID, UUID regionUUID) + { + //Big query to or insert or update primshapes + //Note for SQL Server 2008 this can be simplified + string queryPrimShapes = @" +IF EXISTS (SELECT UUID FROM primshapes WHERE UUID = @UUID) + BEGIN + UPDATE primshapes SET + Shape = @Shape, ScaleX = @ScaleX, ScaleY = @ScaleY, ScaleZ = @ScaleZ, PCode = @PCode, PathBegin = @PathBegin, + PathEnd = @PathEnd, PathScaleX = @PathScaleX, PathScaleY = @PathScaleY, PathShearX = @PathShearX, PathShearY = @PathShearY, + PathSkew = @PathSkew, PathCurve = @PathCurve, PathRadiusOffset = @PathRadiusOffset, PathRevolutions = @PathRevolutions, + PathTaperX = @PathTaperX, PathTaperY = @PathTaperY, PathTwist = @PathTwist, PathTwistBegin = @PathTwistBegin, + ProfileBegin = @ProfileBegin, ProfileEnd = @ProfileEnd, ProfileCurve = @ProfileCurve, ProfileHollow = @ProfileHollow, + Texture = @Texture, ExtraParams = @ExtraParams, State = @State + WHERE UUID = @UUID + END +ELSE + BEGIN + INSERT INTO + primshapes ( + UUID, Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY, + PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin, + ProfileEnd, ProfileCurve, ProfileHollow, Texture, ExtraParams, State + ) VALUES ( + @UUID, @Shape, @ScaleX, @ScaleY, @ScaleZ, @PCode, @PathBegin, @PathEnd, @PathScaleX, @PathScaleY, @PathShearX, @PathShearY, + @PathSkew, @PathCurve, @PathRadiusOffset, @PathRevolutions, @PathTaperX, @PathTaperY, @PathTwist, @PathTwistBegin, @ProfileBegin, + @ProfileEnd, @ProfileCurve, @ProfileHollow, @Texture, @ExtraParams, @State + ) + END"; + + //Set commandtext. + sqlCommand.CommandText = queryPrimShapes; + + //Add parameters + sqlCommand.Parameters.AddRange(CreatePrimShapeParameters(sceneObjectPart, sceneGroupID, regionUUID)); + + //Execute the query. If it fails then error is trapped in calling function + sqlCommand.ExecuteNonQuery(); + + } + + /// + /// Removes a object from the database. + /// Meaning removing it from tables Prims, PrimShapes and PrimItems + /// + /// id of scenegroup + /// regionUUID (is this used anyway + public void RemoveObject(UUID objectID, UUID regionUUID) + { + _Log.InfoFormat("[MSSQL]: Removing obj: {0} from region: {1}", objectID, regionUUID); + + //Remove from prims and primsitem table + string sqlPrims = "DELETE FROM PRIMS WHERE SceneGroupID = @objectID"; + string sqlPrimItems = "DELETE FROM PRIMITEMS WHERE primID in (SELECT UUID FROM PRIMS WHERE SceneGroupID = @objectID)"; + string sqlPrimShapes = "DELETE FROM PRIMSHAPES WHERE uuid in (SELECT UUID FROM PRIMS WHERE SceneGroupID = @objectID)"; + + lock (_Database) + { + //Using the non transaction mode. + using (AutoClosingSqlCommand cmd = _Database.Query(sqlPrimShapes)) + { + cmd.Parameters.Add(_Database.CreateParameter("objectID", objectID)); + cmd.ExecuteNonQuery(); + + cmd.CommandText = sqlPrimItems; + cmd.ExecuteNonQuery(); + + cmd.CommandText = sqlPrims; + cmd.ExecuteNonQuery(); + } + } + } + + /// + /// Store the inventory of a prim. Warning deletes everything first and then adds all again. + /// + /// + /// + public void StorePrimInventory(UUID primID, ICollection items) + { + //_Log.InfoFormat("[REGION DB: Persisting Prim Inventory with prim ID {0}", primID); + + //Statement from MySQL section! + // For now, we're just going to crudely remove all the previous inventory items + // no matter whether they have changed or not, and replace them with the current set. + + //Delete everything from PrimID + //TODO add index on PrimID in DB, if not already exist + using (AutoClosingSqlCommand cmd = _Database.Query("DELETE PRIMITEMS WHERE primID = @primID")) + { + cmd.Parameters.Add(_Database.CreateParameter("@primID", primID)); + cmd.ExecuteNonQuery(); + } + + string sql = + @"INSERT INTO primitems ( + itemID,primID,assetID,parentFolderID,invType,assetType,name,description,creationDate,creatorID,ownerID,lastOwnerID,groupID, + nextPermissions,currentPermissions,basePermissions,everyonePermissions,groupPermissions,flags) + VALUES (@itemID,@primID,@assetID,@parentFolderID,@invType,@assetType,@name,@description,@creationDate,@creatorID,@ownerID, + @lastOwnerID,@groupID,@nextPermissions,@currentPermissions,@basePermissions,@everyonePermissions,@groupPermissions,@flags)"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + foreach (TaskInventoryItem taskItem in items) + { + cmd.Parameters.AddRange(CreatePrimInventoryParameters(taskItem)); + cmd.ExecuteNonQuery(); + + cmd.Parameters.Clear(); + } + } + } + + #endregion + + /// + /// Loads the terrain map. + /// + /// regionID. + /// + public double[,] LoadTerrain(UUID regionID) + { + double[,] terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; + terrain.Initialize(); + + string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + // MySqlParameter param = new MySqlParameter(); + cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); + + using (SqlDataReader reader = cmd.ExecuteReader()) + { + int rev; + if (reader.Read()) + { + MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]); + BinaryReader br = new BinaryReader(str); + for (int x = 0; x < (int)Constants.RegionSize; x++) + { + for (int y = 0; y < (int)Constants.RegionSize; y++) + { + terrain[x, y] = br.ReadDouble(); + } + } + rev = (int)reader["Revision"]; + } + else + { + _Log.Info("[REGION DB]: No terrain found for region"); + return null; + } + _Log.Info("[REGION DB]: Loaded terrain revision r" + rev); + } + } + + return terrain; + } + + /// + /// Stores the terrain map to DB. + /// + /// terrain map data. + /// regionID. + public void StoreTerrain(double[,] terrain, UUID regionID) + { + int revision = Util.UnixTimeSinceEpoch(); + + //Delete old terrain map + string sql = "delete from terrain where RegionUUID=@RegionUUID"; + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); + cmd.ExecuteNonQuery(); + } + + sql = "insert into terrain(RegionUUID, Revision, Heightfield) values(@RegionUUID, @Revision, @Heightfield)"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); + cmd.Parameters.Add(_Database.CreateParameter("@Revision", revision)); + cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", serializeTerrain(terrain))); + cmd.ExecuteNonQuery(); + } + + _Log.Info("[REGION DB]: Stored terrain revision r " + revision); + } + + /// + /// Loads all the land objects of a region. + /// + /// The region UUID. + /// + public List LoadLandObjects(UUID regionUUID) + { + List LandDataForRegion = new List(); + + string sql = "select * from land where RegionUUID = @RegionUUID"; + + //Retrieve all land data from region + using (AutoClosingSqlCommand cmdLandData = _Database.Query(sql)) + { + cmdLandData.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionUUID)); + + using (SqlDataReader readerLandData = cmdLandData.ExecuteReader()) + { + while (readerLandData.Read()) + { + LandDataForRegion.Add(BuildLandData(readerLandData)); + } + } + } + + //Retrieve all accesslist data for all landdata + foreach (LandData LandData in LandDataForRegion) + { + sql = "select * from landaccesslist where LandUUID = @LandUUID"; + using (AutoClosingSqlCommand cmdAccessList = _Database.Query(sql)) + { + cmdAccessList.Parameters.Add(_Database.CreateParameter("@LandUUID", LandData.GlobalID)); + using (SqlDataReader readerAccessList = cmdAccessList.ExecuteReader()) + { + while (readerAccessList.Read()) + { + LandData.ParcelAccessList.Add(BuildLandAccessData(readerAccessList)); + } + } + } + } + + //Return data + return LandDataForRegion; + } + + /// + /// Stores land object with landaccess list. + /// + /// parcel data. + public void StoreLandObject(ILandObject parcel) + { + //As this is only one record in land table I just delete all and then add a new record. + //As the delete landaccess is already in the mysql code + + //Delete old values + RemoveLandObject(parcel.LandData.GlobalID); + + //Insert new values + string sql = @"INSERT INTO [land] +([UUID],[RegionUUID],[LocalLandID],[Bitmap],[Name],[Description],[OwnerUUID],[IsGroupOwned],[Area],[AuctionID],[Category],[ClaimDate],[ClaimPrice],[GroupUUID],[SalePrice],[LandStatus],[LandFlags],[LandingType],[MediaAutoScale],[MediaTextureUUID],[MediaURL],[MusicURL],[PassHours],[PassPrice],[SnapshotUUID],[UserLocationX],[UserLocationY],[UserLocationZ],[UserLookAtX],[UserLookAtY],[UserLookAtZ],[AuthbuyerID],[OtherCleanTime],[Dwell]) +VALUES +(@UUID,@RegionUUID,@LocalLandID,@Bitmap,@Name,@Description,@OwnerUUID,@IsGroupOwned,@Area,@AuctionID,@Category,@ClaimDate,@ClaimPrice,@GroupUUID,@SalePrice,@LandStatus,@LandFlags,@LandingType,@MediaAutoScale,@MediaTextureUUID,@MediaURL,@MusicURL,@PassHours,@PassPrice,@SnapshotUUID,@UserLocationX,@UserLocationY,@UserLocationZ,@UserLookAtX,@UserLookAtY,@UserLookAtZ,@AuthbuyerID,@OtherCleanTime,@Dwell)"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.AddRange(CreateLandParameters(parcel.LandData, parcel.RegionUUID)); + + cmd.ExecuteNonQuery(); + } + + sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags]) VALUES (@LandUUID,@AccessUUID,@Flags)"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + foreach (ParcelManager.ParcelAccessEntry parcelAccessEntry in parcel.LandData.ParcelAccessList) + { + cmd.Parameters.AddRange(CreateLandAccessParameters(parcelAccessEntry, parcel.RegionUUID)); + + cmd.ExecuteNonQuery(); + cmd.Parameters.Clear(); + } + } + } + + /// + /// Removes a land object from DB. + /// + /// UUID of landobject + public void RemoveLandObject(UUID globalID) + { + using (AutoClosingSqlCommand cmd = _Database.Query("delete from land where UUID=@UUID")) + { + cmd.Parameters.Add(_Database.CreateParameter("@UUID", globalID)); + cmd.ExecuteNonQuery(); + } + + using (AutoClosingSqlCommand cmd = _Database.Query("delete from landaccesslist where LandUUID=@UUID")) + { + cmd.Parameters.Add(_Database.CreateParameter("@UUID", globalID)); + cmd.ExecuteNonQuery(); + } + } + + /// + /// Loads the settings of a region. + /// + /// The region UUID. + /// + public RegionSettings LoadRegionSettings(UUID regionUUID) + { + string sql = "select * from regionsettings where regionUUID = @regionUUID"; + RegionSettings regionSettings; + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.Add(_Database.CreateParameter("@regionUUID", regionUUID)); + using (SqlDataReader reader = cmd.ExecuteReader()) + { + if (reader.Read()) + { + regionSettings = BuildRegionSettings(reader); + regionSettings.OnSave += StoreRegionSettings; + + return regionSettings; + } + } + } + + //If comes here then there is now region setting for that region + regionSettings = new RegionSettings(); + regionSettings.RegionUUID = regionUUID; + regionSettings.OnSave += StoreRegionSettings; + + //Store new values + StoreNewRegionSettings(regionSettings); + + return regionSettings; + } + + /// + /// Store region settings, need to check if the check is really necesary. If we can make something for creating new region. + /// + /// region settings. + public void StoreRegionSettings(RegionSettings regionSettings) + { + //Little check if regionUUID already exist in DB + string regionUUID; + using (AutoClosingSqlCommand cmd = _Database.Query("SELECT regionUUID FROM regionsettings WHERE regionUUID = @regionUUID")) + { + cmd.Parameters.Add(_Database.CreateParameter("@regionUUID", regionSettings.RegionUUID)); + regionUUID = cmd.ExecuteScalar().ToString(); + } + + if (string.IsNullOrEmpty(regionUUID)) + { + StoreNewRegionSettings(regionSettings); + } + else + { + //This method only updates region settings!!! First call LoadRegionSettings to create new region settings in DB + string sql = + @"UPDATE [regionsettings] SET [block_terraform] = @block_terraform ,[block_fly] = @block_fly ,[allow_damage] = @allow_damage +,[restrict_pushing] = @restrict_pushing ,[allow_land_resell] = @allow_land_resell ,[allow_land_join_divide] = @allow_land_join_divide +,[block_show_in_search] = @block_show_in_search ,[agent_limit] = @agent_limit ,[object_bonus] = @object_bonus ,[maturity] = @maturity +,[disable_scripts] = @disable_scripts ,[disable_collisions] = @disable_collisions ,[disable_physics] = @disable_physics +,[terrain_texture_1] = @terrain_texture_1 ,[terrain_texture_2] = @terrain_texture_2 ,[terrain_texture_3] = @terrain_texture_3 +,[terrain_texture_4] = @terrain_texture_4 ,[elevation_1_nw] = @elevation_1_nw ,[elevation_2_nw] = @elevation_2_nw +,[elevation_1_ne] = @elevation_1_ne ,[elevation_2_ne] = @elevation_2_ne ,[elevation_1_se] = @elevation_1_se ,[elevation_2_se] = @elevation_2_se +,[elevation_1_sw] = @elevation_1_sw ,[elevation_2_sw] = @elevation_2_sw ,[water_height] = @water_height ,[terrain_raise_limit] = @terrain_raise_limit +,[terrain_lower_limit] = @terrain_lower_limit ,[use_estate_sun] = @use_estate_sun ,[fixed_sun] = @fixed_sun ,[sun_position] = @sun_position +,[covenant] = @covenant , [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz, [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id + WHERE [regionUUID] = @regionUUID"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.AddRange(CreateRegionSettingParameters(regionSettings)); + + cmd.ExecuteNonQuery(); + } + } + } + + public void Shutdown() + { + //Not used?? + } + + #region Private Methods + + /// + /// Serializes the terrain data for storage in DB. + /// + /// terrain data + /// + private static Array serializeTerrain(double[,] val) + { + MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) * sizeof(double)); + BinaryWriter bw = new BinaryWriter(str); + + // TODO: COMPATIBILITY - Add byte-order conversions + for (int x = 0; x < (int)Constants.RegionSize; x++) + for (int y = 0; y < (int)Constants.RegionSize; y++) + { + double height = val[x, y]; + if (height == 0.0) + height = double.Epsilon; + + bw.Write(height); + } + + return str.ToArray(); + } + + /// + /// Stores new regionsettings. + /// + /// The region settings. + private void StoreNewRegionSettings(RegionSettings regionSettings) + { + string sql = @"INSERT INTO [regionsettings] + ([regionUUID],[block_terraform],[block_fly],[allow_damage],[restrict_pushing],[allow_land_resell],[allow_land_join_divide], + [block_show_in_search],[agent_limit],[object_bonus],[maturity],[disable_scripts],[disable_collisions],[disable_physics], + [terrain_texture_1],[terrain_texture_2],[terrain_texture_3],[terrain_texture_4],[elevation_1_nw],[elevation_2_nw],[elevation_1_ne], + [elevation_2_ne],[elevation_1_se],[elevation_2_se],[elevation_1_sw],[elevation_2_sw],[water_height],[terrain_raise_limit], + [terrain_lower_limit],[use_estate_sun],[fixed_sun],[sun_position],[covenant],[sunvectorx], [sunvectory], [sunvectorz],[Sandbox], [loaded_creation_datetime], [loaded_creation_id] + ) + VALUES + (@regionUUID,@block_terraform,@block_fly,@allow_damage,@restrict_pushing,@allow_land_resell,@allow_land_join_divide, + @block_show_in_search,@agent_limit,@object_bonus,@maturity,@disable_scripts,@disable_collisions,@disable_physics, + @terrain_texture_1,@terrain_texture_2,@terrain_texture_3,@terrain_texture_4,@elevation_1_nw,@elevation_2_nw,@elevation_1_ne, + @elevation_2_ne,@elevation_1_se,@elevation_2_se,@elevation_1_sw,@elevation_2_sw,@water_height,@terrain_raise_limit, + @terrain_lower_limit,@use_estate_sun,@fixed_sun,@sun_position,@covenant,@sunvectorx,@sunvectory, @sunvectorz, @Sandbox, @loaded_creation_datetime, @loaded_creation_id)"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.AddRange(CreateRegionSettingParameters(regionSettings)); + cmd.ExecuteNonQuery(); + } + } + + #region Private DataRecord conversion methods + + /// + /// Builds the region settings from a datarecod. + /// + /// datarecord with regionsettings. + /// + private static RegionSettings BuildRegionSettings(IDataRecord row) + { + //TODO change this is some more generic code so we doesnt have to change it every time a new field is added? + RegionSettings newSettings = new RegionSettings(); + + newSettings.RegionUUID = new UUID((Guid)row["regionUUID"]); + newSettings.BlockTerraform = Convert.ToBoolean(row["block_terraform"]); + newSettings.AllowDamage = Convert.ToBoolean(row["allow_damage"]); + newSettings.BlockFly = Convert.ToBoolean(row["block_fly"]); + newSettings.RestrictPushing = Convert.ToBoolean(row["restrict_pushing"]); + newSettings.AllowLandResell = Convert.ToBoolean(row["allow_land_resell"]); + newSettings.AllowLandJoinDivide = Convert.ToBoolean(row["allow_land_join_divide"]); + newSettings.BlockShowInSearch = Convert.ToBoolean(row["block_show_in_search"]); + newSettings.AgentLimit = Convert.ToInt32(row["agent_limit"]); + newSettings.ObjectBonus = Convert.ToDouble(row["object_bonus"]); + newSettings.Maturity = Convert.ToInt32(row["maturity"]); + newSettings.DisableScripts = Convert.ToBoolean(row["disable_scripts"]); + newSettings.DisableCollisions = Convert.ToBoolean(row["disable_collisions"]); + newSettings.DisablePhysics = Convert.ToBoolean(row["disable_physics"]); + newSettings.TerrainTexture1 = new UUID((Guid)row["terrain_texture_1"]); + newSettings.TerrainTexture2 = new UUID((Guid)row["terrain_texture_2"]); + newSettings.TerrainTexture3 = new UUID((Guid)row["terrain_texture_3"]); + newSettings.TerrainTexture4 = new UUID((Guid)row["terrain_texture_4"]); + newSettings.Elevation1NW = Convert.ToDouble(row["elevation_1_nw"]); + newSettings.Elevation2NW = Convert.ToDouble(row["elevation_2_nw"]); + newSettings.Elevation1NE = Convert.ToDouble(row["elevation_1_ne"]); + newSettings.Elevation2NE = Convert.ToDouble(row["elevation_2_ne"]); + newSettings.Elevation1SE = Convert.ToDouble(row["elevation_1_se"]); + newSettings.Elevation2SE = Convert.ToDouble(row["elevation_2_se"]); + newSettings.Elevation1SW = Convert.ToDouble(row["elevation_1_sw"]); + newSettings.Elevation2SW = Convert.ToDouble(row["elevation_2_sw"]); + newSettings.WaterHeight = Convert.ToDouble(row["water_height"]); + newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]); + newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]); + newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]); + newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]); + newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]); + newSettings.SunPosition = Convert.ToDouble(row["sun_position"]); + newSettings.SunVector = new Vector3( + Convert.ToSingle(row["sunvectorx"]), + Convert.ToSingle(row["sunvectory"]), + Convert.ToSingle(row["sunvectorz"]) + ); + newSettings.Covenant = new UUID((Guid)row["covenant"]); + + newSettings.LoadedCreationDateTime = Convert.ToInt32(row["loaded_creation_datetime"]); + + if (row["loaded_creation_id"] is DBNull) + newSettings.LoadedCreationID = ""; + else + newSettings.LoadedCreationID = (String)row["loaded_creation_id"]; + return newSettings; + } + + /// + /// Builds the land data from a datarecord. + /// + /// datarecord with land data + /// + private static LandData BuildLandData(IDataRecord row) + { + LandData newData = new LandData(); + + newData.GlobalID = new UUID((Guid)row["UUID"]); + newData.LocalID = Convert.ToInt32(row["LocalLandID"]); + + // Bitmap is a byte[512] + newData.Bitmap = (Byte[])row["Bitmap"]; + + newData.Name = (string)row["Name"]; + newData.Description = (string)row["Description"]; + newData.OwnerID = new UUID((Guid)row["OwnerUUID"]); + newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); + newData.Area = Convert.ToInt32(row["Area"]); + newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented + newData.Category = (ParcelCategory)Convert.ToInt32(row["Category"]); + //Enum libsecondlife.Parcel.ParcelCategory + newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]); + newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]); + newData.GroupID = new UUID((Guid)row["GroupUUID"]); + newData.SalePrice = Convert.ToInt32(row["SalePrice"]); + newData.Status = (ParcelStatus)Convert.ToInt32(row["LandStatus"]); + //Enum. libsecondlife.Parcel.ParcelStatus + newData.Flags = Convert.ToUInt32(row["LandFlags"]); + newData.LandingType = Convert.ToByte(row["LandingType"]); + newData.MediaAutoScale = Convert.ToByte(row["MediaAutoScale"]); + newData.MediaID = new UUID((Guid)row["MediaTextureUUID"]); + newData.MediaURL = (string)row["MediaURL"]; + newData.MusicURL = (string)row["MusicURL"]; + newData.PassHours = Convert.ToSingle(row["PassHours"]); + newData.PassPrice = Convert.ToInt32(row["PassPrice"]); + +// UUID authedbuyer; +// UUID snapshotID; +// +// if (UUID.TryParse((string)row["AuthBuyerID"], out authedbuyer)) +// newData.AuthBuyerID = authedbuyer; +// +// if (UUID.TryParse((string)row["SnapshotUUID"], out snapshotID)) +// newData.SnapshotID = snapshotID; + newData.AuthBuyerID = new UUID((Guid) row["AuthBuyerID"]); + newData.SnapshotID = new UUID((Guid)row["SnapshotUUID"]); + + newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]); + newData.Dwell = Convert.ToInt32(row["Dwell"]); + + try + { + newData.UserLocation = + new Vector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]), + Convert.ToSingle(row["UserLocationZ"])); + newData.UserLookAt = + new Vector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]), + Convert.ToSingle(row["UserLookAtZ"])); + } + catch (InvalidCastException) + { + newData.UserLocation = Vector3.Zero; + newData.UserLookAt = Vector3.Zero; + _Log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name); + } + + newData.ParcelAccessList = new List(); + + return newData; + } + + /// + /// Builds the landaccess data from a data record. + /// + /// datarecord with landaccess data + /// + private static ParcelManager.ParcelAccessEntry BuildLandAccessData(IDataRecord row) + { + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = new UUID((Guid)row["AccessUUID"]); + entry.Flags = (AccessList)Convert.ToInt32(row["Flags"]); + entry.Time = new DateTime(); + return entry; + } + + /// + /// Builds the prim from a datarecord. + /// + /// datarecord + /// + private static SceneObjectPart BuildPrim(IDataRecord primRow) + { + SceneObjectPart prim = new SceneObjectPart(); + + prim.UUID = new UUID((Guid)primRow["UUID"]); + // explicit conversion of integers is required, which sort + // of sucks. No idea if there is a shortcut here or not. + prim.CreationDate = Convert.ToInt32(primRow["CreationDate"]); + prim.Name = (string)primRow["Name"]; + // various text fields + prim.Text = (string)primRow["Text"]; + prim.Color = Color.FromArgb(Convert.ToInt32(primRow["ColorA"]), + Convert.ToInt32(primRow["ColorR"]), + Convert.ToInt32(primRow["ColorG"]), + Convert.ToInt32(primRow["ColorB"])); + prim.Description = (string)primRow["Description"]; + prim.SitName = (string)primRow["SitName"]; + prim.TouchName = (string)primRow["TouchName"]; + // permissions + prim.ObjectFlags = Convert.ToUInt32(primRow["ObjectFlags"]); + prim.CreatorID = new UUID((Guid)primRow["CreatorID"]); + prim.OwnerID = new UUID((Guid)primRow["OwnerID"]); + prim.GroupID = new UUID((Guid)primRow["GroupID"]); + prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]); + prim.OwnerMask = Convert.ToUInt32(primRow["OwnerMask"]); + prim.NextOwnerMask = Convert.ToUInt32(primRow["NextOwnerMask"]); + prim.GroupMask = Convert.ToUInt32(primRow["GroupMask"]); + prim.EveryoneMask = Convert.ToUInt32(primRow["EveryoneMask"]); + prim.BaseMask = Convert.ToUInt32(primRow["BaseMask"]); + // vectors + prim.OffsetPosition = new Vector3( + Convert.ToSingle(primRow["PositionX"]), + Convert.ToSingle(primRow["PositionY"]), + Convert.ToSingle(primRow["PositionZ"])); + + prim.GroupPosition = new Vector3( + Convert.ToSingle(primRow["GroupPositionX"]), + Convert.ToSingle(primRow["GroupPositionY"]), + Convert.ToSingle(primRow["GroupPositionZ"])); + + prim.Velocity = new Vector3( + Convert.ToSingle(primRow["VelocityX"]), + Convert.ToSingle(primRow["VelocityY"]), + Convert.ToSingle(primRow["VelocityZ"])); + + prim.AngularVelocity = new Vector3( + Convert.ToSingle(primRow["AngularVelocityX"]), + Convert.ToSingle(primRow["AngularVelocityY"]), + Convert.ToSingle(primRow["AngularVelocityZ"])); + + prim.Acceleration = new Vector3( + Convert.ToSingle(primRow["AccelerationX"]), + Convert.ToSingle(primRow["AccelerationY"]), + Convert.ToSingle(primRow["AccelerationZ"])); + + // quaternions + prim.RotationOffset = new Quaternion( + Convert.ToSingle(primRow["RotationX"]), + Convert.ToSingle(primRow["RotationY"]), + Convert.ToSingle(primRow["RotationZ"]), + Convert.ToSingle(primRow["RotationW"])); + + prim.SitTargetPositionLL = new Vector3( + Convert.ToSingle(primRow["SitTargetOffsetX"]), + Convert.ToSingle(primRow["SitTargetOffsetY"]), + Convert.ToSingle(primRow["SitTargetOffsetZ"])); + + prim.SitTargetOrientationLL = new Quaternion( + Convert.ToSingle(primRow["SitTargetOrientX"]), + Convert.ToSingle(primRow["SitTargetOrientY"]), + Convert.ToSingle(primRow["SitTargetOrientZ"]), + Convert.ToSingle(primRow["SitTargetOrientW"])); + + prim.PayPrice[0] = Convert.ToInt32(primRow["PayPrice"]); + prim.PayPrice[1] = Convert.ToInt32(primRow["PayButton1"]); + prim.PayPrice[2] = Convert.ToInt32(primRow["PayButton2"]); + prim.PayPrice[3] = Convert.ToInt32(primRow["PayButton3"]); + prim.PayPrice[4] = Convert.ToInt32(primRow["PayButton4"]); + + prim.Sound = new UUID((Guid)primRow["LoopedSound"]); + prim.SoundGain = Convert.ToSingle(primRow["LoopedSoundGain"]); + prim.SoundFlags = 1; // If it's persisted at all, it's looped + + if (!(primRow["TextureAnimation"] is DBNull)) + prim.TextureAnimation = (Byte[])primRow["TextureAnimation"]; + if (!(primRow["ParticleSystem"] is DBNull)) + prim.ParticleSystem = (Byte[])primRow["ParticleSystem"]; + + prim.RotationalVelocity = new Vector3( + Convert.ToSingle(primRow["OmegaX"]), + Convert.ToSingle(primRow["OmegaY"]), + Convert.ToSingle(primRow["OmegaZ"])); + + prim.SetCameraEyeOffset(new Vector3( + Convert.ToSingle(primRow["CameraEyeOffsetX"]), + Convert.ToSingle(primRow["CameraEyeOffsetY"]), + Convert.ToSingle(primRow["CameraEyeOffsetZ"]) + )); + + prim.SetCameraAtOffset(new Vector3( + Convert.ToSingle(primRow["CameraAtOffsetX"]), + Convert.ToSingle(primRow["CameraAtOffsetY"]), + Convert.ToSingle(primRow["CameraAtOffsetZ"]) + )); + + if (Convert.ToInt16(primRow["ForceMouselook"]) != 0) + prim.SetForceMouselook(true); + + prim.ScriptAccessPin = Convert.ToInt32(primRow["ScriptAccessPin"]); + + if (Convert.ToInt16(primRow["AllowedDrop"]) != 0) + prim.AllowedDrop = true; + + if (Convert.ToInt16(primRow["DieAtEdge"]) != 0) + prim.DIE_AT_EDGE = true; + + prim.SalePrice = Convert.ToInt32(primRow["SalePrice"]); + prim.ObjectSaleType = Convert.ToByte(primRow["SaleType"]); + + prim.Material = Convert.ToByte(primRow["Material"]); + + if (!(primRow["ClickAction"] is DBNull)) + prim.ClickAction = Convert.ToByte(primRow["ClickAction"]); + + prim.CollisionSound = new UUID((Guid)primRow["CollisionSound"]); + prim.CollisionSoundVolume = Convert.ToSingle(primRow["CollisionSoundVolume"]); + if (Convert.ToInt16(primRow["PassTouches"]) != 0) + prim.PassTouches = true; + prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]); + + return prim; + } + + /// + /// Builds the prim shape from a datarecord. + /// + /// The row. + /// + private static PrimitiveBaseShape BuildShape(IDataRecord shapeRow) + { + PrimitiveBaseShape baseShape = new PrimitiveBaseShape(); + + baseShape.Scale = new Vector3( + Convert.ToSingle(shapeRow["ScaleX"]), + Convert.ToSingle(shapeRow["ScaleY"]), + Convert.ToSingle(shapeRow["ScaleZ"])); + + // paths + baseShape.PCode = Convert.ToByte(shapeRow["PCode"]); + baseShape.PathBegin = Convert.ToUInt16(shapeRow["PathBegin"]); + baseShape.PathEnd = Convert.ToUInt16(shapeRow["PathEnd"]); + baseShape.PathScaleX = Convert.ToByte(shapeRow["PathScaleX"]); + baseShape.PathScaleY = Convert.ToByte(shapeRow["PathScaleY"]); + baseShape.PathShearX = Convert.ToByte(shapeRow["PathShearX"]); + baseShape.PathShearY = Convert.ToByte(shapeRow["PathShearY"]); + baseShape.PathSkew = Convert.ToSByte(shapeRow["PathSkew"]); + baseShape.PathCurve = Convert.ToByte(shapeRow["PathCurve"]); + baseShape.PathRadiusOffset = Convert.ToSByte(shapeRow["PathRadiusOffset"]); + baseShape.PathRevolutions = Convert.ToByte(shapeRow["PathRevolutions"]); + baseShape.PathTaperX = Convert.ToSByte(shapeRow["PathTaperX"]); + baseShape.PathTaperY = Convert.ToSByte(shapeRow["PathTaperY"]); + baseShape.PathTwist = Convert.ToSByte(shapeRow["PathTwist"]); + baseShape.PathTwistBegin = Convert.ToSByte(shapeRow["PathTwistBegin"]); + // profile + baseShape.ProfileBegin = Convert.ToUInt16(shapeRow["ProfileBegin"]); + baseShape.ProfileEnd = Convert.ToUInt16(shapeRow["ProfileEnd"]); + baseShape.ProfileCurve = Convert.ToByte(shapeRow["ProfileCurve"]); + baseShape.ProfileHollow = Convert.ToUInt16(shapeRow["ProfileHollow"]); + + byte[] textureEntry = (byte[])shapeRow["Texture"]; + baseShape.TextureEntry = textureEntry; + + baseShape.ExtraParams = (byte[])shapeRow["ExtraParams"]; + + try + { + baseShape.State = Convert.ToByte(shapeRow["State"]); + } + catch (InvalidCastException) + { + } + + return baseShape; + } + + /// + /// Build a prim inventory item from the persisted data. + /// + /// + /// + private static TaskInventoryItem BuildItem(IDataRecord inventoryRow) + { + TaskInventoryItem taskItem = new TaskInventoryItem(); + + taskItem.ItemID = new UUID((Guid)inventoryRow["itemID"]); + taskItem.ParentPartID = new UUID((Guid)inventoryRow["primID"]); + taskItem.AssetID = new UUID((Guid)inventoryRow["assetID"]); + taskItem.ParentID = new UUID((Guid)inventoryRow["parentFolderID"]); + + taskItem.InvType = Convert.ToInt32(inventoryRow["invType"]); + taskItem.Type = Convert.ToInt32(inventoryRow["assetType"]); + + taskItem.Name = (string)inventoryRow["name"]; + taskItem.Description = (string)inventoryRow["description"]; + taskItem.CreationDate = Convert.ToUInt32(inventoryRow["creationDate"]); + taskItem.CreatorID = new UUID((Guid)inventoryRow["creatorID"]); + taskItem.OwnerID = new UUID((Guid)inventoryRow["ownerID"]); + taskItem.LastOwnerID = new UUID((Guid)inventoryRow["lastOwnerID"]); + taskItem.GroupID = new UUID((Guid)inventoryRow["groupID"]); + + taskItem.NextPermissions = Convert.ToUInt32(inventoryRow["nextPermissions"]); + taskItem.CurrentPermissions = Convert.ToUInt32(inventoryRow["currentPermissions"]); + taskItem.BasePermissions = Convert.ToUInt32(inventoryRow["basePermissions"]); + taskItem.EveryonePermissions = Convert.ToUInt32(inventoryRow["everyonePermissions"]); + taskItem.GroupPermissions = Convert.ToUInt32(inventoryRow["groupPermissions"]); + taskItem.Flags = Convert.ToUInt32(inventoryRow["flags"]); + + return taskItem; + } + + #endregion + + #region Create parameters methods + + /// + /// Creates the prim inventory parameters. + /// + /// item in inventory. + /// + private SqlParameter[] CreatePrimInventoryParameters(TaskInventoryItem taskItem) + { + List parameters = new List(); + + parameters.Add(_Database.CreateParameter("itemID", taskItem.ItemID)); + parameters.Add(_Database.CreateParameter("primID", taskItem.ParentPartID)); + parameters.Add(_Database.CreateParameter("assetID", taskItem.AssetID)); + parameters.Add(_Database.CreateParameter("parentFolderID", taskItem.ParentID)); + parameters.Add(_Database.CreateParameter("invType", taskItem.InvType)); + parameters.Add(_Database.CreateParameter("assetType", taskItem.Type)); + + parameters.Add(_Database.CreateParameter("name", taskItem.Name)); + parameters.Add(_Database.CreateParameter("description", taskItem.Description)); + parameters.Add(_Database.CreateParameter("creationDate", taskItem.CreationDate)); + parameters.Add(_Database.CreateParameter("creatorID", taskItem.CreatorID)); + parameters.Add(_Database.CreateParameter("ownerID", taskItem.OwnerID)); + parameters.Add(_Database.CreateParameter("lastOwnerID", taskItem.LastOwnerID)); + parameters.Add(_Database.CreateParameter("groupID", taskItem.GroupID)); + parameters.Add(_Database.CreateParameter("nextPermissions", taskItem.NextPermissions)); + parameters.Add(_Database.CreateParameter("currentPermissions", taskItem.CurrentPermissions)); + parameters.Add(_Database.CreateParameter("basePermissions", taskItem.BasePermissions)); + parameters.Add(_Database.CreateParameter("everyonePermissions", taskItem.EveryonePermissions)); + parameters.Add(_Database.CreateParameter("groupPermissions", taskItem.GroupPermissions)); + parameters.Add(_Database.CreateParameter("flags", taskItem.Flags)); + + return parameters.ToArray(); + } + + /// + /// Creates the region setting parameters. + /// + /// regionsettings. + /// + private SqlParameter[] CreateRegionSettingParameters(RegionSettings settings) + { + List parameters = new List(); + + parameters.Add(_Database.CreateParameter("regionUUID", settings.RegionUUID)); + parameters.Add(_Database.CreateParameter("block_terraform", settings.BlockTerraform)); + parameters.Add(_Database.CreateParameter("block_fly", settings.BlockFly)); + parameters.Add(_Database.CreateParameter("allow_damage", settings.AllowDamage)); + parameters.Add(_Database.CreateParameter("restrict_pushing", settings.RestrictPushing)); + parameters.Add(_Database.CreateParameter("allow_land_resell", settings.AllowLandResell)); + parameters.Add(_Database.CreateParameter("allow_land_join_divide", settings.AllowLandJoinDivide)); + parameters.Add(_Database.CreateParameter("block_show_in_search", settings.BlockShowInSearch)); + parameters.Add(_Database.CreateParameter("agent_limit", settings.AgentLimit)); + parameters.Add(_Database.CreateParameter("object_bonus", settings.ObjectBonus)); + parameters.Add(_Database.CreateParameter("maturity", settings.Maturity)); + parameters.Add(_Database.CreateParameter("disable_scripts", settings.DisableScripts)); + parameters.Add(_Database.CreateParameter("disable_collisions", settings.DisableCollisions)); + parameters.Add(_Database.CreateParameter("disable_physics", settings.DisablePhysics)); + parameters.Add(_Database.CreateParameter("terrain_texture_1", settings.TerrainTexture1)); + parameters.Add(_Database.CreateParameter("terrain_texture_2", settings.TerrainTexture2)); + parameters.Add(_Database.CreateParameter("terrain_texture_3", settings.TerrainTexture3)); + parameters.Add(_Database.CreateParameter("terrain_texture_4", settings.TerrainTexture4)); + parameters.Add(_Database.CreateParameter("elevation_1_nw", settings.Elevation1NW)); + parameters.Add(_Database.CreateParameter("elevation_2_nw", settings.Elevation2NW)); + parameters.Add(_Database.CreateParameter("elevation_1_ne", settings.Elevation1NE)); + parameters.Add(_Database.CreateParameter("elevation_2_ne", settings.Elevation2NE)); + parameters.Add(_Database.CreateParameter("elevation_1_se", settings.Elevation1SE)); + parameters.Add(_Database.CreateParameter("elevation_2_se", settings.Elevation2SE)); + parameters.Add(_Database.CreateParameter("elevation_1_sw", settings.Elevation1SW)); + parameters.Add(_Database.CreateParameter("elevation_2_sw", settings.Elevation2SW)); + parameters.Add(_Database.CreateParameter("water_height", settings.WaterHeight)); + parameters.Add(_Database.CreateParameter("terrain_raise_limit", settings.TerrainRaiseLimit)); + parameters.Add(_Database.CreateParameter("terrain_lower_limit", settings.TerrainLowerLimit)); + parameters.Add(_Database.CreateParameter("use_estate_sun", settings.UseEstateSun)); + parameters.Add(_Database.CreateParameter("sandbox", settings.Sandbox)); + parameters.Add(_Database.CreateParameter("fixed_sun", settings.FixedSun)); + parameters.Add(_Database.CreateParameter("sun_position", settings.SunPosition)); + parameters.Add(_Database.CreateParameter("sunvectorx", settings.SunVector.X)); + parameters.Add(_Database.CreateParameter("sunvectory", settings.SunVector.Y)); + parameters.Add(_Database.CreateParameter("sunvectorz", settings.SunVector.Z)); + parameters.Add(_Database.CreateParameter("covenant", settings.Covenant)); + parameters.Add(_Database.CreateParameter("Loaded_Creation_DateTime", settings.LoadedCreationDateTime)); + parameters.Add(_Database.CreateParameter("Loaded_Creation_ID", settings.LoadedCreationID)); + + return parameters.ToArray(); + } + + /// + /// Creates the land parameters. + /// + /// land parameters. + /// region UUID. + /// + private SqlParameter[] CreateLandParameters(LandData land, UUID regionUUID) + { + List parameters = new List(); + + parameters.Add(_Database.CreateParameter("UUID", land.GlobalID)); + parameters.Add(_Database.CreateParameter("RegionUUID", regionUUID)); + parameters.Add(_Database.CreateParameter("LocalLandID", land.LocalID)); + + // Bitmap is a byte[512] + parameters.Add(_Database.CreateParameter("Bitmap", land.Bitmap)); + + parameters.Add(_Database.CreateParameter("Name", land.Name)); + parameters.Add(_Database.CreateParameter("Description", land.Description)); + parameters.Add(_Database.CreateParameter("OwnerUUID", land.OwnerID)); + parameters.Add(_Database.CreateParameter("IsGroupOwned", land.IsGroupOwned)); + parameters.Add(_Database.CreateParameter("Area", land.Area)); + parameters.Add(_Database.CreateParameter("AuctionID", land.AuctionID)); //Unemplemented + parameters.Add(_Database.CreateParameter("Category", (int)land.Category)); //Enum libsecondlife.Parcel.ParcelCategory + parameters.Add(_Database.CreateParameter("ClaimDate", land.ClaimDate)); + parameters.Add(_Database.CreateParameter("ClaimPrice", land.ClaimPrice)); + parameters.Add(_Database.CreateParameter("GroupUUID", land.GroupID)); + parameters.Add(_Database.CreateParameter("SalePrice", land.SalePrice)); + parameters.Add(_Database.CreateParameter("LandStatus", (int)land.Status)); //Enum. libsecondlife.Parcel.ParcelStatus + parameters.Add(_Database.CreateParameter("LandFlags", land.Flags)); + parameters.Add(_Database.CreateParameter("LandingType", land.LandingType)); + parameters.Add(_Database.CreateParameter("MediaAutoScale", land.MediaAutoScale)); + parameters.Add(_Database.CreateParameter("MediaTextureUUID", land.MediaID)); + parameters.Add(_Database.CreateParameter("MediaURL", land.MediaURL)); + parameters.Add(_Database.CreateParameter("MusicURL", land.MusicURL)); + parameters.Add(_Database.CreateParameter("PassHours", land.PassHours)); + parameters.Add(_Database.CreateParameter("PassPrice", land.PassPrice)); + parameters.Add(_Database.CreateParameter("SnapshotUUID", land.SnapshotID)); + parameters.Add(_Database.CreateParameter("UserLocationX", land.UserLocation.X)); + parameters.Add(_Database.CreateParameter("UserLocationY", land.UserLocation.Y)); + parameters.Add(_Database.CreateParameter("UserLocationZ", land.UserLocation.Z)); + parameters.Add(_Database.CreateParameter("UserLookAtX", land.UserLookAt.X)); + parameters.Add(_Database.CreateParameter("UserLookAtY", land.UserLookAt.Y)); + parameters.Add(_Database.CreateParameter("UserLookAtZ", land.UserLookAt.Z)); + parameters.Add(_Database.CreateParameter("AuthBuyerID", land.AuthBuyerID)); + parameters.Add(_Database.CreateParameter("OtherCleanTime", land.OtherCleanTime)); + parameters.Add(_Database.CreateParameter("Dwell", land.Dwell)); + + return parameters.ToArray(); + } + + /// + /// Creates the land access parameters. + /// + /// parcel access entry. + /// parcel ID. + /// + private SqlParameter[] CreateLandAccessParameters(ParcelManager.ParcelAccessEntry parcelAccessEntry, UUID parcelID) + { + List parameters = new List(); + + parameters.Add(_Database.CreateParameter("LandUUID", parcelID)); + parameters.Add(_Database.CreateParameter("AccessUUID", parcelAccessEntry.AgentID)); + parameters.Add(_Database.CreateParameter("Flags", parcelAccessEntry.Flags)); + + return parameters.ToArray(); + } + + /// + /// Creates the prim parameters for storing in DB. + /// + /// Basic data of SceneObjectpart prim. + /// The scenegroup ID. + /// The region ID. + /// + private SqlParameter[] CreatePrimParameters(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) + { + List parameters = new List(); + + parameters.Add(_Database.CreateParameter("UUID", prim.UUID)); + parameters.Add(_Database.CreateParameter("RegionUUID", regionUUID)); + parameters.Add(_Database.CreateParameter("CreationDate", prim.CreationDate)); + parameters.Add(_Database.CreateParameter("Name", prim.Name)); + parameters.Add(_Database.CreateParameter("SceneGroupID", sceneGroupID)); + // the UUID of the root part for this SceneObjectGroup + // various text fields + parameters.Add(_Database.CreateParameter("Text", prim.Text)); + parameters.Add(_Database.CreateParameter("ColorR", prim.Color.R)); + parameters.Add(_Database.CreateParameter("ColorG", prim.Color.G)); + parameters.Add(_Database.CreateParameter("ColorB", prim.Color.B)); + parameters.Add(_Database.CreateParameter("ColorA", prim.Color.A)); + parameters.Add(_Database.CreateParameter("Description", prim.Description)); + parameters.Add(_Database.CreateParameter("SitName", prim.SitName)); + parameters.Add(_Database.CreateParameter("TouchName", prim.TouchName)); + // permissions + parameters.Add(_Database.CreateParameter("ObjectFlags", prim.ObjectFlags)); + parameters.Add(_Database.CreateParameter("CreatorID", prim.CreatorID)); + parameters.Add(_Database.CreateParameter("OwnerID", prim.OwnerID)); + parameters.Add(_Database.CreateParameter("GroupID", prim.GroupID)); + parameters.Add(_Database.CreateParameter("LastOwnerID", prim.LastOwnerID)); + parameters.Add(_Database.CreateParameter("OwnerMask", prim.OwnerMask)); + parameters.Add(_Database.CreateParameter("NextOwnerMask", prim.NextOwnerMask)); + parameters.Add(_Database.CreateParameter("GroupMask", prim.GroupMask)); + parameters.Add(_Database.CreateParameter("EveryoneMask", prim.EveryoneMask)); + parameters.Add(_Database.CreateParameter("BaseMask", prim.BaseMask)); + // vectors + parameters.Add(_Database.CreateParameter("PositionX", prim.OffsetPosition.X)); + parameters.Add(_Database.CreateParameter("PositionY", prim.OffsetPosition.Y)); + parameters.Add(_Database.CreateParameter("PositionZ", prim.OffsetPosition.Z)); + parameters.Add(_Database.CreateParameter("GroupPositionX", prim.GroupPosition.X)); + parameters.Add(_Database.CreateParameter("GroupPositionY", prim.GroupPosition.Y)); + parameters.Add(_Database.CreateParameter("GroupPositionZ", prim.GroupPosition.Z)); + parameters.Add(_Database.CreateParameter("VelocityX", prim.Velocity.X)); + parameters.Add(_Database.CreateParameter("VelocityY", prim.Velocity.Y)); + parameters.Add(_Database.CreateParameter("VelocityZ", prim.Velocity.Z)); + parameters.Add(_Database.CreateParameter("AngularVelocityX", prim.AngularVelocity.X)); + parameters.Add(_Database.CreateParameter("AngularVelocityY", prim.AngularVelocity.Y)); + parameters.Add(_Database.CreateParameter("AngularVelocityZ", prim.AngularVelocity.Z)); + parameters.Add(_Database.CreateParameter("AccelerationX", prim.Acceleration.X)); + parameters.Add(_Database.CreateParameter("AccelerationY", prim.Acceleration.Y)); + parameters.Add(_Database.CreateParameter("AccelerationZ", prim.Acceleration.Z)); + // quaternions + parameters.Add(_Database.CreateParameter("RotationX", prim.RotationOffset.X)); + parameters.Add(_Database.CreateParameter("RotationY", prim.RotationOffset.Y)); + parameters.Add(_Database.CreateParameter("RotationZ", prim.RotationOffset.Z)); + parameters.Add(_Database.CreateParameter("RotationW", prim.RotationOffset.W)); + + // Sit target + Vector3 sitTargetPos = prim.SitTargetPositionLL; + parameters.Add(_Database.CreateParameter("SitTargetOffsetX", sitTargetPos.X)); + parameters.Add(_Database.CreateParameter("SitTargetOffsetY", sitTargetPos.Y)); + parameters.Add(_Database.CreateParameter("SitTargetOffsetZ", sitTargetPos.Z)); + + Quaternion sitTargetOrient = prim.SitTargetOrientationLL; + parameters.Add(_Database.CreateParameter("SitTargetOrientW", sitTargetOrient.W)); + parameters.Add(_Database.CreateParameter("SitTargetOrientX", sitTargetOrient.X)); + parameters.Add(_Database.CreateParameter("SitTargetOrientY", sitTargetOrient.Y)); + parameters.Add(_Database.CreateParameter("SitTargetOrientZ", sitTargetOrient.Z)); + + parameters.Add(_Database.CreateParameter("PayPrice", prim.PayPrice[0])); + parameters.Add(_Database.CreateParameter("PayButton1", prim.PayPrice[1])); + parameters.Add(_Database.CreateParameter("PayButton2", prim.PayPrice[2])); + parameters.Add(_Database.CreateParameter("PayButton3", prim.PayPrice[3])); + parameters.Add(_Database.CreateParameter("PayButton4", prim.PayPrice[4])); + + if ((prim.SoundFlags & 1) != 0) // Looped + { + parameters.Add(_Database.CreateParameter("LoopedSound", prim.Sound)); + parameters.Add(_Database.CreateParameter("LoopedSoundGain", prim.SoundGain)); + } + else + { + parameters.Add(_Database.CreateParameter("LoopedSound", UUID.Zero)); + parameters.Add(_Database.CreateParameter("LoopedSoundGain", 0.0f)); + } + + parameters.Add(_Database.CreateParameter("TextureAnimation", prim.TextureAnimation)); + parameters.Add(_Database.CreateParameter("ParticleSystem", prim.ParticleSystem)); + + parameters.Add(_Database.CreateParameter("OmegaX", prim.RotationalVelocity.X)); + parameters.Add(_Database.CreateParameter("OmegaY", prim.RotationalVelocity.Y)); + parameters.Add(_Database.CreateParameter("OmegaZ", prim.RotationalVelocity.Z)); + + parameters.Add(_Database.CreateParameter("CameraEyeOffsetX", prim.GetCameraEyeOffset().X)); + parameters.Add(_Database.CreateParameter("CameraEyeOffsetY", prim.GetCameraEyeOffset().Y)); + parameters.Add(_Database.CreateParameter("CameraEyeOffsetZ", prim.GetCameraEyeOffset().Z)); + + parameters.Add(_Database.CreateParameter("CameraAtOffsetX", prim.GetCameraAtOffset().X)); + parameters.Add(_Database.CreateParameter("CameraAtOffsetY", prim.GetCameraAtOffset().Y)); + parameters.Add(_Database.CreateParameter("CameraAtOffsetZ", prim.GetCameraAtOffset().Z)); + + if (prim.GetForceMouselook()) + parameters.Add(_Database.CreateParameter("ForceMouselook", 1)); + else + parameters.Add(_Database.CreateParameter("ForceMouselook", 0)); + + parameters.Add(_Database.CreateParameter("ScriptAccessPin", prim.ScriptAccessPin)); + + if (prim.AllowedDrop) + parameters.Add(_Database.CreateParameter("AllowedDrop", 1)); + else + parameters.Add(_Database.CreateParameter("AllowedDrop", 0)); + + if (prim.DIE_AT_EDGE) + parameters.Add(_Database.CreateParameter("DieAtEdge", 1)); + else + parameters.Add(_Database.CreateParameter("DieAtEdge", 0)); + + parameters.Add(_Database.CreateParameter("SalePrice", prim.SalePrice)); + parameters.Add(_Database.CreateParameter("SaleType", prim.ObjectSaleType)); + + byte clickAction = prim.ClickAction; + parameters.Add(_Database.CreateParameter("ClickAction", clickAction)); + + parameters.Add(_Database.CreateParameter("Material", prim.Material)); + + parameters.Add(_Database.CreateParameter("CollisionSound", prim.CollisionSound)); + parameters.Add(_Database.CreateParameter("CollisionSoundVolume", prim.CollisionSoundVolume)); + if (prim.PassTouches) + parameters.Add(_Database.CreateParameter("PassTouches", 1)); + else + parameters.Add(_Database.CreateParameter("PassTouches", 0)); + parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum)); + + return parameters.ToArray(); + } + + /// + /// Creates the primshape parameters for stroing in DB. + /// + /// Basic data of SceneObjectpart prim. + /// The scene group ID. + /// The region UUID. + /// + private SqlParameter[] CreatePrimShapeParameters(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) + { + List parameters = new List(); + + PrimitiveBaseShape s = prim.Shape; + parameters.Add(_Database.CreateParameter("UUID", prim.UUID)); + // shape is an enum + parameters.Add(_Database.CreateParameter("Shape", 0)); + // vectors + parameters.Add(_Database.CreateParameter("ScaleX", s.Scale.X)); + parameters.Add(_Database.CreateParameter("ScaleY", s.Scale.Y)); + parameters.Add(_Database.CreateParameter("ScaleZ", s.Scale.Z)); + // paths + parameters.Add(_Database.CreateParameter("PCode", s.PCode)); + parameters.Add(_Database.CreateParameter("PathBegin", s.PathBegin)); + parameters.Add(_Database.CreateParameter("PathEnd", s.PathEnd)); + parameters.Add(_Database.CreateParameter("PathScaleX", s.PathScaleX)); + parameters.Add(_Database.CreateParameter("PathScaleY", s.PathScaleY)); + parameters.Add(_Database.CreateParameter("PathShearX", s.PathShearX)); + parameters.Add(_Database.CreateParameter("PathShearY", s.PathShearY)); + parameters.Add(_Database.CreateParameter("PathSkew", s.PathSkew)); + parameters.Add(_Database.CreateParameter("PathCurve", s.PathCurve)); + parameters.Add(_Database.CreateParameter("PathRadiusOffset", s.PathRadiusOffset)); + parameters.Add(_Database.CreateParameter("PathRevolutions", s.PathRevolutions)); + parameters.Add(_Database.CreateParameter("PathTaperX", s.PathTaperX)); + parameters.Add(_Database.CreateParameter("PathTaperY", s.PathTaperY)); + parameters.Add(_Database.CreateParameter("PathTwist", s.PathTwist)); + parameters.Add(_Database.CreateParameter("PathTwistBegin", s.PathTwistBegin)); + // profile + parameters.Add(_Database.CreateParameter("ProfileBegin", s.ProfileBegin)); + parameters.Add(_Database.CreateParameter("ProfileEnd", s.ProfileEnd)); + parameters.Add(_Database.CreateParameter("ProfileCurve", s.ProfileCurve)); + parameters.Add(_Database.CreateParameter("ProfileHollow", s.ProfileHollow)); + parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry)); + parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams)); + parameters.Add(_Database.CreateParameter("State", s.State)); + + return parameters.ToArray(); + } + + #endregion + + #endregion + } +} diff --git a/OpenSim/Data/MSSQL/MSSQLRegionData.cs b/OpenSim/Data/MSSQL/MSSQLRegionData.cs index 6318c09d53..78d7fd0ced 100644 --- a/OpenSim/Data/MSSQL/MSSQLRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLRegionData.cs @@ -13,7 +13,7 @@ * 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 + * 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 @@ -43,1489 +43,269 @@ namespace OpenSim.Data.MSSQL /// /// A MSSQL Interface for the Region Server. /// - public class MSSQLRegionDataStore : IRegionDataStore + public class MSSQLRegionData : IRegionData { - private const string _migrationStore = "RegionStore"; + private string m_Realm; + private List m_ColumnNames = null; + private string m_ConnectionString; + private MSSQLManager m_database; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - // private static FileSystemDataStore Instance = new FileSystemDataStore(); - private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - /// - /// The database manager - /// - private MSSQLManager _Database; - - /// - /// Initialises the region datastore - /// - /// The connection string. - public void Initialise(string connectionString) + public MSSQLRegionData(string connectionString, string realm) { - if (!string.IsNullOrEmpty(connectionString)) + m_Realm = realm; + m_ConnectionString = connectionString; + m_database = new MSSQLManager(connectionString); + + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) { - _Database = new MSSQLManager(connectionString); - } - else - { - IniFile iniFile = new IniFile("mssql_connection.ini"); - string settingDataSource = iniFile.ParseFileReadValue("data_source"); - string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog"); - string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info"); - string settingUserId = iniFile.ParseFileReadValue("user_id"); - string settingPassword = iniFile.ParseFileReadValue("password"); + conn.Open(); + Migration m = new Migration(conn, GetType().Assembly, "GridStore"); + m.Update(); + } + } - _Database = new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, settingPassword); - } - - //Migration settings - _Database.CheckMigration(_migrationStore); - } - - /// - /// Dispose the database - /// - public void Dispose() { } - - #region SceneObjectGroup region for loading and Store of the scene. - - /// - /// Loads the objects present in the region. - /// - /// The region UUID. - /// - public List LoadObjects(UUID regionUUID) + public List Get(string regionName, UUID scopeID) { - UUID lastGroupID = UUID.Zero; - - Dictionary prims = new Dictionary(); - Dictionary objects = new Dictionary(); - SceneObjectGroup grp = null; - - - string query = "SELECT *, " + - "sort = CASE WHEN prims.UUID = prims.SceneGroupID THEN 0 ELSE 1 END " + - "FROM prims " + - "LEFT JOIN primshapes ON prims.UUID = primshapes.UUID " + - "WHERE RegionUUID = @RegionUUID " + - "ORDER BY SceneGroupID asc, sort asc, LinkNumber asc"; - - using (AutoClosingSqlCommand command = _Database.Query(query)) + string sql = "select * from ["+m_Realm+"] where regionName like @regionName"; + if (scopeID != UUID.Zero) + sql += " and ScopeID = @scopeID"; + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) { - command.Parameters.Add(_Database.CreateParameter("@regionUUID", regionUUID)); - - using (SqlDataReader reader = command.ExecuteReader()) - { - while (reader.Read()) - { - SceneObjectPart sceneObjectPart = BuildPrim(reader); - if (reader["Shape"] is DBNull) - sceneObjectPart.Shape = PrimitiveBaseShape.Default; - else - sceneObjectPart.Shape = BuildShape(reader); - - prims[sceneObjectPart.UUID] = sceneObjectPart; - - UUID groupID = new UUID((Guid)reader["SceneGroupID"]); - - if (groupID != lastGroupID) // New SOG - { - if (grp != null) - objects[grp.UUID] = grp; - - lastGroupID = groupID; - - // There sometimes exist OpenSim bugs that 'orphan groups' so that none of the prims are - // recorded as the root prim (for which the UUID must equal the persisted group UUID). In - // this case, force the UUID to be the same as the group UUID so that at least these can be - // deleted (we need to change the UUID so that any other prims in the linkset can also be - // deleted). - if (sceneObjectPart.UUID != groupID && groupID != UUID.Zero) - { - _Log.WarnFormat( - "[REGION DB]: Found root prim {0} {1} at {2} where group was actually {3}. Forcing UUID to group UUID", - sceneObjectPart.Name, sceneObjectPart.UUID, sceneObjectPart.GroupPosition, groupID); - - sceneObjectPart.UUID = groupID; - } - - grp = new SceneObjectGroup(sceneObjectPart); - } - else - { - // Black magic to preserve link numbers - // Why is this needed, fix this in AddPart method. - int link = sceneObjectPart.LinkNum; - - grp.AddPart(sceneObjectPart); - - if (link != 0) - sceneObjectPart.LinkNum = link; - } - } - } - } - - if (grp != null) - objects[grp.UUID] = grp; - - // Instead of attempting to LoadItems on every prim, - // most of which probably have no items... get a - // list from DB of all prims which have items and - // LoadItems only on those - List primsWithInventory = new List(); - string qry = "select distinct primID from primitems"; - using (AutoClosingSqlCommand command = _Database.Query(qry)) - { - using (SqlDataReader itemReader = command.ExecuteReader()) - { - while (itemReader.Read()) - { - if (!(itemReader["primID"] is DBNull)) - { - UUID primID = new UUID(itemReader["primID"].ToString()); - if (prims.ContainsKey(primID)) - { - primsWithInventory.Add(prims[primID]); - } - } - } - } - } - - LoadItems(primsWithInventory); - - _Log.DebugFormat("[REGION DB]: Loaded {0} objects using {1} prims", objects.Count, prims.Count); - - return new List(objects.Values); - } - - /// - /// Load in the prim's persisted inventory. - /// - /// all prims with inventory on a region - private void LoadItems(List allPrimsWithInventory) - { - - using (AutoClosingSqlCommand command = _Database.Query("SELECT * FROM primitems WHERE PrimID = @PrimID")) - { - foreach (SceneObjectPart objectPart in allPrimsWithInventory) - { - command.Parameters.Clear(); - command.Parameters.Add(_Database.CreateParameter("@PrimID", objectPart.UUID)); - - List inventory = new List(); - - using (SqlDataReader reader = command.ExecuteReader()) - { - while (reader.Read()) - { - TaskInventoryItem item = BuildItem(reader); - - item.ParentID = objectPart.UUID; // Values in database are - // often wrong - inventory.Add(item); - } - } - - objectPart.Inventory.RestoreInventoryItems(inventory); - } + cmd.Parameters.Add(m_database.CreateParameter("@regionName", regionName)); + cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID)); + conn.Open(); + return RunCommand(cmd); } } - /// - /// Stores all object's details apart from inventory - /// - /// - /// - public void StoreObject(SceneObjectGroup obj, UUID regionUUID) + public RegionData Get(int posX, int posY, UUID scopeID) { - _Log.InfoFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count); + string sql = "select * from ["+m_Realm+"] where locX = @posX and locY = @posY"; + if (scopeID != UUID.Zero) + sql += " and ScopeID = @scopeID"; - using (SqlConnection conn = _Database.DatabaseConnection()) + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) { - SqlTransaction transaction = conn.BeginTransaction(); + cmd.Parameters.Add(m_database.CreateParameter("@posX", posX.ToString())); + cmd.Parameters.Add(m_database.CreateParameter("@posY", posY.ToString())); + cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID)); + conn.Open(); + List ret = RunCommand(cmd); + if (ret.Count == 0) + return null; + return ret[0]; + } + } + + public RegionData Get(UUID regionID, UUID scopeID) + { + string sql = "select * from ["+m_Realm+"] where uuid = @regionID"; + if (scopeID != UUID.Zero) + sql += " and ScopeID = @scopeID"; + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + cmd.Parameters.Add(m_database.CreateParameter("@regionID", regionID)); + cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID)); + conn.Open(); + List ret = RunCommand(cmd); + if (ret.Count == 0) + return null; + + return ret[0]; + } + } + + public List Get(int startX, int startY, int endX, int endY, UUID scopeID) + { + string sql = "select * from ["+m_Realm+"] where locX between @startX and @endX and locY between @startY and @endY"; + if (scopeID != UUID.Zero) + sql += " and ScopeID = @scopeID"; + + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + cmd.Parameters.Add(m_database.CreateParameter("@startX", startX.ToString())); + cmd.Parameters.Add(m_database.CreateParameter("@startY", startY.ToString())); + cmd.Parameters.Add(m_database.CreateParameter("@endX", endX.ToString())); + cmd.Parameters.Add(m_database.CreateParameter("@endY", endY.ToString())); + cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID)); + conn.Open(); + return RunCommand(cmd); + } + } + + public List RunCommand(SqlCommand cmd) + { + List retList = new List(); + + SqlDataReader result = cmd.ExecuteReader(); + + while (result.Read()) + { + RegionData ret = new RegionData(); + ret.Data = new Dictionary(); + + UUID regionID; + UUID.TryParse(result["uuid"].ToString(), out regionID); + ret.RegionID = regionID; + UUID scope; + UUID.TryParse(result["ScopeID"].ToString(), out scope); + ret.ScopeID = scope; + ret.RegionName = result["regionName"].ToString(); + ret.posX = Convert.ToInt32(result["locX"]); + ret.posY = Convert.ToInt32(result["locY"]); + ret.sizeX = Convert.ToInt32(result["sizeX"]); + ret.sizeY = Convert.ToInt32(result["sizeY"]); + + if (m_ColumnNames == null) + { + m_ColumnNames = new List(); + + DataTable schemaTable = result.GetSchemaTable(); + foreach (DataRow row in schemaTable.Rows) + m_ColumnNames.Add(row["ColumnName"].ToString()); + } + + foreach (string s in m_ColumnNames) + { + if (s == "uuid") + continue; + if (s == "ScopeID") + continue; + if (s == "regionName") + continue; + if (s == "locX") + continue; + if (s == "locY") + continue; + + ret.Data[s] = result[s].ToString(); + } + + retList.Add(ret); + } + return retList; + } + + public bool Store(RegionData data) + { + if (data.Data.ContainsKey("uuid")) + data.Data.Remove("uuid"); + if (data.Data.ContainsKey("ScopeID")) + data.Data.Remove("ScopeID"); + if (data.Data.ContainsKey("regionName")) + data.Data.Remove("regionName"); + if (data.Data.ContainsKey("posX")) + data.Data.Remove("posX"); + if (data.Data.ContainsKey("posY")) + data.Data.Remove("posY"); + if (data.Data.ContainsKey("sizeX")) + data.Data.Remove("sizeX"); + if (data.Data.ContainsKey("sizeY")) + data.Data.Remove("sizeY"); + if (data.Data.ContainsKey("locX")) + data.Data.Remove("locX"); + if (data.Data.ContainsKey("locY")) + data.Data.Remove("locY"); + + string[] fields = new List(data.Data.Keys).ToArray(); + + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + using (SqlCommand cmd = new SqlCommand()) + { + + string update = "update [" + m_Realm + "] set locX=@posX, locY=@posY, sizeX=@sizeX, sizeY=@sizeY "; + + foreach (string field in fields) + { + + update += ", "; + update += "[" + field + "] = @" + field; + + cmd.Parameters.Add(m_database.CreateParameter("@" + field, data.Data[field])); + } + + update += " where uuid = @regionID"; + + if (data.ScopeID != UUID.Zero) + update += " and ScopeID = @scopeID"; + + cmd.CommandText = update; + cmd.Connection = conn; + cmd.Parameters.Add(m_database.CreateParameter("@regionID", data.RegionID)); + cmd.Parameters.Add(m_database.CreateParameter("@regionName", data.RegionName)); + cmd.Parameters.Add(m_database.CreateParameter("@scopeID", data.ScopeID)); + cmd.Parameters.Add(m_database.CreateParameter("@posX", data.posX)); + cmd.Parameters.Add(m_database.CreateParameter("@posY", data.posY)); + cmd.Parameters.Add(m_database.CreateParameter("@sizeX", data.sizeX)); + cmd.Parameters.Add(m_database.CreateParameter("@sizeY", data.sizeY)); + conn.Open(); try { - foreach (SceneObjectPart sceneObjectPart in obj.Children.Values) + if (cmd.ExecuteNonQuery() < 1) { - //Update prim - using (SqlCommand sqlCommand = conn.CreateCommand()) + string insert = "insert into [" + m_Realm + "] ([uuid], [ScopeID], [locX], [locY], [sizeX], [sizeY], [regionName], [" + + String.Join("], [", fields) + + "]) values ( @regionID, @scopeID, @posX, @posY, @sizeX, @sizeY, @regionName, @" + String.Join(", @", fields) + ")"; + + cmd.CommandText = insert; + + try { - sqlCommand.Transaction = transaction; - try + if (cmd.ExecuteNonQuery() < 1) { - StoreSceneObjectPrim(sceneObjectPart, sqlCommand, obj.UUID, regionUUID); - } - catch (SqlException sqlEx) - { - _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrim SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber); - throw; + return false; } } - - //Update primshapes - using (SqlCommand sqlCommand = conn.CreateCommand()) + catch (Exception ex) { - sqlCommand.Transaction = transaction; - try - { - StoreSceneObjectPrimShapes(sceneObjectPart, sqlCommand, obj.UUID, regionUUID); - } - catch (SqlException sqlEx) - { - _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrimShapes SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber); - throw; - } + m_log.Warn("[MSSQL Grid]: Error inserting into Regions table: " + ex.Message + ", INSERT sql: " + insert); } } - - transaction.Commit(); } catch (Exception ex) { - _Log.ErrorFormat("[REGION DB]: Store SceneObjectGroup error: {0}, Rolling back...", ex.Message); - try - { - transaction.Rollback(); - } - catch (Exception ex2) - { - //Show error - _Log.InfoFormat("[REGION DB]: Rollback of SceneObjectGroup store transaction failed with error: {0}", ex2.Message); - - } + m_log.Warn("[MSSQL Grid]: Error updating Regions table: " + ex.Message + ", UPDATE sql: " + update); } } + return true; } - /// - /// Stores the prim of the sceneobjectpart. - /// - /// The sceneobjectpart or prim. - /// The SQL command with the transaction. - /// The scenegroup UUID. - /// The region UUID. - private void StoreSceneObjectPrim(SceneObjectPart sceneObjectPart, SqlCommand sqlCommand, UUID sceneGroupID, UUID regionUUID) + public bool SetDataItem(UUID regionID, string item, string value) { - //Big query to update or insert a new prim. - //Note for SQL Server 2008 this could be simplified - string queryPrims = @" -IF EXISTS (SELECT UUID FROM prims WHERE UUID = @UUID) - BEGIN - UPDATE prims SET - CreationDate = @CreationDate, Name = @Name, Text = @Text, Description = @Description, SitName = @SitName, - TouchName = @TouchName, ObjectFlags = @ObjectFlags, OwnerMask = @OwnerMask, NextOwnerMask = @NextOwnerMask, GroupMask = @GroupMask, - EveryoneMask = @EveryoneMask, BaseMask = @BaseMask, PositionX = @PositionX, PositionY = @PositionY, PositionZ = @PositionZ, - GroupPositionX = @GroupPositionX, GroupPositionY = @GroupPositionY, GroupPositionZ = @GroupPositionZ, VelocityX = @VelocityX, - VelocityY = @VelocityY, VelocityZ = @VelocityZ, AngularVelocityX = @AngularVelocityX, AngularVelocityY = @AngularVelocityY, - AngularVelocityZ = @AngularVelocityZ, AccelerationX = @AccelerationX, AccelerationY = @AccelerationY, - AccelerationZ = @AccelerationZ, RotationX = @RotationX, RotationY = @RotationY, RotationZ = @RotationZ, RotationW = @RotationW, - SitTargetOffsetX = @SitTargetOffsetX, SitTargetOffsetY = @SitTargetOffsetY, SitTargetOffsetZ = @SitTargetOffsetZ, - SitTargetOrientW = @SitTargetOrientW, SitTargetOrientX = @SitTargetOrientX, SitTargetOrientY = @SitTargetOrientY, - SitTargetOrientZ = @SitTargetOrientZ, RegionUUID = @RegionUUID, CreatorID = @CreatorID, OwnerID = @OwnerID, GroupID = @GroupID, - LastOwnerID = @LastOwnerID, SceneGroupID = @SceneGroupID, PayPrice = @PayPrice, PayButton1 = @PayButton1, PayButton2 = @PayButton2, - PayButton3 = @PayButton3, PayButton4 = @PayButton4, LoopedSound = @LoopedSound, LoopedSoundGain = @LoopedSoundGain, - TextureAnimation = @TextureAnimation, OmegaX = @OmegaX, OmegaY = @OmegaY, OmegaZ = @OmegaZ, CameraEyeOffsetX = @CameraEyeOffsetX, - CameraEyeOffsetY = @CameraEyeOffsetY, CameraEyeOffsetZ = @CameraEyeOffsetZ, CameraAtOffsetX = @CameraAtOffsetX, - CameraAtOffsetY = @CameraAtOffsetY, CameraAtOffsetZ = @CameraAtOffsetZ, ForceMouselook = @ForceMouselook, - ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice, - SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem, - ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches, - LinkNumber = @LinkNumber - WHERE UUID = @UUID - END -ELSE - BEGIN - INSERT INTO - prims ( - UUID, CreationDate, Name, Text, Description, SitName, TouchName, ObjectFlags, OwnerMask, NextOwnerMask, GroupMask, - EveryoneMask, BaseMask, PositionX, PositionY, PositionZ, GroupPositionX, GroupPositionY, GroupPositionZ, VelocityX, - VelocityY, VelocityZ, AngularVelocityX, AngularVelocityY, AngularVelocityZ, AccelerationX, AccelerationY, AccelerationZ, - RotationX, RotationY, RotationZ, RotationW, SitTargetOffsetX, SitTargetOffsetY, SitTargetOffsetZ, SitTargetOrientW, - SitTargetOrientX, SitTargetOrientY, SitTargetOrientZ, RegionUUID, CreatorID, OwnerID, GroupID, LastOwnerID, SceneGroupID, - PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX, - OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ, - ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA, - ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber - ) VALUES ( - @UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask, - @EveryoneMask, @BaseMask, @PositionX, @PositionY, @PositionZ, @GroupPositionX, @GroupPositionY, @GroupPositionZ, @VelocityX, - @VelocityY, @VelocityZ, @AngularVelocityX, @AngularVelocityY, @AngularVelocityZ, @AccelerationX, @AccelerationY, @AccelerationZ, - @RotationX, @RotationY, @RotationZ, @RotationW, @SitTargetOffsetX, @SitTargetOffsetY, @SitTargetOffsetZ, @SitTargetOrientW, - @SitTargetOrientX, @SitTargetOrientY, @SitTargetOrientZ, @RegionUUID, @CreatorID, @OwnerID, @GroupID, @LastOwnerID, @SceneGroupID, - @PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX, - @OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ, - @ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA, - @ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber - ) - END"; - - //Set commandtext. - sqlCommand.CommandText = queryPrims; - //Add parameters - sqlCommand.Parameters.AddRange(CreatePrimParameters(sceneObjectPart, sceneGroupID, regionUUID)); - - //Execute the query. If it fails then error is trapped in calling function - sqlCommand.ExecuteNonQuery(); - } - - /// - /// Stores the scene object prim shapes. - /// - /// The sceneobjectpart containing prim shape. - /// The SQL command with the transaction. - /// The scenegroup UUID. - /// The region UUID. - private void StoreSceneObjectPrimShapes(SceneObjectPart sceneObjectPart, SqlCommand sqlCommand, UUID sceneGroupID, UUID regionUUID) - { - //Big query to or insert or update primshapes - //Note for SQL Server 2008 this can be simplified - string queryPrimShapes = @" -IF EXISTS (SELECT UUID FROM primshapes WHERE UUID = @UUID) - BEGIN - UPDATE primshapes SET - Shape = @Shape, ScaleX = @ScaleX, ScaleY = @ScaleY, ScaleZ = @ScaleZ, PCode = @PCode, PathBegin = @PathBegin, - PathEnd = @PathEnd, PathScaleX = @PathScaleX, PathScaleY = @PathScaleY, PathShearX = @PathShearX, PathShearY = @PathShearY, - PathSkew = @PathSkew, PathCurve = @PathCurve, PathRadiusOffset = @PathRadiusOffset, PathRevolutions = @PathRevolutions, - PathTaperX = @PathTaperX, PathTaperY = @PathTaperY, PathTwist = @PathTwist, PathTwistBegin = @PathTwistBegin, - ProfileBegin = @ProfileBegin, ProfileEnd = @ProfileEnd, ProfileCurve = @ProfileCurve, ProfileHollow = @ProfileHollow, - Texture = @Texture, ExtraParams = @ExtraParams, State = @State - WHERE UUID = @UUID - END -ELSE - BEGIN - INSERT INTO - primshapes ( - UUID, Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY, - PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin, - ProfileEnd, ProfileCurve, ProfileHollow, Texture, ExtraParams, State - ) VALUES ( - @UUID, @Shape, @ScaleX, @ScaleY, @ScaleZ, @PCode, @PathBegin, @PathEnd, @PathScaleX, @PathScaleY, @PathShearX, @PathShearY, - @PathSkew, @PathCurve, @PathRadiusOffset, @PathRevolutions, @PathTaperX, @PathTaperY, @PathTwist, @PathTwistBegin, @ProfileBegin, - @ProfileEnd, @ProfileCurve, @ProfileHollow, @Texture, @ExtraParams, @State - ) - END"; - - //Set commandtext. - sqlCommand.CommandText = queryPrimShapes; - - //Add parameters - sqlCommand.Parameters.AddRange(CreatePrimShapeParameters(sceneObjectPart, sceneGroupID, regionUUID)); - - //Execute the query. If it fails then error is trapped in calling function - sqlCommand.ExecuteNonQuery(); - - } - - /// - /// Removes a object from the database. - /// Meaning removing it from tables Prims, PrimShapes and PrimItems - /// - /// id of scenegroup - /// regionUUID (is this used anyway - public void RemoveObject(UUID objectID, UUID regionUUID) - { - _Log.InfoFormat("[MSSQL]: Removing obj: {0} from region: {1}", objectID, regionUUID); - - //Remove from prims and primsitem table - string sqlPrims = "DELETE FROM PRIMS WHERE SceneGroupID = @objectID"; - string sqlPrimItems = "DELETE FROM PRIMITEMS WHERE primID in (SELECT UUID FROM PRIMS WHERE SceneGroupID = @objectID)"; - string sqlPrimShapes = "DELETE FROM PRIMSHAPES WHERE uuid in (SELECT UUID FROM PRIMS WHERE SceneGroupID = @objectID)"; - - lock (_Database) + string sql = "update [" + m_Realm + + "] set [" + item + "] = @" + item + " where uuid = @UUID"; + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) { - //Using the non transaction mode. - using (AutoClosingSqlCommand cmd = _Database.Query(sqlPrimShapes)) - { - cmd.Parameters.Add(_Database.CreateParameter("objectID", objectID)); - cmd.ExecuteNonQuery(); - - cmd.CommandText = sqlPrimItems; - cmd.ExecuteNonQuery(); - - cmd.CommandText = sqlPrims; - cmd.ExecuteNonQuery(); - } + cmd.Parameters.Add(m_database.CreateParameter("@" + item, value)); + cmd.Parameters.Add(m_database.CreateParameter("@UUID", regionID)); + conn.Open(); + if (cmd.ExecuteNonQuery() > 0) + return true; } + return false; } - /// - /// Store the inventory of a prim. Warning deletes everything first and then adds all again. - /// - /// - /// - public void StorePrimInventory(UUID primID, ICollection items) + public bool Delete(UUID regionID) { - //_Log.InfoFormat("[REGION DB: Persisting Prim Inventory with prim ID {0}", primID); - - //Statement from MySQL section! - // For now, we're just going to crudely remove all the previous inventory items - // no matter whether they have changed or not, and replace them with the current set. - - //Delete everything from PrimID - //TODO add index on PrimID in DB, if not already exist - using (AutoClosingSqlCommand cmd = _Database.Query("DELETE PRIMITEMS WHERE primID = @primID")) + string sql = "delete from [" + m_Realm + + "] where uuid = @UUID"; + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) { - cmd.Parameters.Add(_Database.CreateParameter("@primID", primID)); - cmd.ExecuteNonQuery(); - } - - string sql = - @"INSERT INTO primitems ( - itemID,primID,assetID,parentFolderID,invType,assetType,name,description,creationDate,creatorID,ownerID,lastOwnerID,groupID, - nextPermissions,currentPermissions,basePermissions,everyonePermissions,groupPermissions,flags) - VALUES (@itemID,@primID,@assetID,@parentFolderID,@invType,@assetType,@name,@description,@creationDate,@creatorID,@ownerID, - @lastOwnerID,@groupID,@nextPermissions,@currentPermissions,@basePermissions,@everyonePermissions,@groupPermissions,@flags)"; - - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) - { - foreach (TaskInventoryItem taskItem in items) - { - cmd.Parameters.AddRange(CreatePrimInventoryParameters(taskItem)); - cmd.ExecuteNonQuery(); - - cmd.Parameters.Clear(); - } + cmd.Parameters.Add(m_database.CreateParameter("@UUID", regionID)); + conn.Open(); + if (cmd.ExecuteNonQuery() > 0) + return true; } + return false; } - - #endregion - - /// - /// Loads the terrain map. - /// - /// regionID. - /// - public double[,] LoadTerrain(UUID regionID) - { - double[,] terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; - terrain.Initialize(); - - string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc"; - - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) - { - // MySqlParameter param = new MySqlParameter(); - cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); - - using (SqlDataReader reader = cmd.ExecuteReader()) - { - int rev; - if (reader.Read()) - { - MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]); - BinaryReader br = new BinaryReader(str); - for (int x = 0; x < (int)Constants.RegionSize; x++) - { - for (int y = 0; y < (int)Constants.RegionSize; y++) - { - terrain[x, y] = br.ReadDouble(); - } - } - rev = (int)reader["Revision"]; - } - else - { - _Log.Info("[REGION DB]: No terrain found for region"); - return null; - } - _Log.Info("[REGION DB]: Loaded terrain revision r" + rev); - } - } - - return terrain; - } - - /// - /// Stores the terrain map to DB. - /// - /// terrain map data. - /// regionID. - public void StoreTerrain(double[,] terrain, UUID regionID) - { - int revision = Util.UnixTimeSinceEpoch(); - - //Delete old terrain map - string sql = "delete from terrain where RegionUUID=@RegionUUID"; - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) - { - cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); - cmd.ExecuteNonQuery(); - } - - sql = "insert into terrain(RegionUUID, Revision, Heightfield) values(@RegionUUID, @Revision, @Heightfield)"; - - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) - { - cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); - cmd.Parameters.Add(_Database.CreateParameter("@Revision", revision)); - cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", serializeTerrain(terrain))); - cmd.ExecuteNonQuery(); - } - - _Log.Info("[REGION DB]: Stored terrain revision r " + revision); - } - - /// - /// Loads all the land objects of a region. - /// - /// The region UUID. - /// - public List LoadLandObjects(UUID regionUUID) - { - List landDataForRegion = new List(); - - string sql = "select * from land where RegionUUID = @RegionUUID"; - - //Retrieve all land data from region - using (AutoClosingSqlCommand cmdLandData = _Database.Query(sql)) - { - cmdLandData.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionUUID)); - - using (SqlDataReader readerLandData = cmdLandData.ExecuteReader()) - { - while (readerLandData.Read()) - { - landDataForRegion.Add(BuildLandData(readerLandData)); - } - } - } - - //Retrieve all accesslist data for all landdata - foreach (LandData landData in landDataForRegion) - { - sql = "select * from landaccesslist where LandUUID = @LandUUID"; - using (AutoClosingSqlCommand cmdAccessList = _Database.Query(sql)) - { - cmdAccessList.Parameters.Add(_Database.CreateParameter("@LandUUID", landData.GlobalID)); - using (SqlDataReader readerAccessList = cmdAccessList.ExecuteReader()) - { - while (readerAccessList.Read()) - { - landData.ParcelAccessList.Add(BuildLandAccessData(readerAccessList)); - } - } - } - } - - //Return data - return landDataForRegion; - } - - /// - /// Stores land object with landaccess list. - /// - /// parcel data. - public void StoreLandObject(ILandObject parcel) - { - //As this is only one record in land table I just delete all and then add a new record. - //As the delete landaccess is already in the mysql code - - //Delete old values - RemoveLandObject(parcel.LandData.GlobalID); - - //Insert new values - string sql = @"INSERT INTO [land] -([UUID],[RegionUUID],[LocalLandID],[Bitmap],[Name],[Description],[OwnerUUID],[IsGroupOwned],[Area],[AuctionID],[Category],[ClaimDate],[ClaimPrice],[GroupUUID],[SalePrice],[LandStatus],[LandFlags],[LandingType],[MediaAutoScale],[MediaTextureUUID],[MediaURL],[MusicURL],[PassHours],[PassPrice],[SnapshotUUID],[UserLocationX],[UserLocationY],[UserLocationZ],[UserLookAtX],[UserLookAtY],[UserLookAtZ],[AuthbuyerID],[OtherCleanTime],[Dwell]) -VALUES -(@UUID,@RegionUUID,@LocalLandID,@Bitmap,@Name,@Description,@OwnerUUID,@IsGroupOwned,@Area,@AuctionID,@Category,@ClaimDate,@ClaimPrice,@GroupUUID,@SalePrice,@LandStatus,@LandFlags,@LandingType,@MediaAutoScale,@MediaTextureUUID,@MediaURL,@MusicURL,@PassHours,@PassPrice,@SnapshotUUID,@UserLocationX,@UserLocationY,@UserLocationZ,@UserLookAtX,@UserLookAtY,@UserLookAtZ,@AuthbuyerID,@OtherCleanTime,@Dwell)"; - - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) - { - cmd.Parameters.AddRange(CreateLandParameters(parcel.LandData, parcel.RegionUUID)); - - cmd.ExecuteNonQuery(); - } - - sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags]) VALUES (@LandUUID,@AccessUUID,@Flags)"; - - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) - { - foreach (ParcelManager.ParcelAccessEntry parcelAccessEntry in parcel.LandData.ParcelAccessList) - { - cmd.Parameters.AddRange(CreateLandAccessParameters(parcelAccessEntry, parcel.RegionUUID)); - - cmd.ExecuteNonQuery(); - cmd.Parameters.Clear(); - } - } - } - - /// - /// Removes a land object from DB. - /// - /// UUID of landobject - public void RemoveLandObject(UUID globalID) - { - using (AutoClosingSqlCommand cmd = _Database.Query("delete from land where UUID=@UUID")) - { - cmd.Parameters.Add(_Database.CreateParameter("@UUID", globalID)); - cmd.ExecuteNonQuery(); - } - - using (AutoClosingSqlCommand cmd = _Database.Query("delete from landaccesslist where LandUUID=@UUID")) - { - cmd.Parameters.Add(_Database.CreateParameter("@UUID", globalID)); - cmd.ExecuteNonQuery(); - } - } - - /// - /// Loads the settings of a region. - /// - /// The region UUID. - /// - public RegionSettings LoadRegionSettings(UUID regionUUID) - { - string sql = "select * from regionsettings where regionUUID = @regionUUID"; - RegionSettings regionSettings; - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) - { - cmd.Parameters.Add(_Database.CreateParameter("@regionUUID", regionUUID)); - using (SqlDataReader reader = cmd.ExecuteReader()) - { - if (reader.Read()) - { - regionSettings = BuildRegionSettings(reader); - regionSettings.OnSave += StoreRegionSettings; - - return regionSettings; - } - } - } - - //If comes here then there is now region setting for that region - regionSettings = new RegionSettings(); - regionSettings.RegionUUID = regionUUID; - regionSettings.OnSave += StoreRegionSettings; - - //Store new values - StoreNewRegionSettings(regionSettings); - - return regionSettings; - } - - /// - /// Store region settings, need to check if the check is really necesary. If we can make something for creating new region. - /// - /// region settings. - public void StoreRegionSettings(RegionSettings regionSettings) - { - //Little check if regionUUID already exist in DB - string regionUUID; - using (AutoClosingSqlCommand cmd = _Database.Query("SELECT regionUUID FROM regionsettings WHERE regionUUID = @regionUUID")) - { - cmd.Parameters.Add(_Database.CreateParameter("@regionUUID", regionSettings.RegionUUID)); - regionUUID = cmd.ExecuteScalar().ToString(); - } - - if (string.IsNullOrEmpty(regionUUID)) - { - StoreNewRegionSettings(regionSettings); - } - else - { - //This method only updates region settings!!! First call LoadRegionSettings to create new region settings in DB - string sql = - @"UPDATE [regionsettings] SET [block_terraform] = @block_terraform ,[block_fly] = @block_fly ,[allow_damage] = @allow_damage -,[restrict_pushing] = @restrict_pushing ,[allow_land_resell] = @allow_land_resell ,[allow_land_join_divide] = @allow_land_join_divide -,[block_show_in_search] = @block_show_in_search ,[agent_limit] = @agent_limit ,[object_bonus] = @object_bonus ,[maturity] = @maturity -,[disable_scripts] = @disable_scripts ,[disable_collisions] = @disable_collisions ,[disable_physics] = @disable_physics -,[terrain_texture_1] = @terrain_texture_1 ,[terrain_texture_2] = @terrain_texture_2 ,[terrain_texture_3] = @terrain_texture_3 -,[terrain_texture_4] = @terrain_texture_4 ,[elevation_1_nw] = @elevation_1_nw ,[elevation_2_nw] = @elevation_2_nw -,[elevation_1_ne] = @elevation_1_ne ,[elevation_2_ne] = @elevation_2_ne ,[elevation_1_se] = @elevation_1_se ,[elevation_2_se] = @elevation_2_se -,[elevation_1_sw] = @elevation_1_sw ,[elevation_2_sw] = @elevation_2_sw ,[water_height] = @water_height ,[terrain_raise_limit] = @terrain_raise_limit -,[terrain_lower_limit] = @terrain_lower_limit ,[use_estate_sun] = @use_estate_sun ,[fixed_sun] = @fixed_sun ,[sun_position] = @sun_position -,[covenant] = @covenant , [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz, [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id - WHERE [regionUUID] = @regionUUID"; - - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) - { - cmd.Parameters.AddRange(CreateRegionSettingParameters(regionSettings)); - - cmd.ExecuteNonQuery(); - } - } - } - - public void Shutdown() - { - //Not used?? - } - - #region Private Methods - - /// - /// Serializes the terrain data for storage in DB. - /// - /// terrain data - /// - private static Array serializeTerrain(double[,] val) - { - MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) * sizeof(double)); - BinaryWriter bw = new BinaryWriter(str); - - // TODO: COMPATIBILITY - Add byte-order conversions - for (int x = 0; x < (int)Constants.RegionSize; x++) - for (int y = 0; y < (int)Constants.RegionSize; y++) - { - double height = val[x, y]; - if (height == 0.0) - height = double.Epsilon; - - bw.Write(height); - } - - return str.ToArray(); - } - - /// - /// Stores new regionsettings. - /// - /// The region settings. - private void StoreNewRegionSettings(RegionSettings regionSettings) - { - string sql = @"INSERT INTO [regionsettings] - ([regionUUID],[block_terraform],[block_fly],[allow_damage],[restrict_pushing],[allow_land_resell],[allow_land_join_divide], - [block_show_in_search],[agent_limit],[object_bonus],[maturity],[disable_scripts],[disable_collisions],[disable_physics], - [terrain_texture_1],[terrain_texture_2],[terrain_texture_3],[terrain_texture_4],[elevation_1_nw],[elevation_2_nw],[elevation_1_ne], - [elevation_2_ne],[elevation_1_se],[elevation_2_se],[elevation_1_sw],[elevation_2_sw],[water_height],[terrain_raise_limit], - [terrain_lower_limit],[use_estate_sun],[fixed_sun],[sun_position],[covenant],[sunvectorx], [sunvectory], [sunvectorz],[Sandbox], [loaded_creation_datetime], [loaded_creation_id] - ) - VALUES - (@regionUUID,@block_terraform,@block_fly,@allow_damage,@restrict_pushing,@allow_land_resell,@allow_land_join_divide, - @block_show_in_search,@agent_limit,@object_bonus,@maturity,@disable_scripts,@disable_collisions,@disable_physics, - @terrain_texture_1,@terrain_texture_2,@terrain_texture_3,@terrain_texture_4,@elevation_1_nw,@elevation_2_nw,@elevation_1_ne, - @elevation_2_ne,@elevation_1_se,@elevation_2_se,@elevation_1_sw,@elevation_2_sw,@water_height,@terrain_raise_limit, - @terrain_lower_limit,@use_estate_sun,@fixed_sun,@sun_position,@covenant,@sunvectorx,@sunvectory, @sunvectorz, @Sandbox, @loaded_creation_datetime, @loaded_creation_id)"; - - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) - { - cmd.Parameters.AddRange(CreateRegionSettingParameters(regionSettings)); - cmd.ExecuteNonQuery(); - } - } - - #region Private DataRecord conversion methods - - /// - /// Builds the region settings from a datarecod. - /// - /// datarecord with regionsettings. - /// - private static RegionSettings BuildRegionSettings(IDataRecord row) - { - //TODO change this is some more generic code so we doesnt have to change it every time a new field is added? - RegionSettings newSettings = new RegionSettings(); - - newSettings.RegionUUID = new UUID((Guid)row["regionUUID"]); - newSettings.BlockTerraform = Convert.ToBoolean(row["block_terraform"]); - newSettings.AllowDamage = Convert.ToBoolean(row["allow_damage"]); - newSettings.BlockFly = Convert.ToBoolean(row["block_fly"]); - newSettings.RestrictPushing = Convert.ToBoolean(row["restrict_pushing"]); - newSettings.AllowLandResell = Convert.ToBoolean(row["allow_land_resell"]); - newSettings.AllowLandJoinDivide = Convert.ToBoolean(row["allow_land_join_divide"]); - newSettings.BlockShowInSearch = Convert.ToBoolean(row["block_show_in_search"]); - newSettings.AgentLimit = Convert.ToInt32(row["agent_limit"]); - newSettings.ObjectBonus = Convert.ToDouble(row["object_bonus"]); - newSettings.Maturity = Convert.ToInt32(row["maturity"]); - newSettings.DisableScripts = Convert.ToBoolean(row["disable_scripts"]); - newSettings.DisableCollisions = Convert.ToBoolean(row["disable_collisions"]); - newSettings.DisablePhysics = Convert.ToBoolean(row["disable_physics"]); - newSettings.TerrainTexture1 = new UUID((Guid)row["terrain_texture_1"]); - newSettings.TerrainTexture2 = new UUID((Guid)row["terrain_texture_2"]); - newSettings.TerrainTexture3 = new UUID((Guid)row["terrain_texture_3"]); - newSettings.TerrainTexture4 = new UUID((Guid)row["terrain_texture_4"]); - newSettings.Elevation1NW = Convert.ToDouble(row["elevation_1_nw"]); - newSettings.Elevation2NW = Convert.ToDouble(row["elevation_2_nw"]); - newSettings.Elevation1NE = Convert.ToDouble(row["elevation_1_ne"]); - newSettings.Elevation2NE = Convert.ToDouble(row["elevation_2_ne"]); - newSettings.Elevation1SE = Convert.ToDouble(row["elevation_1_se"]); - newSettings.Elevation2SE = Convert.ToDouble(row["elevation_2_se"]); - newSettings.Elevation1SW = Convert.ToDouble(row["elevation_1_sw"]); - newSettings.Elevation2SW = Convert.ToDouble(row["elevation_2_sw"]); - newSettings.WaterHeight = Convert.ToDouble(row["water_height"]); - newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]); - newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]); - newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]); - newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]); - newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]); - newSettings.SunPosition = Convert.ToDouble(row["sun_position"]); - newSettings.SunVector = new Vector3( - Convert.ToSingle(row["sunvectorx"]), - Convert.ToSingle(row["sunvectory"]), - Convert.ToSingle(row["sunvectorz"]) - ); - newSettings.Covenant = new UUID((Guid)row["covenant"]); - - newSettings.LoadedCreationDateTime = Convert.ToInt32(row["loaded_creation_datetime"]); - - if (row["loaded_creation_id"] is DBNull) - newSettings.LoadedCreationID = ""; - else - newSettings.LoadedCreationID = (String)row["loaded_creation_id"]; - return newSettings; - } - - /// - /// Builds the land data from a datarecord. - /// - /// datarecord with land data - /// - private static LandData BuildLandData(IDataRecord row) - { - LandData newData = new LandData(); - - newData.GlobalID = new UUID((Guid)row["UUID"]); - newData.LocalID = Convert.ToInt32(row["LocalLandID"]); - - // Bitmap is a byte[512] - newData.Bitmap = (Byte[])row["Bitmap"]; - - newData.Name = (string)row["Name"]; - newData.Description = (string)row["Description"]; - newData.OwnerID = new UUID((Guid)row["OwnerUUID"]); - newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); - newData.Area = Convert.ToInt32(row["Area"]); - newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented - newData.Category = (ParcelCategory)Convert.ToInt32(row["Category"]); - //Enum libsecondlife.Parcel.ParcelCategory - newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]); - newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]); - newData.GroupID = new UUID((Guid)row["GroupUUID"]); - newData.SalePrice = Convert.ToInt32(row["SalePrice"]); - newData.Status = (ParcelStatus)Convert.ToInt32(row["LandStatus"]); - //Enum. libsecondlife.Parcel.ParcelStatus - newData.Flags = Convert.ToUInt32(row["LandFlags"]); - newData.LandingType = Convert.ToByte(row["LandingType"]); - newData.MediaAutoScale = Convert.ToByte(row["MediaAutoScale"]); - newData.MediaID = new UUID((Guid)row["MediaTextureUUID"]); - newData.MediaURL = (string)row["MediaURL"]; - newData.MusicURL = (string)row["MusicURL"]; - newData.PassHours = Convert.ToSingle(row["PassHours"]); - newData.PassPrice = Convert.ToInt32(row["PassPrice"]); - -// UUID authedbuyer; -// UUID snapshotID; -// -// if (UUID.TryParse((string)row["AuthBuyerID"], out authedbuyer)) -// newData.AuthBuyerID = authedbuyer; -// -// if (UUID.TryParse((string)row["SnapshotUUID"], out snapshotID)) -// newData.SnapshotID = snapshotID; - newData.AuthBuyerID = new UUID((Guid) row["AuthBuyerID"]); - newData.SnapshotID = new UUID((Guid)row["SnapshotUUID"]); - - newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]); - newData.Dwell = Convert.ToInt32(row["Dwell"]); - - try - { - newData.UserLocation = - new Vector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]), - Convert.ToSingle(row["UserLocationZ"])); - newData.UserLookAt = - new Vector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]), - Convert.ToSingle(row["UserLookAtZ"])); - } - catch (InvalidCastException) - { - newData.UserLocation = Vector3.Zero; - newData.UserLookAt = Vector3.Zero; - _Log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name); - } - - newData.ParcelAccessList = new List(); - - return newData; - } - - /// - /// Builds the landaccess data from a data record. - /// - /// datarecord with landaccess data - /// - private static ParcelManager.ParcelAccessEntry BuildLandAccessData(IDataRecord row) - { - ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); - entry.AgentID = new UUID((Guid)row["AccessUUID"]); - entry.Flags = (AccessList)Convert.ToInt32(row["Flags"]); - entry.Time = new DateTime(); - return entry; - } - - /// - /// Builds the prim from a datarecord. - /// - /// datarecord - /// - private static SceneObjectPart BuildPrim(IDataRecord primRow) - { - SceneObjectPart prim = new SceneObjectPart(); - - prim.UUID = new UUID((Guid)primRow["UUID"]); - // explicit conversion of integers is required, which sort - // of sucks. No idea if there is a shortcut here or not. - prim.CreationDate = Convert.ToInt32(primRow["CreationDate"]); - prim.Name = (string)primRow["Name"]; - // various text fields - prim.Text = (string)primRow["Text"]; - prim.Color = Color.FromArgb(Convert.ToInt32(primRow["ColorA"]), - Convert.ToInt32(primRow["ColorR"]), - Convert.ToInt32(primRow["ColorG"]), - Convert.ToInt32(primRow["ColorB"])); - prim.Description = (string)primRow["Description"]; - prim.SitName = (string)primRow["SitName"]; - prim.TouchName = (string)primRow["TouchName"]; - // permissions - prim.ObjectFlags = Convert.ToUInt32(primRow["ObjectFlags"]); - prim.CreatorID = new UUID((Guid)primRow["CreatorID"]); - prim.OwnerID = new UUID((Guid)primRow["OwnerID"]); - prim.GroupID = new UUID((Guid)primRow["GroupID"]); - prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]); - prim.OwnerMask = Convert.ToUInt32(primRow["OwnerMask"]); - prim.NextOwnerMask = Convert.ToUInt32(primRow["NextOwnerMask"]); - prim.GroupMask = Convert.ToUInt32(primRow["GroupMask"]); - prim.EveryoneMask = Convert.ToUInt32(primRow["EveryoneMask"]); - prim.BaseMask = Convert.ToUInt32(primRow["BaseMask"]); - // vectors - prim.OffsetPosition = new Vector3( - Convert.ToSingle(primRow["PositionX"]), - Convert.ToSingle(primRow["PositionY"]), - Convert.ToSingle(primRow["PositionZ"])); - - prim.GroupPosition = new Vector3( - Convert.ToSingle(primRow["GroupPositionX"]), - Convert.ToSingle(primRow["GroupPositionY"]), - Convert.ToSingle(primRow["GroupPositionZ"])); - - prim.Velocity = new Vector3( - Convert.ToSingle(primRow["VelocityX"]), - Convert.ToSingle(primRow["VelocityY"]), - Convert.ToSingle(primRow["VelocityZ"])); - - prim.AngularVelocity = new Vector3( - Convert.ToSingle(primRow["AngularVelocityX"]), - Convert.ToSingle(primRow["AngularVelocityY"]), - Convert.ToSingle(primRow["AngularVelocityZ"])); - - prim.Acceleration = new Vector3( - Convert.ToSingle(primRow["AccelerationX"]), - Convert.ToSingle(primRow["AccelerationY"]), - Convert.ToSingle(primRow["AccelerationZ"])); - - // quaternions - prim.RotationOffset = new Quaternion( - Convert.ToSingle(primRow["RotationX"]), - Convert.ToSingle(primRow["RotationY"]), - Convert.ToSingle(primRow["RotationZ"]), - Convert.ToSingle(primRow["RotationW"])); - - prim.SitTargetPositionLL = new Vector3( - Convert.ToSingle(primRow["SitTargetOffsetX"]), - Convert.ToSingle(primRow["SitTargetOffsetY"]), - Convert.ToSingle(primRow["SitTargetOffsetZ"])); - - prim.SitTargetOrientationLL = new Quaternion( - Convert.ToSingle(primRow["SitTargetOrientX"]), - Convert.ToSingle(primRow["SitTargetOrientY"]), - Convert.ToSingle(primRow["SitTargetOrientZ"]), - Convert.ToSingle(primRow["SitTargetOrientW"])); - - prim.PayPrice[0] = Convert.ToInt32(primRow["PayPrice"]); - prim.PayPrice[1] = Convert.ToInt32(primRow["PayButton1"]); - prim.PayPrice[2] = Convert.ToInt32(primRow["PayButton2"]); - prim.PayPrice[3] = Convert.ToInt32(primRow["PayButton3"]); - prim.PayPrice[4] = Convert.ToInt32(primRow["PayButton4"]); - - prim.Sound = new UUID((Guid)primRow["LoopedSound"]); - prim.SoundGain = Convert.ToSingle(primRow["LoopedSoundGain"]); - prim.SoundFlags = 1; // If it's persisted at all, it's looped - - if (!(primRow["TextureAnimation"] is DBNull)) - prim.TextureAnimation = (Byte[])primRow["TextureAnimation"]; - if (!(primRow["ParticleSystem"] is DBNull)) - prim.ParticleSystem = (Byte[])primRow["ParticleSystem"]; - - prim.RotationalVelocity = new Vector3( - Convert.ToSingle(primRow["OmegaX"]), - Convert.ToSingle(primRow["OmegaY"]), - Convert.ToSingle(primRow["OmegaZ"])); - - prim.SetCameraEyeOffset(new Vector3( - Convert.ToSingle(primRow["CameraEyeOffsetX"]), - Convert.ToSingle(primRow["CameraEyeOffsetY"]), - Convert.ToSingle(primRow["CameraEyeOffsetZ"]) - )); - - prim.SetCameraAtOffset(new Vector3( - Convert.ToSingle(primRow["CameraAtOffsetX"]), - Convert.ToSingle(primRow["CameraAtOffsetY"]), - Convert.ToSingle(primRow["CameraAtOffsetZ"]) - )); - - if (Convert.ToInt16(primRow["ForceMouselook"]) != 0) - prim.SetForceMouselook(true); - - prim.ScriptAccessPin = Convert.ToInt32(primRow["ScriptAccessPin"]); - - if (Convert.ToInt16(primRow["AllowedDrop"]) != 0) - prim.AllowedDrop = true; - - if (Convert.ToInt16(primRow["DieAtEdge"]) != 0) - prim.DIE_AT_EDGE = true; - - prim.SalePrice = Convert.ToInt32(primRow["SalePrice"]); - prim.ObjectSaleType = Convert.ToByte(primRow["SaleType"]); - - prim.Material = Convert.ToByte(primRow["Material"]); - - if (!(primRow["ClickAction"] is DBNull)) - prim.ClickAction = Convert.ToByte(primRow["ClickAction"]); - - prim.CollisionSound = new UUID((Guid)primRow["CollisionSound"]); - prim.CollisionSoundVolume = Convert.ToSingle(primRow["CollisionSoundVolume"]); - if (Convert.ToInt16(primRow["PassTouches"]) != 0) - prim.PassTouches = true; - prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]); - - return prim; - } - - /// - /// Builds the prim shape from a datarecord. - /// - /// The row. - /// - private static PrimitiveBaseShape BuildShape(IDataRecord shapeRow) - { - PrimitiveBaseShape baseShape = new PrimitiveBaseShape(); - - baseShape.Scale = new Vector3( - Convert.ToSingle(shapeRow["ScaleX"]), - Convert.ToSingle(shapeRow["ScaleY"]), - Convert.ToSingle(shapeRow["ScaleZ"])); - - // paths - baseShape.PCode = Convert.ToByte(shapeRow["PCode"]); - baseShape.PathBegin = Convert.ToUInt16(shapeRow["PathBegin"]); - baseShape.PathEnd = Convert.ToUInt16(shapeRow["PathEnd"]); - baseShape.PathScaleX = Convert.ToByte(shapeRow["PathScaleX"]); - baseShape.PathScaleY = Convert.ToByte(shapeRow["PathScaleY"]); - baseShape.PathShearX = Convert.ToByte(shapeRow["PathShearX"]); - baseShape.PathShearY = Convert.ToByte(shapeRow["PathShearY"]); - baseShape.PathSkew = Convert.ToSByte(shapeRow["PathSkew"]); - baseShape.PathCurve = Convert.ToByte(shapeRow["PathCurve"]); - baseShape.PathRadiusOffset = Convert.ToSByte(shapeRow["PathRadiusOffset"]); - baseShape.PathRevolutions = Convert.ToByte(shapeRow["PathRevolutions"]); - baseShape.PathTaperX = Convert.ToSByte(shapeRow["PathTaperX"]); - baseShape.PathTaperY = Convert.ToSByte(shapeRow["PathTaperY"]); - baseShape.PathTwist = Convert.ToSByte(shapeRow["PathTwist"]); - baseShape.PathTwistBegin = Convert.ToSByte(shapeRow["PathTwistBegin"]); - // profile - baseShape.ProfileBegin = Convert.ToUInt16(shapeRow["ProfileBegin"]); - baseShape.ProfileEnd = Convert.ToUInt16(shapeRow["ProfileEnd"]); - baseShape.ProfileCurve = Convert.ToByte(shapeRow["ProfileCurve"]); - baseShape.ProfileHollow = Convert.ToUInt16(shapeRow["ProfileHollow"]); - - byte[] textureEntry = (byte[])shapeRow["Texture"]; - baseShape.TextureEntry = textureEntry; - - baseShape.ExtraParams = (byte[])shapeRow["ExtraParams"]; - - try - { - baseShape.State = Convert.ToByte(shapeRow["State"]); - } - catch (InvalidCastException) - { - } - - return baseShape; - } - - /// - /// Build a prim inventory item from the persisted data. - /// - /// - /// - private static TaskInventoryItem BuildItem(IDataRecord inventoryRow) - { - TaskInventoryItem taskItem = new TaskInventoryItem(); - - taskItem.ItemID = new UUID((Guid)inventoryRow["itemID"]); - taskItem.ParentPartID = new UUID((Guid)inventoryRow["primID"]); - taskItem.AssetID = new UUID((Guid)inventoryRow["assetID"]); - taskItem.ParentID = new UUID((Guid)inventoryRow["parentFolderID"]); - - taskItem.InvType = Convert.ToInt32(inventoryRow["invType"]); - taskItem.Type = Convert.ToInt32(inventoryRow["assetType"]); - - taskItem.Name = (string)inventoryRow["name"]; - taskItem.Description = (string)inventoryRow["description"]; - taskItem.CreationDate = Convert.ToUInt32(inventoryRow["creationDate"]); - taskItem.CreatorID = new UUID((Guid)inventoryRow["creatorID"]); - taskItem.OwnerID = new UUID((Guid)inventoryRow["ownerID"]); - taskItem.LastOwnerID = new UUID((Guid)inventoryRow["lastOwnerID"]); - taskItem.GroupID = new UUID((Guid)inventoryRow["groupID"]); - - taskItem.NextPermissions = Convert.ToUInt32(inventoryRow["nextPermissions"]); - taskItem.CurrentPermissions = Convert.ToUInt32(inventoryRow["currentPermissions"]); - taskItem.BasePermissions = Convert.ToUInt32(inventoryRow["basePermissions"]); - taskItem.EveryonePermissions = Convert.ToUInt32(inventoryRow["everyonePermissions"]); - taskItem.GroupPermissions = Convert.ToUInt32(inventoryRow["groupPermissions"]); - taskItem.Flags = Convert.ToUInt32(inventoryRow["flags"]); - - return taskItem; - } - - #endregion - - #region Create parameters methods - - /// - /// Creates the prim inventory parameters. - /// - /// item in inventory. - /// - private SqlParameter[] CreatePrimInventoryParameters(TaskInventoryItem taskItem) - { - List parameters = new List(); - - parameters.Add(_Database.CreateParameter("itemID", taskItem.ItemID)); - parameters.Add(_Database.CreateParameter("primID", taskItem.ParentPartID)); - parameters.Add(_Database.CreateParameter("assetID", taskItem.AssetID)); - parameters.Add(_Database.CreateParameter("parentFolderID", taskItem.ParentID)); - parameters.Add(_Database.CreateParameter("invType", taskItem.InvType)); - parameters.Add(_Database.CreateParameter("assetType", taskItem.Type)); - - parameters.Add(_Database.CreateParameter("name", taskItem.Name)); - parameters.Add(_Database.CreateParameter("description", taskItem.Description)); - parameters.Add(_Database.CreateParameter("creationDate", taskItem.CreationDate)); - parameters.Add(_Database.CreateParameter("creatorID", taskItem.CreatorID)); - parameters.Add(_Database.CreateParameter("ownerID", taskItem.OwnerID)); - parameters.Add(_Database.CreateParameter("lastOwnerID", taskItem.LastOwnerID)); - parameters.Add(_Database.CreateParameter("groupID", taskItem.GroupID)); - parameters.Add(_Database.CreateParameter("nextPermissions", taskItem.NextPermissions)); - parameters.Add(_Database.CreateParameter("currentPermissions", taskItem.CurrentPermissions)); - parameters.Add(_Database.CreateParameter("basePermissions", taskItem.BasePermissions)); - parameters.Add(_Database.CreateParameter("everyonePermissions", taskItem.EveryonePermissions)); - parameters.Add(_Database.CreateParameter("groupPermissions", taskItem.GroupPermissions)); - parameters.Add(_Database.CreateParameter("flags", taskItem.Flags)); - - return parameters.ToArray(); - } - - /// - /// Creates the region setting parameters. - /// - /// regionsettings. - /// - private SqlParameter[] CreateRegionSettingParameters(RegionSettings settings) - { - List parameters = new List(); - - parameters.Add(_Database.CreateParameter("regionUUID", settings.RegionUUID)); - parameters.Add(_Database.CreateParameter("block_terraform", settings.BlockTerraform)); - parameters.Add(_Database.CreateParameter("block_fly", settings.BlockFly)); - parameters.Add(_Database.CreateParameter("allow_damage", settings.AllowDamage)); - parameters.Add(_Database.CreateParameter("restrict_pushing", settings.RestrictPushing)); - parameters.Add(_Database.CreateParameter("allow_land_resell", settings.AllowLandResell)); - parameters.Add(_Database.CreateParameter("allow_land_join_divide", settings.AllowLandJoinDivide)); - parameters.Add(_Database.CreateParameter("block_show_in_search", settings.BlockShowInSearch)); - parameters.Add(_Database.CreateParameter("agent_limit", settings.AgentLimit)); - parameters.Add(_Database.CreateParameter("object_bonus", settings.ObjectBonus)); - parameters.Add(_Database.CreateParameter("maturity", settings.Maturity)); - parameters.Add(_Database.CreateParameter("disable_scripts", settings.DisableScripts)); - parameters.Add(_Database.CreateParameter("disable_collisions", settings.DisableCollisions)); - parameters.Add(_Database.CreateParameter("disable_physics", settings.DisablePhysics)); - parameters.Add(_Database.CreateParameter("terrain_texture_1", settings.TerrainTexture1)); - parameters.Add(_Database.CreateParameter("terrain_texture_2", settings.TerrainTexture2)); - parameters.Add(_Database.CreateParameter("terrain_texture_3", settings.TerrainTexture3)); - parameters.Add(_Database.CreateParameter("terrain_texture_4", settings.TerrainTexture4)); - parameters.Add(_Database.CreateParameter("elevation_1_nw", settings.Elevation1NW)); - parameters.Add(_Database.CreateParameter("elevation_2_nw", settings.Elevation2NW)); - parameters.Add(_Database.CreateParameter("elevation_1_ne", settings.Elevation1NE)); - parameters.Add(_Database.CreateParameter("elevation_2_ne", settings.Elevation2NE)); - parameters.Add(_Database.CreateParameter("elevation_1_se", settings.Elevation1SE)); - parameters.Add(_Database.CreateParameter("elevation_2_se", settings.Elevation2SE)); - parameters.Add(_Database.CreateParameter("elevation_1_sw", settings.Elevation1SW)); - parameters.Add(_Database.CreateParameter("elevation_2_sw", settings.Elevation2SW)); - parameters.Add(_Database.CreateParameter("water_height", settings.WaterHeight)); - parameters.Add(_Database.CreateParameter("terrain_raise_limit", settings.TerrainRaiseLimit)); - parameters.Add(_Database.CreateParameter("terrain_lower_limit", settings.TerrainLowerLimit)); - parameters.Add(_Database.CreateParameter("use_estate_sun", settings.UseEstateSun)); - parameters.Add(_Database.CreateParameter("sandbox", settings.Sandbox)); - parameters.Add(_Database.CreateParameter("fixed_sun", settings.FixedSun)); - parameters.Add(_Database.CreateParameter("sun_position", settings.SunPosition)); - parameters.Add(_Database.CreateParameter("sunvectorx", settings.SunVector.X)); - parameters.Add(_Database.CreateParameter("sunvectory", settings.SunVector.Y)); - parameters.Add(_Database.CreateParameter("sunvectorz", settings.SunVector.Z)); - parameters.Add(_Database.CreateParameter("covenant", settings.Covenant)); - parameters.Add(_Database.CreateParameter("Loaded_Creation_DateTime", settings.LoadedCreationDateTime)); - parameters.Add(_Database.CreateParameter("Loaded_Creation_ID", settings.LoadedCreationID)); - - return parameters.ToArray(); - } - - /// - /// Creates the land parameters. - /// - /// land parameters. - /// region UUID. - /// - private SqlParameter[] CreateLandParameters(LandData land, UUID regionUUID) - { - List parameters = new List(); - - parameters.Add(_Database.CreateParameter("UUID", land.GlobalID)); - parameters.Add(_Database.CreateParameter("RegionUUID", regionUUID)); - parameters.Add(_Database.CreateParameter("LocalLandID", land.LocalID)); - - // Bitmap is a byte[512] - parameters.Add(_Database.CreateParameter("Bitmap", land.Bitmap)); - - parameters.Add(_Database.CreateParameter("Name", land.Name)); - parameters.Add(_Database.CreateParameter("Description", land.Description)); - parameters.Add(_Database.CreateParameter("OwnerUUID", land.OwnerID)); - parameters.Add(_Database.CreateParameter("IsGroupOwned", land.IsGroupOwned)); - parameters.Add(_Database.CreateParameter("Area", land.Area)); - parameters.Add(_Database.CreateParameter("AuctionID", land.AuctionID)); //Unemplemented - parameters.Add(_Database.CreateParameter("Category", (int)land.Category)); //Enum libsecondlife.Parcel.ParcelCategory - parameters.Add(_Database.CreateParameter("ClaimDate", land.ClaimDate)); - parameters.Add(_Database.CreateParameter("ClaimPrice", land.ClaimPrice)); - parameters.Add(_Database.CreateParameter("GroupUUID", land.GroupID)); - parameters.Add(_Database.CreateParameter("SalePrice", land.SalePrice)); - parameters.Add(_Database.CreateParameter("LandStatus", (int)land.Status)); //Enum. libsecondlife.Parcel.ParcelStatus - parameters.Add(_Database.CreateParameter("LandFlags", land.Flags)); - parameters.Add(_Database.CreateParameter("LandingType", land.LandingType)); - parameters.Add(_Database.CreateParameter("MediaAutoScale", land.MediaAutoScale)); - parameters.Add(_Database.CreateParameter("MediaTextureUUID", land.MediaID)); - parameters.Add(_Database.CreateParameter("MediaURL", land.MediaURL)); - parameters.Add(_Database.CreateParameter("MusicURL", land.MusicURL)); - parameters.Add(_Database.CreateParameter("PassHours", land.PassHours)); - parameters.Add(_Database.CreateParameter("PassPrice", land.PassPrice)); - parameters.Add(_Database.CreateParameter("SnapshotUUID", land.SnapshotID)); - parameters.Add(_Database.CreateParameter("UserLocationX", land.UserLocation.X)); - parameters.Add(_Database.CreateParameter("UserLocationY", land.UserLocation.Y)); - parameters.Add(_Database.CreateParameter("UserLocationZ", land.UserLocation.Z)); - parameters.Add(_Database.CreateParameter("UserLookAtX", land.UserLookAt.X)); - parameters.Add(_Database.CreateParameter("UserLookAtY", land.UserLookAt.Y)); - parameters.Add(_Database.CreateParameter("UserLookAtZ", land.UserLookAt.Z)); - parameters.Add(_Database.CreateParameter("AuthBuyerID", land.AuthBuyerID)); - parameters.Add(_Database.CreateParameter("OtherCleanTime", land.OtherCleanTime)); - parameters.Add(_Database.CreateParameter("Dwell", land.Dwell)); - - return parameters.ToArray(); - } - - /// - /// Creates the land access parameters. - /// - /// parcel access entry. - /// parcel ID. - /// - private SqlParameter[] CreateLandAccessParameters(ParcelManager.ParcelAccessEntry parcelAccessEntry, UUID parcelID) - { - List parameters = new List(); - - parameters.Add(_Database.CreateParameter("LandUUID", parcelID)); - parameters.Add(_Database.CreateParameter("AccessUUID", parcelAccessEntry.AgentID)); - parameters.Add(_Database.CreateParameter("Flags", parcelAccessEntry.Flags)); - - return parameters.ToArray(); - } - - /// - /// Creates the prim parameters for storing in DB. - /// - /// Basic data of SceneObjectpart prim. - /// The scenegroup ID. - /// The region ID. - /// - private SqlParameter[] CreatePrimParameters(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) - { - List parameters = new List(); - - parameters.Add(_Database.CreateParameter("UUID", prim.UUID)); - parameters.Add(_Database.CreateParameter("RegionUUID", regionUUID)); - parameters.Add(_Database.CreateParameter("CreationDate", prim.CreationDate)); - parameters.Add(_Database.CreateParameter("Name", prim.Name)); - parameters.Add(_Database.CreateParameter("SceneGroupID", sceneGroupID)); - // the UUID of the root part for this SceneObjectGroup - // various text fields - parameters.Add(_Database.CreateParameter("Text", prim.Text)); - parameters.Add(_Database.CreateParameter("ColorR", prim.Color.R)); - parameters.Add(_Database.CreateParameter("ColorG", prim.Color.G)); - parameters.Add(_Database.CreateParameter("ColorB", prim.Color.B)); - parameters.Add(_Database.CreateParameter("ColorA", prim.Color.A)); - parameters.Add(_Database.CreateParameter("Description", prim.Description)); - parameters.Add(_Database.CreateParameter("SitName", prim.SitName)); - parameters.Add(_Database.CreateParameter("TouchName", prim.TouchName)); - // permissions - parameters.Add(_Database.CreateParameter("ObjectFlags", prim.ObjectFlags)); - parameters.Add(_Database.CreateParameter("CreatorID", prim.CreatorID)); - parameters.Add(_Database.CreateParameter("OwnerID", prim.OwnerID)); - parameters.Add(_Database.CreateParameter("GroupID", prim.GroupID)); - parameters.Add(_Database.CreateParameter("LastOwnerID", prim.LastOwnerID)); - parameters.Add(_Database.CreateParameter("OwnerMask", prim.OwnerMask)); - parameters.Add(_Database.CreateParameter("NextOwnerMask", prim.NextOwnerMask)); - parameters.Add(_Database.CreateParameter("GroupMask", prim.GroupMask)); - parameters.Add(_Database.CreateParameter("EveryoneMask", prim.EveryoneMask)); - parameters.Add(_Database.CreateParameter("BaseMask", prim.BaseMask)); - // vectors - parameters.Add(_Database.CreateParameter("PositionX", prim.OffsetPosition.X)); - parameters.Add(_Database.CreateParameter("PositionY", prim.OffsetPosition.Y)); - parameters.Add(_Database.CreateParameter("PositionZ", prim.OffsetPosition.Z)); - parameters.Add(_Database.CreateParameter("GroupPositionX", prim.GroupPosition.X)); - parameters.Add(_Database.CreateParameter("GroupPositionY", prim.GroupPosition.Y)); - parameters.Add(_Database.CreateParameter("GroupPositionZ", prim.GroupPosition.Z)); - parameters.Add(_Database.CreateParameter("VelocityX", prim.Velocity.X)); - parameters.Add(_Database.CreateParameter("VelocityY", prim.Velocity.Y)); - parameters.Add(_Database.CreateParameter("VelocityZ", prim.Velocity.Z)); - parameters.Add(_Database.CreateParameter("AngularVelocityX", prim.AngularVelocity.X)); - parameters.Add(_Database.CreateParameter("AngularVelocityY", prim.AngularVelocity.Y)); - parameters.Add(_Database.CreateParameter("AngularVelocityZ", prim.AngularVelocity.Z)); - parameters.Add(_Database.CreateParameter("AccelerationX", prim.Acceleration.X)); - parameters.Add(_Database.CreateParameter("AccelerationY", prim.Acceleration.Y)); - parameters.Add(_Database.CreateParameter("AccelerationZ", prim.Acceleration.Z)); - // quaternions - parameters.Add(_Database.CreateParameter("RotationX", prim.RotationOffset.X)); - parameters.Add(_Database.CreateParameter("RotationY", prim.RotationOffset.Y)); - parameters.Add(_Database.CreateParameter("RotationZ", prim.RotationOffset.Z)); - parameters.Add(_Database.CreateParameter("RotationW", prim.RotationOffset.W)); - - // Sit target - Vector3 sitTargetPos = prim.SitTargetPositionLL; - parameters.Add(_Database.CreateParameter("SitTargetOffsetX", sitTargetPos.X)); - parameters.Add(_Database.CreateParameter("SitTargetOffsetY", sitTargetPos.Y)); - parameters.Add(_Database.CreateParameter("SitTargetOffsetZ", sitTargetPos.Z)); - - Quaternion sitTargetOrient = prim.SitTargetOrientationLL; - parameters.Add(_Database.CreateParameter("SitTargetOrientW", sitTargetOrient.W)); - parameters.Add(_Database.CreateParameter("SitTargetOrientX", sitTargetOrient.X)); - parameters.Add(_Database.CreateParameter("SitTargetOrientY", sitTargetOrient.Y)); - parameters.Add(_Database.CreateParameter("SitTargetOrientZ", sitTargetOrient.Z)); - - parameters.Add(_Database.CreateParameter("PayPrice", prim.PayPrice[0])); - parameters.Add(_Database.CreateParameter("PayButton1", prim.PayPrice[1])); - parameters.Add(_Database.CreateParameter("PayButton2", prim.PayPrice[2])); - parameters.Add(_Database.CreateParameter("PayButton3", prim.PayPrice[3])); - parameters.Add(_Database.CreateParameter("PayButton4", prim.PayPrice[4])); - - if ((prim.SoundFlags & 1) != 0) // Looped - { - parameters.Add(_Database.CreateParameter("LoopedSound", prim.Sound)); - parameters.Add(_Database.CreateParameter("LoopedSoundGain", prim.SoundGain)); - } - else - { - parameters.Add(_Database.CreateParameter("LoopedSound", UUID.Zero)); - parameters.Add(_Database.CreateParameter("LoopedSoundGain", 0.0f)); - } - - parameters.Add(_Database.CreateParameter("TextureAnimation", prim.TextureAnimation)); - parameters.Add(_Database.CreateParameter("ParticleSystem", prim.ParticleSystem)); - - parameters.Add(_Database.CreateParameter("OmegaX", prim.RotationalVelocity.X)); - parameters.Add(_Database.CreateParameter("OmegaY", prim.RotationalVelocity.Y)); - parameters.Add(_Database.CreateParameter("OmegaZ", prim.RotationalVelocity.Z)); - - parameters.Add(_Database.CreateParameter("CameraEyeOffsetX", prim.GetCameraEyeOffset().X)); - parameters.Add(_Database.CreateParameter("CameraEyeOffsetY", prim.GetCameraEyeOffset().Y)); - parameters.Add(_Database.CreateParameter("CameraEyeOffsetZ", prim.GetCameraEyeOffset().Z)); - - parameters.Add(_Database.CreateParameter("CameraAtOffsetX", prim.GetCameraAtOffset().X)); - parameters.Add(_Database.CreateParameter("CameraAtOffsetY", prim.GetCameraAtOffset().Y)); - parameters.Add(_Database.CreateParameter("CameraAtOffsetZ", prim.GetCameraAtOffset().Z)); - - if (prim.GetForceMouselook()) - parameters.Add(_Database.CreateParameter("ForceMouselook", 1)); - else - parameters.Add(_Database.CreateParameter("ForceMouselook", 0)); - - parameters.Add(_Database.CreateParameter("ScriptAccessPin", prim.ScriptAccessPin)); - - if (prim.AllowedDrop) - parameters.Add(_Database.CreateParameter("AllowedDrop", 1)); - else - parameters.Add(_Database.CreateParameter("AllowedDrop", 0)); - - if (prim.DIE_AT_EDGE) - parameters.Add(_Database.CreateParameter("DieAtEdge", 1)); - else - parameters.Add(_Database.CreateParameter("DieAtEdge", 0)); - - parameters.Add(_Database.CreateParameter("SalePrice", prim.SalePrice)); - parameters.Add(_Database.CreateParameter("SaleType", prim.ObjectSaleType)); - - byte clickAction = prim.ClickAction; - parameters.Add(_Database.CreateParameter("ClickAction", clickAction)); - - parameters.Add(_Database.CreateParameter("Material", prim.Material)); - - parameters.Add(_Database.CreateParameter("CollisionSound", prim.CollisionSound)); - parameters.Add(_Database.CreateParameter("CollisionSoundVolume", prim.CollisionSoundVolume)); - if (prim.PassTouches) - parameters.Add(_Database.CreateParameter("PassTouches", 1)); - else - parameters.Add(_Database.CreateParameter("PassTouches", 0)); - parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum)); - - return parameters.ToArray(); - } - - /// - /// Creates the primshape parameters for stroing in DB. - /// - /// Basic data of SceneObjectpart prim. - /// The scene group ID. - /// The region UUID. - /// - private SqlParameter[] CreatePrimShapeParameters(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) - { - List parameters = new List(); - - PrimitiveBaseShape s = prim.Shape; - parameters.Add(_Database.CreateParameter("UUID", prim.UUID)); - // shape is an enum - parameters.Add(_Database.CreateParameter("Shape", 0)); - // vectors - parameters.Add(_Database.CreateParameter("ScaleX", s.Scale.X)); - parameters.Add(_Database.CreateParameter("ScaleY", s.Scale.Y)); - parameters.Add(_Database.CreateParameter("ScaleZ", s.Scale.Z)); - // paths - parameters.Add(_Database.CreateParameter("PCode", s.PCode)); - parameters.Add(_Database.CreateParameter("PathBegin", s.PathBegin)); - parameters.Add(_Database.CreateParameter("PathEnd", s.PathEnd)); - parameters.Add(_Database.CreateParameter("PathScaleX", s.PathScaleX)); - parameters.Add(_Database.CreateParameter("PathScaleY", s.PathScaleY)); - parameters.Add(_Database.CreateParameter("PathShearX", s.PathShearX)); - parameters.Add(_Database.CreateParameter("PathShearY", s.PathShearY)); - parameters.Add(_Database.CreateParameter("PathSkew", s.PathSkew)); - parameters.Add(_Database.CreateParameter("PathCurve", s.PathCurve)); - parameters.Add(_Database.CreateParameter("PathRadiusOffset", s.PathRadiusOffset)); - parameters.Add(_Database.CreateParameter("PathRevolutions", s.PathRevolutions)); - parameters.Add(_Database.CreateParameter("PathTaperX", s.PathTaperX)); - parameters.Add(_Database.CreateParameter("PathTaperY", s.PathTaperY)); - parameters.Add(_Database.CreateParameter("PathTwist", s.PathTwist)); - parameters.Add(_Database.CreateParameter("PathTwistBegin", s.PathTwistBegin)); - // profile - parameters.Add(_Database.CreateParameter("ProfileBegin", s.ProfileBegin)); - parameters.Add(_Database.CreateParameter("ProfileEnd", s.ProfileEnd)); - parameters.Add(_Database.CreateParameter("ProfileCurve", s.ProfileCurve)); - parameters.Add(_Database.CreateParameter("ProfileHollow", s.ProfileHollow)); - parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry)); - parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams)); - parameters.Add(_Database.CreateParameter("State", s.State)); - - return parameters.ToArray(); - } - - #endregion - - #endregion } } diff --git a/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs b/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs index 38be9f4061..7b6e7c8a0c 100644 --- a/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs +++ b/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs @@ -40,19 +40,21 @@ namespace OpenSim.Data.MSSQL { private string m_Realm; private List m_ColumnNames = null; - private int m_LastExpire = 0; private string m_ConnectionString; + private MSSQLManager m_database; public MSSQLUserAccountData(string connectionString, string realm) { m_Realm = realm; m_ConnectionString = connectionString; + m_database = new MSSQLManager(connectionString); + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) { conn.Open(); Migration m = new Migration(conn, GetType().Assembly, "UserStore"); m.Update(); - } + } } public List Query(UUID principalID, UUID scopeID, string query) @@ -65,16 +67,16 @@ namespace OpenSim.Data.MSSQL UserAccountData ret = new UserAccountData(); ret.Data = new Dictionary(); - string sql = string.Format("select * from '{0}' where UUID = @principalID", m_Realm); + string sql = string.Format("select * from {0} where UUID = @principalID", m_Realm); if (scopeID != UUID.Zero) sql += " and ScopeID = @scopeID"; using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand(sql, conn)) { - - cmd.Parameters.AddWithValue("@principalID", principalID); - cmd.Parameters.AddWithValue("@scopeID", scopeID); + cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID)); + cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID)); + conn.Open(); using (SqlDataReader result = cmd.ExecuteReader()) { @@ -123,17 +125,16 @@ namespace OpenSim.Data.MSSQL using (SqlCommand cmd = new SqlCommand()) { StringBuilder updateBuilder = new StringBuilder(); - updateBuilder.AppendFormat("update '{0}' set ", m_Realm); + updateBuilder.AppendFormat("update {0} set ", m_Realm); bool first = true; foreach (string field in fields) { if (!first) updateBuilder.Append(", "); - updateBuilder.AppendFormat("'{0}' = @{0}", field); + updateBuilder.AppendFormat("{0} = @{0}", field); first = false; - - cmd.Parameters.AddWithValue("@" + field, data.Data[field]); + cmd.Parameters.Add(m_database.CreateParameter("@" + field, data.Data[field])); } updateBuilder.Append(" where UUID = @principalID"); @@ -143,16 +144,16 @@ namespace OpenSim.Data.MSSQL cmd.CommandText = updateBuilder.ToString(); cmd.Connection = conn; - cmd.Parameters.AddWithValue("@principalID", data.PrincipalID); - cmd.Parameters.AddWithValue("@scopeID", data.ScopeID); + cmd.Parameters.Add(m_database.CreateParameter("@principalID", data.PrincipalID)); + cmd.Parameters.Add(m_database.CreateParameter("@scopeID", data.ScopeID)); conn.Open(); if (cmd.ExecuteNonQuery() < 1) { StringBuilder insertBuilder = new StringBuilder(); - insertBuilder.AppendFormat("insert into '{0}' ('UUID', 'ScopeID', '", m_Realm); - insertBuilder.Append(String.Join("', '", fields)); - insertBuilder.Append("') values (@principalID, @scopeID, @"); + insertBuilder.AppendFormat("insert into {0} (UUID, ScopeID, ", m_Realm); + insertBuilder.Append(String.Join(", ", fields)); + insertBuilder.Append(") values ( @principalID, @scopeID, @"); insertBuilder.Append(String.Join(", @", fields)); insertBuilder.Append(")"); @@ -169,12 +170,13 @@ namespace OpenSim.Data.MSSQL public bool SetDataItem(UUID principalID, string item, string value) { - string sql = string.Format("update '{0}' set '{1}' = @{1} where UUID = @UUID", m_Realm, item); + string sql = string.Format("update {0} set {1} = @{1} where UUID = @UUID", m_Realm, item); using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand(sql, conn)) { - cmd.Parameters.AddWithValue("@" + item, value); - cmd.Parameters.AddWithValue("@UUID", principalID); + cmd.Parameters.Add(m_database.CreateParameter("@" + item, value)); + cmd.Parameters.Add(m_database.CreateParameter("@UUID", principalID)); + conn.Open(); if (cmd.ExecuteNonQuery() > 0) diff --git a/OpenSim/Data/MSSQL/Resources/006_GridStore.sql b/OpenSim/Data/MSSQL/Resources/006_GridStore.sql new file mode 100644 index 0000000000..42010ce657 --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/006_GridStore.sql @@ -0,0 +1,8 @@ +BEGIN TRANSACTION + +ALTER TABLE regions ADD scopeid uniqueidentifier default '00000000-0000-0000-0000-000000000000'; +ALTER TABLE regions ADD DEFAULT ('00000000-0000-0000-0000-000000000000') FOR [owner_uuid]; +ALTER TABLE regions ADD sizeX integer not null default 0; +ALTER TABLE regions ADD sizeY integer not null default 0; + +COMMIT diff --git a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs index e96a123348..a41f9f8f40 100644 --- a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs +++ b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs @@ -82,12 +82,16 @@ namespace OpenSim.Data.MySQL ret.Data[s] = result[s].ToString(); } + CloseDBConnection(cmd); return ret; } + else + { + CloseDBConnection(cmd); + return null; + } } } - - return null; } public bool Store(AuthenticationData data) diff --git a/OpenSim/Data/MySQL/MySQLFramework.cs b/OpenSim/Data/MySQL/MySQLFramework.cs index c756c9cf45..f37e9bcb6c 100644 --- a/OpenSim/Data/MySQL/MySQLFramework.cs +++ b/OpenSim/Data/MySQL/MySQLFramework.cs @@ -47,7 +47,6 @@ namespace OpenSim.Data.MySQL protected MySqlFramework(string connectionString) { m_Connection = new MySqlConnection(connectionString); - m_Connection.Open(); } @@ -82,8 +81,7 @@ namespace OpenSim.Data.MySQL errorSeen = true; m_Connection.Close(); - MySqlConnection newConnection = (MySqlConnection) - ((ICloneable)m_Connection).Clone(); + MySqlConnection newConnection = (MySqlConnection)((ICloneable)m_Connection).Clone(); m_Connection.Dispose(); m_Connection = newConnection; m_Connection.Open(); @@ -104,14 +102,16 @@ namespace OpenSim.Data.MySQL protected IDataReader ExecuteReader(MySqlCommand cmd) { - MySqlConnection newConnection = (MySqlConnection) - ((ICloneable)m_Connection).Clone(); - + MySqlConnection newConnection = (MySqlConnection)((ICloneable)m_Connection).Clone(); newConnection.Open(); cmd.Connection = newConnection; - return cmd.ExecuteReader(); } + + protected void CloseDBConnection(MySqlCommand cmd) + { + cmd.Connection.Dispose(); + } } } diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index 04b24b6362..3fe27d5702 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -172,6 +172,8 @@ namespace OpenSim.Data.MySQL retList.Add(ret); } + + CloseDBConnection(cmd); } return retList; diff --git a/OpenSim/Data/MySQL/MySQLUserAccountData.cs b/OpenSim/Data/MySQL/MySQLUserAccountData.cs index c713a119d3..38a6f55ed3 100644 --- a/OpenSim/Data/MySQL/MySQLUserAccountData.cs +++ b/OpenSim/Data/MySQL/MySQLUserAccountData.cs @@ -97,12 +97,16 @@ namespace OpenSim.Data.MySQL ret.Data[s] = result[s].ToString(); } + CloseDBConnection(cmd); return ret; } + else + { + CloseDBConnection(cmd); + return null; + } } } - - return null; } public bool Store(UserAccountData data) diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 632b551f47..56155ddd59 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -238,7 +238,7 @@ namespace OpenSim.Framework.Servers List threads = ThreadTracker.GetThreads(); if (threads == null) { - sb.Append("Thread tracking is only enabled in DEBUG mode."); + sb.Append("OpenSim thread tracking is only enabled in DEBUG mode."); } else { @@ -264,6 +264,12 @@ namespace OpenSim.Framework.Servers } } } + int workers = 0, ports = 0, maxWorkers = 0, maxPorts = 0; + ThreadPool.GetAvailableThreads(out workers, out ports); + ThreadPool.GetMaxThreads(out maxWorkers, out maxPorts); + + sb.Append(Environment.NewLine + "*** ThreadPool threads ***" + Environment.NewLine); + sb.Append("workers: " + (maxWorkers - workers) + " (" + maxWorkers + "); ports: " + (maxPorts - ports) + " (" + maxPorts + ")" + Environment.NewLine); return sb.ToString(); } diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs index 8a490f7233..4543fd5e99 100644 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs @@ -28,14 +28,21 @@ using System; using System.IO; using System.Net; +using System.Reflection; using System.Text; using System.Xml; using System.Xml.Serialization; +using log4net; + namespace OpenSim.Framework.Servers.HttpServer { public class SynchronousRestFormsRequester { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + /// /// Perform a synchronous REST request. /// @@ -72,8 +79,9 @@ namespace OpenSim.Framework.Servers.HttpServer requestStream = request.GetRequestStream(); requestStream.Write(buffer.ToArray(), 0, length); } - catch + catch (Exception e) { + m_log.DebugFormat("[FORMS]: exception occured on sending request {0}", e.Message); } finally { @@ -102,7 +110,10 @@ namespace OpenSim.Framework.Servers.HttpServer respstring = reader.ReadToEnd(); } } - catch { } + catch (Exception e) + { + m_log.DebugFormat("[FORMS]: exception occured on receiving reply {0}", e.Message); + } finally { if (respStream != null) @@ -114,6 +125,7 @@ namespace OpenSim.Framework.Servers.HttpServer catch (System.InvalidOperationException) { // This is what happens when there is invalid XML + m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving request"); } return respstring; } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs index 5219df708d..343f537d94 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs @@ -88,7 +88,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP J2KImage imgrequest; // Do a linear search for this texture download - lock (m_priorityQueue) + lock (m_syncRoot) m_priorityQueue.Find(delegate(J2KImage img) { return img.TextureID == newRequest.RequestedAssetID; }, out imgrequest); if (imgrequest != null) @@ -99,7 +99,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP try { - lock (m_priorityQueue) + lock (m_syncRoot) m_priorityQueue.Delete(imgrequest.PriorityQueueHandle); } catch (Exception) { } @@ -167,8 +167,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP J2KImage imagereq; int numCollected = 0; - lock (m_syncRoot) - { + //lock (m_syncRoot) + //{ m_lastloopprocessed = DateTime.Now.Ticks; // This can happen during Close() @@ -191,7 +191,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (numCollected == count) break; } - } + //} return m_priorityQueue.Count > 0; } @@ -211,16 +211,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP { J2KImage image = null; - if (m_priorityQueue.Count > 0) + lock (m_syncRoot) { - try - { - lock (m_priorityQueue) - image = m_priorityQueue.FindMax(); - } - catch (Exception) { } - } + if (m_priorityQueue.Count > 0) + { + try + { + image = m_priorityQueue.FindMax(); + } + catch (Exception) { } + } + } return image; } @@ -228,23 +230,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP { image.PriorityQueueHandle = null; - lock (m_priorityQueue) - m_priorityQueue.Add(ref image.PriorityQueueHandle, image); + lock (m_syncRoot) + try + { + m_priorityQueue.Add(ref image.PriorityQueueHandle, image); + } + catch (Exception) { } } void RemoveImageFromQueue(J2KImage image) { - try - { - lock (m_priorityQueue) + lock (m_syncRoot) + try + { m_priorityQueue.Delete(image.PriorityQueueHandle); - } - catch (Exception) { } + } + catch (Exception) { } } void UpdateImageInQueue(J2KImage image) { - lock (m_priorityQueue) + lock (m_syncRoot) { try { m_priorityQueue.Replace(image.PriorityQueueHandle, image); } catch (Exception) diff --git a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs index 5a5ad7e493..66ca7c2336 100644 --- a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs @@ -178,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Asset { if (maximalSize <= 0 || maximalCount <= 0) { - Log.Info("[ASSET CACHE]: Cenome asset cache is not enabled."); + //Log.Debug("[ASSET CACHE]: Cenome asset cache is not enabled."); m_enabled = false; return; } @@ -194,7 +194,7 @@ namespace OpenSim.Region.CoreModules.Asset CnmSynchronizedCache.Synchronized(new CnmMemoryCache( maximalSize, maximalCount, expirationTime)); m_enabled = true; - Log.InfoFormat( + Log.DebugFormat( "[ASSET CACHE]: Cenome asset cache enabled (MaxSize = {0} bytes, MaxCount = {1}, ExpirationTime = {2})", maximalSize, maximalCount, @@ -263,7 +263,7 @@ namespace OpenSim.Region.CoreModules.Asset if (m_getCount == m_debugEpoch) { - Log.InfoFormat( + Log.DebugFormat( "[ASSET CACHE]: Cached = {0}, Get = {1}, Hits = {2}%, Size = {3} bytes, Avg. A. Size = {4} bytes", m_cachedCount, m_getCount, @@ -333,7 +333,7 @@ namespace OpenSim.Region.CoreModules.Asset return; string name = moduleConfig.GetString("AssetCaching"); - Log.DebugFormat("[XXX] name = {0} (this module's name: {1}", name, Name); + //Log.DebugFormat("[XXX] name = {0} (this module's name: {1}", name, Name); if (name != Name) return; @@ -343,14 +343,14 @@ namespace OpenSim.Region.CoreModules.Asset int maxCount = DefaultMaxCount; TimeSpan expirationTime = DefaultExpirationTime; - IConfig assetConfig = source.Configs[ "AssetCache" ]; + IConfig assetConfig = source.Configs["AssetCache"]; if (assetConfig != null) { // Get optional configurations maxSize = assetConfig.GetLong("MaxSize", DefaultMaxSize); maxCount = assetConfig.GetInt("MaxCount", DefaultMaxCount); expirationTime = - TimeSpan.FromMinutes(assetConfig.GetInt("ExpirationTime", (int) DefaultExpirationTime.TotalMinutes)); + TimeSpan.FromMinutes(assetConfig.GetInt("ExpirationTime", (int)DefaultExpirationTime.TotalMinutes)); // Debugging purposes only m_debugEpoch = assetConfig.GetInt("DebugEpoch", 0); diff --git a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs index 2de40d28ee..0a7e736599 100644 --- a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs @@ -66,7 +66,7 @@ namespace OpenSim.Region.CoreModules.Asset if (moduleConfig != null) { string name = moduleConfig.GetString("AssetCaching"); - m_log.DebugFormat("[XXX] name = {0} (this module's name: {1}", name, Name); + //m_log.DebugFormat("[XXX] name = {0} (this module's name: {1}", name, Name); if (name == Name) { diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index c0bb70cafc..b81ab41351 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -636,11 +636,8 @@ namespace Flotsam.RegionModules.AssetCache m_log.InfoFormat("[FLOTSAM ASSET CACHE] flotsamcache clearfile - Remove all assets cached on disk"); } - - } #endregion - } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs index 8d8e0fe481..4869f5d6b8 100644 --- a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs @@ -68,7 +68,7 @@ namespace OpenSim.Region.CoreModules.Asset if (moduleConfig != null) { string name = moduleConfig.GetString("AssetCaching"); - m_log.DebugFormat("[ASSET CACHE] name = {0} (this module's name: {1}). Sync? ", name, Name, m_Cache.IsSynchronized); + //m_log.DebugFormat("[ASSET CACHE] name = {0} (this module's name: {1}). Sync? ", name, Name, m_Cache.IsSynchronized); if (name == Name) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs index 3ca4882327..1c72488bbc 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs @@ -206,6 +206,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) { + GridRegion region = null; + + // First see if it's a neighbour, even if it isn't on this sim. + // Neighbour data is cached in memory, so this is fast + foreach (RegionCache rcache in m_LocalCache.Values) + { + region = rcache.GetRegionByPosition(x, y); + if (region != null) + { + return region; + } + } + + // Then try on this sim (may be a lookup in DB if this is using MySql). return m_GridService.GetRegionByPosition(scopeID, x, y); } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs index 2b336bb0a2..44e850bae3 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs @@ -29,10 +29,12 @@ using System; using System.Collections.Generic; using System.Reflection; +using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using OpenMetaverse; using log4net; namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid @@ -75,5 +77,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid { return new List(m_neighbours.Values); } + + public GridRegion GetRegionByPosition(int x, int y) + { + uint xsnap = (uint)(x / Constants.RegionSize) * Constants.RegionSize; + uint ysnap = (uint)(y / Constants.RegionSize) * Constants.RegionSize; + ulong handle = Utils.UIntsToLong(xsnap, ysnap); + + if (m_neighbours.ContainsKey(handle)) + return m_neighbours[handle]; + + return null; + } } } diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 9622555af1..901144a289 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -397,10 +397,15 @@ namespace OpenSim.Region.CoreModules.World.Permissions // with the powers requested (powers = 0 for no powers check) protected bool IsGroupMember(UUID groupID, UUID userID, ulong powers) { - IClientAPI client = m_scene.GetScenePresence(userID).ControllingClient; - - return ((groupID == client.ActiveGroupId) && (client.ActiveGroupPowers != 0) && - ((powers == 0) || ((client.ActiveGroupPowers & powers) == powers))); + ScenePresence sp = m_scene.GetScenePresence(userID); + if (sp != null) + { + IClientAPI client = sp.ControllingClient; + + return ((groupID == client.ActiveGroupId) && (client.ActiveGroupPowers != 0) && + ((powers == 0) || ((client.ActiveGroupPowers & powers) == powers))); + } + return false; } /// diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 631d80143a..00fe5df046 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -425,7 +425,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) { - if (m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) + if (!m_agentsDroppedSession.ContainsKey(im.imSessionID) || m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) { // Don't deliver messages to people who have dropped this session if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 2e89a24a14..b2091995e9 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -148,9 +148,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups UUID[] CurrentKeys = new UUID[m_clientRequestIDInfo.Count]; foreach (UUID key in CurrentKeys) { - if (DateTime.Now - m_clientRequestIDInfo[key].LastUsedTMStamp > cacheTimeout) + if (m_clientRequestIDInfo.ContainsKey(key)) { - m_clientRequestIDInfo.Remove(key); + if (DateTime.Now - m_clientRequestIDInfo[key].LastUsedTMStamp > cacheTimeout) + { + m_clientRequestIDInfo.Remove(key); + } } } } @@ -476,7 +479,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (string key in binBucketOSD.Keys) { - m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); + if (binBucketOSD.ContainsKey(key)) + { + m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); + } } } diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs index e26c6234a1..ac14292915 100644 --- a/OpenSim/Region/Physics/Manager/IMesher.cs +++ b/OpenSim/Region/Physics/Manager/IMesher.cs @@ -47,6 +47,8 @@ namespace OpenSim.Region.Physics.Manager int[] getIndexListAsInt(); int[] getIndexListAsIntLocked(); float[] getVertexListAsFloatLocked(); + void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount); + void getVertexListAsPtrToFloatArray( out IntPtr vertexList, out int vertexStride, out int vertexCount ); void releaseSourceMeshData(); void releasePinned(); void Append(IMesh newMesh); diff --git a/OpenSim/Region/Physics/Meshing/Mesh.cs b/OpenSim/Region/Physics/Meshing/Mesh.cs index aae88710ab..ff1f816c88 100644 --- a/OpenSim/Region/Physics/Meshing/Mesh.cs +++ b/OpenSim/Region/Physics/Meshing/Mesh.cs @@ -36,23 +36,27 @@ namespace OpenSim.Region.Physics.Meshing { public class Mesh : IMesh { - private Dictionary vertices; - private List triangles; - GCHandle pinnedVirtexes; - GCHandle pinnedIndex; - public float[] normals; + private Dictionary m_vertices; + private List m_triangles; + GCHandle m_pinnedVertexes; + GCHandle m_pinnedIndex; + IntPtr m_verticesPtr = IntPtr.Zero; + int m_vertexCount = 0; + IntPtr m_indicesPtr = IntPtr.Zero; + int m_indexCount = 0; + public float[] m_normals; public Mesh() { - vertices = new Dictionary(); - triangles = new List(); + m_vertices = new Dictionary(); + m_triangles = new List(); } public Mesh Clone() { Mesh result = new Mesh(); - foreach (Triangle t in triangles) + foreach (Triangle t in m_triangles) { result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone())); } @@ -62,27 +66,27 @@ namespace OpenSim.Region.Physics.Meshing public void Add(Triangle triangle) { - if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated) + if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) throw new NotSupportedException("Attempt to Add to a pinned Mesh"); // If a vertex of the triangle is not yet in the vertices list, // add it and set its index to the current index count - if (!vertices.ContainsKey(triangle.v1)) - vertices[triangle.v1] = vertices.Count; - if (!vertices.ContainsKey(triangle.v2)) - vertices[triangle.v2] = vertices.Count; - if (!vertices.ContainsKey(triangle.v3)) - vertices[triangle.v3] = vertices.Count; - triangles.Add(triangle); + if( !m_vertices.ContainsKey(triangle.v1) ) + m_vertices[triangle.v1] = m_vertices.Count; + if (!m_vertices.ContainsKey(triangle.v2)) + m_vertices[triangle.v2] = m_vertices.Count; + if (!m_vertices.ContainsKey(triangle.v3)) + m_vertices[triangle.v3] = m_vertices.Count; + m_triangles.Add(triangle); } public void CalcNormals() { - int iTriangles = triangles.Count; + int iTriangles = m_triangles.Count; - this.normals = new float[iTriangles * 3]; + this.m_normals = new float[iTriangles * 3]; int i = 0; - foreach (Triangle t in triangles) + foreach (Triangle t in m_triangles) { float ux, uy, uz; float vx, vy, vz; @@ -129,9 +133,9 @@ namespace OpenSim.Region.Physics.Meshing //ny /= l; //nz /= l; - normals[i] = nx * lReciprocal; - normals[i + 1] = ny * lReciprocal; - normals[i + 2] = nz * lReciprocal; + m_normals[i] = nx * lReciprocal; + m_normals[i + 1] = ny * lReciprocal; + m_normals[i + 2] = nz * lReciprocal; i += 3; } @@ -140,45 +144,70 @@ namespace OpenSim.Region.Physics.Meshing public List getVertexList() { List result = new List(); - foreach (Vertex v in vertices.Keys) + foreach (Vertex v in m_vertices.Keys) { result.Add(v); } return result; } - public float[] getVertexListAsFloatLocked() + private float[] getVertexListAsFloat() { - if (pinnedVirtexes.IsAllocated) - return (float[])(pinnedVirtexes.Target); - float[] result; - - //m_log.WarnFormat("vertices.Count = {0}", vertices.Count); - result = new float[vertices.Count * 3]; - foreach (KeyValuePair kvp in vertices) + if(m_vertices == null) + throw new NotSupportedException(); + float[] result = new float[m_vertices.Count * 3]; + foreach (KeyValuePair kvp in m_vertices) { Vertex v = kvp.Key; int i = kvp.Value; - //m_log.WarnFormat("kvp.Value = {0}", i); result[3 * i + 0] = v.X; result[3 * i + 1] = v.Y; result[3 * i + 2] = v.Z; } - pinnedVirtexes = GCHandle.Alloc(result, GCHandleType.Pinned); return result; } + public float[] getVertexListAsFloatLocked() + { + if( m_pinnedVertexes.IsAllocated ) + return (float[])(m_pinnedVertexes.Target); + + float[] result = getVertexListAsFloat(); + m_pinnedVertexes = GCHandle.Alloc(result, GCHandleType.Pinned); + + return result; + } + + public void getVertexListAsPtrToFloatArray(out IntPtr vertices, out int vertexStride, out int vertexCount) + { + // A vertex is 3 floats + vertexStride = 3 * sizeof(float); + + // If there isn't an unmanaged array allocated yet, do it now + if (m_verticesPtr == IntPtr.Zero) + { + float[] vertexList = getVertexListAsFloat(); + // Each vertex is 3 elements (floats) + m_vertexCount = vertexList.Length / 3; + int byteCount = m_vertexCount * vertexStride; + m_verticesPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(byteCount); + System.Runtime.InteropServices.Marshal.Copy(vertexList, 0, m_verticesPtr, m_vertexCount * 3); + } + vertices = m_verticesPtr; + vertexCount = m_vertexCount; + } + public int[] getIndexListAsInt() { - int[] result; - - result = new int[triangles.Count * 3]; - for (int i = 0; i < triangles.Count; i++) + if (m_triangles == null) + throw new NotSupportedException(); + int[] result = new int[m_triangles.Count * 3]; + for (int i = 0; i < m_triangles.Count; i++) { - Triangle t = triangles[i]; - result[3 * i + 0] = vertices[t.v1]; - result[3 * i + 1] = vertices[t.v2]; - result[3 * i + 2] = vertices[t.v3]; + Triangle t = m_triangles[i]; + result[3 * i + 0] = m_vertices[t.v1]; + result[3 * i + 1] = m_vertices[t.v2]; + result[3 * i + 2] = m_vertices[t.v3]; } return result; } @@ -189,19 +218,48 @@ namespace OpenSim.Region.Physics.Meshing /// public int[] getIndexListAsIntLocked() { - if (pinnedIndex.IsAllocated) - return (int[])(pinnedIndex.Target); + if (m_pinnedIndex.IsAllocated) + return (int[])(m_pinnedIndex.Target); int[] result = getIndexListAsInt(); - pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned); + m_pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned); return result; } + public void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount) + { + // If there isn't an unmanaged array allocated yet, do it now + if (m_indicesPtr == IntPtr.Zero) + { + int[] indexList = getIndexListAsInt(); + m_indexCount = indexList.Length; + int byteCount = m_indexCount * sizeof(int); + m_indicesPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(byteCount); + System.Runtime.InteropServices.Marshal.Copy(indexList, 0, m_indicesPtr, m_indexCount); + } + // A triangle is 3 ints (indices) + triStride = 3 * sizeof(int); + indices = m_indicesPtr; + indexCount = m_indexCount; + } + public void releasePinned() { - pinnedVirtexes.Free(); - pinnedIndex.Free(); + if (m_pinnedVertexes.IsAllocated) + m_pinnedVertexes.Free(); + if (m_pinnedIndex.IsAllocated) + m_pinnedIndex.Free(); + if (m_verticesPtr != IntPtr.Zero) + { + System.Runtime.InteropServices.Marshal.FreeHGlobal(m_verticesPtr); + m_verticesPtr = IntPtr.Zero; + } + if (m_indicesPtr != IntPtr.Zero) + { + System.Runtime.InteropServices.Marshal.FreeHGlobal(m_indicesPtr); + m_indicesPtr = IntPtr.Zero; + } } /// @@ -209,29 +267,29 @@ namespace OpenSim.Region.Physics.Meshing /// public void releaseSourceMeshData() { - triangles = null; - vertices = null; + m_triangles = null; + m_vertices = null; } public void Append(IMesh newMesh) { - if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated) + if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) throw new NotSupportedException("Attempt to Append to a pinned Mesh"); if (!(newMesh is Mesh)) return; - foreach (Triangle t in ((Mesh)newMesh).triangles) + foreach (Triangle t in ((Mesh)newMesh).m_triangles) Add(t); } // Do a linear transformation of mesh. public void TransformLinear(float[,] matrix, float[] offset) { - if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated) + if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) throw new NotSupportedException("Attempt to TransformLinear a pinned Mesh"); - foreach (Vertex v in vertices.Keys) + foreach (Vertex v in m_vertices.Keys) { if (v == null) continue; @@ -252,7 +310,7 @@ namespace OpenSim.Region.Physics.Meshing String fileName = name + "_" + title + ".raw"; String completePath = Path.Combine(path, fileName); StreamWriter sw = new StreamWriter(completePath); - foreach (Triangle t in triangles) + foreach (Triangle t in m_triangles) { String s = t.ToStringRaw(); sw.WriteLine(s); @@ -262,7 +320,7 @@ namespace OpenSim.Region.Physics.Meshing public void TrimExcess() { - triangles.TrimExcess(); + m_triangles.TrimExcess(); } } } diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 0e29cccfa3..1ea08e250c 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -498,12 +498,9 @@ namespace OpenSim.Region.Physics.Meshing // If this mesh has been created already, return it instead of creating another copy // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory - if (! primShape.SculptEntry) - { - key = GetMeshKey(primShape, size, lod); - if (m_uniqueMeshes.TryGetValue(key, out mesh)) - return mesh; - } + key = GetMeshKey(primShape, size, lod); + if (m_uniqueMeshes.TryGetValue(key, out mesh)) + return mesh; if (size.X < 0.01f) size.X = 0.01f; if (size.Y < 0.01f) size.Y = 0.01f; @@ -525,10 +522,9 @@ namespace OpenSim.Region.Physics.Meshing // trim the vertex and triangle lists to free up memory mesh.TrimExcess(); - } - if (!primShape.SculptEntry) m_uniqueMeshes.Add(key, mesh); + } return mesh; } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 032b5dff6d..c04124327c 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -813,18 +813,17 @@ namespace OpenSim.Region.Physics.OdePlugin } } - float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory - int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage + IntPtr vertices, indices; + int vertexCount, indexCount; + int vertexStride, triStride; + mesh.getVertexListAsPtrToFloatArray( out vertices, out vertexStride, out vertexCount ); // Note, that vertices are fixed in unmanaged heap + mesh.getIndexListAsPtrToIntArray( out indices, out triStride, out indexCount ); // Also fixed, needs release after usage mesh.releaseSourceMeshData(); // free up the original mesh data to save memory - int VertexCount = vertexList.GetLength(0)/3; - int IndexCount = indexList.GetLength(0); - _triMeshData = d.GeomTriMeshDataCreate(); - d.GeomTriMeshDataBuildSimple(_triMeshData, vertexList, 3*sizeof (float), VertexCount, indexList, IndexCount, - 3*sizeof (int)); + d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); d.GeomTriMeshDataPreprocess(_triMeshData); _parent_scene.waitForSpaceUnlock(m_targetSpace); diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 0769c907ba..f5ab1de1e8 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -3476,7 +3476,7 @@ namespace OpenSim.Region.Physics.OdePlugin public override void UnCombine(PhysicsScene pScene) { IntPtr localGround = IntPtr.Zero; - float[] localHeightfield; + //float[] localHeightfield; bool proceed = false; List geomDestroyList = new List(); @@ -3771,16 +3771,13 @@ namespace OpenSim.Region.Physics.OdePlugin sides.Z = 0.5f; ds.DrawBox(ref pos, ref R, ref sides); - - } } } } public void start(int unused) - { - + { ds.SetViewpoint(ref xyz, ref hpr); } #endif diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs index 0964caaed7..9d9735e439 100644 --- a/OpenSim/Server/Base/ServerUtils.cs +++ b/OpenSim/Server/Base/ServerUtils.cs @@ -260,7 +260,7 @@ namespace OpenSim.Server.Base public static Dictionary ParseXmlResponse(string data) { - //m_log.DebugFormat("[XXX]: received xml string: {0}", data); + m_log.DebugFormat("[XXX]: received xml string: {0}", data); Dictionary ret = new Dictionary(); diff --git a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs index e22328dc66..433ed0b700 100644 --- a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs @@ -67,43 +67,50 @@ namespace OpenSim.Server.Handlers.Grid //m_log.DebugFormat("[XXX]: query String: {0}", body); - Dictionary request = - ServerUtils.ParseQueryString(body); - - if (!request.ContainsKey("METHOD")) - return FailureResult(); - - string method = request["METHOD"]; - - switch (method) + try { - case "register": - return Register(request); + Dictionary request = + ServerUtils.ParseQueryString(body); - case "deregister": - return Deregister(request); + if (!request.ContainsKey("METHOD")) + return FailureResult(); - case "get_neighbours": - return GetNeighbours(request); + string method = request["METHOD"]; - case "get_region_by_uuid": - return GetRegionByUUID(request); + switch (method) + { + case "register": + return Register(request); - case "get_region_by_position": - return GetRegionByPosition(request); + case "deregister": + return Deregister(request); - case "get_region_by_name": - return GetRegionByName(request); + case "get_neighbours": + return GetNeighbours(request); - case "get_regions_by_name": - return GetRegionsByName(request); + case "get_region_by_uuid": + return GetRegionByUUID(request); - case "get_region_range": - return GetRegionRange(request); + case "get_region_by_position": + return GetRegionByPosition(request); + case "get_region_by_name": + return GetRegionByName(request); + + case "get_regions_by_name": + return GetRegionsByName(request); + + case "get_region_range": + return GetRegionRange(request); + + } + m_log.DebugFormat("[GRID HANDLER]: unknown method {0} request {1}", method.Length, method); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID HANDLER]: Exception {0}", e); } - m_log.DebugFormat("[GRID HANDLER]: unknown method {0} request {1}", method.Length, method); return FailureResult(); } @@ -113,7 +120,7 @@ namespace OpenSim.Server.Handlers.Grid byte[] Register(Dictionary request) { UUID scopeID = UUID.Zero; - if (request["SCOPEID"] != null) + if (request.ContainsKey("SCOPEID")) UUID.TryParse(request["SCOPEID"], out scopeID); else m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to register region"); @@ -137,11 +144,21 @@ namespace OpenSim.Server.Handlers.Grid } Dictionary rinfoData = new Dictionary(); - foreach (KeyValuePair kvp in request) - rinfoData[kvp.Key] = kvp.Value; - GridRegion rinfo = new GridRegion(rinfoData); + GridRegion rinfo = null; + try + { + foreach (KeyValuePair kvp in request) + rinfoData[kvp.Key] = kvp.Value; + rinfo = new GridRegion(rinfoData); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID HANDLER]: exception unpacking region data: {0}", e); + } - bool result = m_GridService.RegisterRegion(scopeID, rinfo); + bool result = false; + if (rinfo != null) + result = m_GridService.RegisterRegion(scopeID, rinfo); if (result) return SuccessResult(); diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs index b1d41daf1e..6f7c90faa9 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs @@ -171,6 +171,8 @@ namespace OpenSim.Services.Connectors if (asset == null) { + bool result = false; + AsynchronousRestObjectRequester. MakeRequest("GET", uri, 0, delegate(AssetBase a) @@ -178,8 +180,10 @@ namespace OpenSim.Services.Connectors if (m_Cache != null) m_Cache.Cache(a); handler(id, sender, a); + result = true; }); + return result; } else { diff --git a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs index ba46b0d71f..acdf5587de 100644 --- a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs +++ b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs @@ -109,8 +109,13 @@ namespace OpenSim.Services.Connectors { Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - if ((replyData["Result"] != null) && (replyData["Result"].ToString().ToLower() == "success")) + if (replyData.ContainsKey("Result")&& (replyData["Result"].ToString().ToLower() == "success")) return true; + else if (!replyData.ContainsKey("Result")) + m_log.DebugFormat("[GRID CONNECTOR]: reply data does not contain result field"); + else + m_log.DebugFormat("[GRID CONNECTOR]: unexpected result {0}", replyData["Result"].ToString()); + } else m_log.DebugFormat("[GRID CONNECTOR]: RegisterRegion received null reply"); diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index 991acf23ee..a2e4771d4b 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -69,18 +69,40 @@ namespace OpenSim.Services.GridService ((region.posX != regionInfos.RegionLocX) || (region.posY != regionInfos.RegionLocY))) { // Region reregistering in other coordinates. Delete the old entry - m_Database.Delete(regionInfos.RegionID); + m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) was previously registered at {2}-{3}. Deleting old entry.", + regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY); + + try + { + m_Database.Delete(regionInfos.RegionID); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e); + } } // Everything is ok, let's register RegionData rdata = RegionInfo2RegionData(regionInfos); rdata.ScopeID = scopeID; - m_Database.Store(rdata); + try + { + m_Database.Store(rdata); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e); + } + + m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) registered successfully at {2}-{3}", + regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY); + return true; } public bool DeregisterRegion(UUID regionID) { + m_log.DebugFormat("[GRID SERVICE]: Region {0} deregistered", regionID); return m_Database.Delete(regionID); } diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index fa8dc9db26..5cb51b28d9 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -312,7 +312,7 @@ ; Uncomment below to enable llRemoteData/remote channels ; remoteDataPort = 20800 - grid_server_url = "http://127.0.0.1:8001" + grid_server_url = "http://127.0.0.1:8003" grid_send_key = "null" grid_recv_key = "null" @@ -322,7 +322,7 @@ asset_server_url = "http://127.0.0.1:8003" - inventory_server_url = "http://127.0.0.1:8004" + inventory_server_url = "http://127.0.0.1:8003" ; The MessagingServer is a companion of the UserServer. It uses ; user_send_key and user_recv_key, too diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index 6607a1a369..3bc9b6ccdb 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -13,13 +13,13 @@ ; ; change this to your grid-wide inventory server ; - InventoryServerURI = "http://myinventoryserver.com:8004" + InventoryServerURI = "http://myinventoryserver.com:8003" [GridService] ; ; change this to your grid-wide grid server ; - GridServerURI = "http://mygridserver.com:8001" + GridServerURI = "http://mygridserver.com:8003" [Modules] ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists.