From 90a4d4f9f93eda3d707292c9619aecc765edada8 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 16 Sep 2009 17:52:16 +0100 Subject: [PATCH 01/10] Adding the MySQL RegionData service. --- OpenSim/Data/IRegionData.cs | 2 +- OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 1594 +++++++++++++++++ OpenSim/Data/MySQL/MySQLRegionData.cs | 1743 +++---------------- 3 files changed, 1803 insertions(+), 1536 deletions(-) create mode 100644 OpenSim/Data/MySQL/MySQLLegacyRegionData.cs diff --git a/OpenSim/Data/IRegionData.cs b/OpenSim/Data/IRegionData.cs index 988bdf8f33..71dd525729 100644 --- a/OpenSim/Data/IRegionData.cs +++ b/OpenSim/Data/IRegionData.cs @@ -48,7 +48,7 @@ namespace OpenSim.Data public interface IRegionData { RegionData Get(UUID regionID, UUID ScopeID); - RegionData Get(string regionName, UUID ScopeID); + List Get(string regionName, UUID ScopeID); RegionData Get(int x, int y, UUID ScopeID); List Get(int xStart, int yStart, int xEnd, int yEnd, UUID ScopeID); diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs new file mode 100644 index 0000000000..4a16a702c4 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs @@ -0,0 +1,1594 @@ +/* + * 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.Drawing; +using System.IO; +using System.Reflection; +using System.Threading; +using log4net; +using MySql.Data.MySqlClient; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Data.MySQL +{ + /// + /// A MySQL Interface for the Region Server + /// + public class MySQLDataStore : IRegionDataStore + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ConnectionString; + + private MySqlConnection m_Connection = null; + + public void Initialise(string connectionString) + { + m_ConnectionString = connectionString; + + m_Connection = new MySqlConnection(m_ConnectionString); + + m_Connection.Open(); + + // Apply new Migrations + // + Assembly assem = GetType().Assembly; + Migration m = new Migration(m_Connection, assem, "RegionStore"); + m.Update(); + + // Clean dropped attachments + // + MySqlCommand cmd = m_Connection.CreateCommand(); + cmd.CommandText = "delete from prims, primshapes using prims " + + "left join primshapes on prims.uuid = primshapes.uuid " + + "where PCode = 9 and State <> 0"; + ExecuteNonQuery(cmd); + cmd.Dispose(); + } + + private IDataReader ExecuteReader(MySqlCommand c) + { + IDataReader r = null; + bool errorSeen = false; + + while (true) + { + try + { + r = c.ExecuteReader(); + } + catch (Exception) + { + Thread.Sleep(500); + + m_Connection.Close(); + m_Connection = (MySqlConnection) ((ICloneable)m_Connection).Clone(); + m_Connection.Open(); + c.Connection = m_Connection; + + if (!errorSeen) + { + errorSeen = true; + continue; + } + throw; + } + + break; + } + + return r; + } + + private void ExecuteNonQuery(MySqlCommand c) + { + bool errorSeen = false; + + while (true) + { + try + { + c.ExecuteNonQuery(); + } + catch (Exception) + { + Thread.Sleep(500); + + m_Connection.Close(); + m_Connection = (MySqlConnection) ((ICloneable)m_Connection).Clone(); + m_Connection.Open(); + c.Connection = m_Connection; + + if (!errorSeen) + { + errorSeen = true; + continue; + } + throw; + } + + break; + } + } + + public void Dispose() {} + + public void StoreObject(SceneObjectGroup obj, UUID regionUUID) + { + uint flags = obj.RootPart.GetEffectiveObjectFlags(); + + // Eligibility check + // + if ((flags & (uint)PrimFlags.Temporary) != 0) + return; + if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0) + return; + + lock (m_Connection) + { + MySqlCommand cmd = m_Connection.CreateCommand(); + + foreach (SceneObjectPart prim in obj.Children.Values) + { + cmd.Parameters.Clear(); + + cmd.CommandText = "replace into prims ("+ + "UUID, CreationDate, "+ + "Name, Text, Description, "+ + "SitName, TouchName, ObjectFlags, "+ + "OwnerMask, NextOwnerMask, GroupMask, "+ + "EveryoneMask, BaseMask, PositionX, "+ + "PositionY, PositionZ, GroupPositionX, "+ + "GroupPositionY, GroupPositionZ, VelocityX, "+ + "VelocityY, VelocityZ, AngularVelocityX, "+ + "AngularVelocityY, AngularVelocityZ, "+ + "AccelerationX, AccelerationY, "+ + "AccelerationZ, RotationX, "+ + "RotationY, RotationZ, "+ + "RotationW, SitTargetOffsetX, "+ + "SitTargetOffsetY, SitTargetOffsetZ, "+ + "SitTargetOrientW, SitTargetOrientX, "+ + "SitTargetOrientY, SitTargetOrientZ, "+ + "RegionUUID, CreatorID, "+ + "OwnerID, GroupID, "+ + "LastOwnerID, SceneGroupID, "+ + "PayPrice, PayButton1, "+ + "PayButton2, PayButton3, "+ + "PayButton4, LoopedSound, "+ + "LoopedSoundGain, TextureAnimation, "+ + "OmegaX, OmegaY, OmegaZ, "+ + "CameraEyeOffsetX, CameraEyeOffsetY, "+ + "CameraEyeOffsetZ, CameraAtOffsetX, "+ + "CameraAtOffsetY, CameraAtOffsetZ, "+ + "ForceMouselook, ScriptAccessPin, "+ + "AllowedDrop, DieAtEdge, "+ + "SalePrice, SaleType, "+ + "ColorR, ColorG, ColorB, ColorA, "+ + "ParticleSystem, ClickAction, Material, "+ + "CollisionSound, CollisionSoundVolume, "+ + "PassTouches, "+ + "LinkNumber) 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)"; + + FillPrimCommand(cmd, prim, obj.UUID, regionUUID); + + ExecuteNonQuery(cmd); + + cmd.Parameters.Clear(); + + cmd.CommandText = "replace into primshapes ("+ + "UUID, Shape, ScaleX, ScaleY, "+ + "ScaleZ, PCode, PathBegin, PathEnd, "+ + "PathScaleX, PathScaleY, PathShearX, "+ + "PathShearY, PathSkew, PathCurve, "+ + "PathRadiusOffset, PathRevolutions, "+ + "PathTaperX, PathTaperY, PathTwist, "+ + "PathTwistBegin, ProfileBegin, ProfileEnd, "+ + "ProfileCurve, ProfileHollow, Texture, "+ + "ExtraParams, State) 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)"; + + FillShapeCommand(cmd, prim); + + ExecuteNonQuery(cmd); + } + cmd.Dispose(); + } + } + + public void RemoveObject(UUID obj, UUID regionUUID) + { + // Formerly, this used to check the region UUID. + // That makes no sense, as we remove the contents of a prim + // unconditionally, but the prim dependent on the region ID. + // So, we would destroy an object and cause hard to detect + // issues if we delete the contents only. Deleting it all may + // cause the loss of a prim, but is cleaner. + // It's also faster because it uses the primary key. + // + lock (m_Connection) + { + MySqlCommand cmd = m_Connection.CreateCommand(); + + cmd.CommandText = "select UUID from prims where "+ + "SceneGroupID= ?UUID"; + + cmd.Parameters.AddWithValue("UUID", obj.ToString()); + + List uuids = new List(); + + IDataReader reader = ExecuteReader(cmd); + + try + { + while (reader.Read()) + { + uuids.Add(new UUID(reader["UUID"].ToString())); + } + } + finally + { + reader.Close(); + } + + // delete the main prims + cmd.CommandText = "delete from prims where SceneGroupID= ?UUID"; + ExecuteNonQuery(cmd); + cmd.Dispose(); + + // there is no way this should be < 1 unless there is + // a very corrupt database, but in that case be extra + // safe anyway. + if (uuids.Count > 0) + { + RemoveShapes(uuids); + RemoveItems(uuids); + } + } + } + + /// + /// Remove all persisted items of the given prim. + /// The caller must acquire the necessrary synchronization locks + /// + /// the Item UUID + private void RemoveItems(UUID uuid) + { + lock (m_Connection) + { + MySqlCommand cmd = m_Connection.CreateCommand(); + + cmd.CommandText = "delete from primitems where " + + "PrimID = ?PrimID"; + + cmd.Parameters.AddWithValue("PrimID", uuid.ToString()); + + ExecuteNonQuery(cmd); + cmd.Dispose(); + } + } + + + /// + /// Remove all persisted shapes for a list of prims + /// The caller must acquire the necessrary synchronization locks + /// + /// the list of UUIDs + private void RemoveShapes(List uuids) + { + lock (m_Connection) + { + string sql = "delete from primshapes where "; + MySqlCommand cmd = m_Connection.CreateCommand(); + + for (int i = 0; i < uuids.Count; i++) + { + if ((i + 1) == uuids.Count) + {// end of the list + sql += "(UUID = ?UUID" + i + ")"; + } + else + { + sql += "(UUID = ?UUID" + i + ") or "; + } + } + cmd.CommandText = sql; + + for (int i = 0; i < uuids.Count; i++) + { + cmd.Parameters.AddWithValue("UUID" + i, uuids[i].ToString()); + } + + ExecuteNonQuery(cmd); + cmd.Dispose(); + } + } + + /// + /// Remove all persisted items for a list of prims + /// The caller must acquire the necessrary synchronization locks + /// + /// the list of UUIDs + private void RemoveItems(List uuids) + { + lock (m_Connection) + { + string sql = "delete from primitems where "; + MySqlCommand cmd = m_Connection.CreateCommand(); + + for (int i = 0; i < uuids.Count; i++) + { + if ((i + 1) == uuids.Count) + {// end of the list + sql += "(PrimID = ?PrimID" + i + ")"; + } + else + { + sql += "(PrimID = ?PrimID" + i + ") or "; + } + } + cmd.CommandText = sql; + + for (int i = 0; i < uuids.Count; i++) + { + cmd.Parameters.AddWithValue("PrimID" + i, uuids[i].ToString()); + } + + ExecuteNonQuery(cmd); + cmd.Dispose(); + } + } + + public List LoadObjects(UUID regionUUID) + { + UUID lastGroupID = UUID.Zero; + Dictionary objects = new Dictionary(); + Dictionary prims = new Dictionary(); + SceneObjectGroup grp = null; + + lock (m_Connection) + { + MySqlCommand cmd = m_Connection.CreateCommand(); + + cmd.CommandText = "select *, " + + "case when prims.UUID = SceneGroupID " + + "then 0 else 1 end as sort from prims " + + "left join primshapes on prims.UUID = primshapes.UUID "+ + "where RegionUUID = ?RegionUUID " + + "order by SceneGroupID asc, sort asc, LinkNumber asc"; + + cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); + + IDataReader reader = ExecuteReader(cmd); + + try + { + while (reader.Read()) + { + SceneObjectPart prim = BuildPrim(reader); + if (reader["Shape"] is DBNull) + prim.Shape = PrimitiveBaseShape.Default; + else + prim.Shape = BuildShape(reader); + + prims[prim.UUID] = prim; + + UUID groupID = new UUID(reader["SceneGroupID"].ToString()); + + 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 (prim.UUID != groupID && groupID != UUID.Zero) + { + m_log.WarnFormat( + "[REGION DB]: Found root prim {0} {1} at {2} where group was actually {3}. Forcing UUID to group UUID", + prim.Name, prim.UUID, prim.GroupPosition, groupID); + + prim.UUID = groupID; + } + + grp = new SceneObjectGroup(prim); + } + else + { + // Black magic to preserve link numbers + // + int link = prim.LinkNum; + + grp.AddPart(prim); + + if (link != 0) + prim.LinkNum = link; + } + } + } + finally + { + reader.Close(); + } + + if (grp != null) + objects[grp.UUID] = grp; + cmd.Dispose(); + } + + // 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(); + lock (m_Connection) + { + MySqlCommand itemCmd = m_Connection.CreateCommand(); + itemCmd.CommandText = "select distinct primID from primitems"; + IDataReader itemReader = ExecuteReader(itemCmd); + try + { + while (itemReader.Read()) + { + if (!(itemReader["primID"] is DBNull)) + { + UUID primID = new UUID(itemReader["primID"].ToString()); + if (prims.ContainsKey(primID)) + { + primsWithInventory.Add(prims[primID]); + } + } + } + } + finally + { + itemReader.Close(); + } + itemCmd.Dispose(); + } + + foreach (SceneObjectPart prim in primsWithInventory) + { + LoadItems(prim); + } + m_log.DebugFormat("[REGION DB]: Loaded {0} objects using {1} prims", objects.Count, prims.Count); + return new List(objects.Values); + } + + /// + /// Load in a prim's persisted inventory. + /// + /// The prim + private void LoadItems(SceneObjectPart prim) + { + lock (m_Connection) + { + MySqlCommand cmd = m_Connection.CreateCommand(); + + cmd.CommandText = "select * from primitems where "+ + "PrimID = ?PrimID"; + + cmd.Parameters.AddWithValue("PrimID", prim.UUID.ToString()); + + IDataReader reader = ExecuteReader(cmd); + List inventory = + new List(); + + try + { + while (reader.Read()) + { + TaskInventoryItem item = BuildItem(reader); + + item.ParentID = prim.UUID; // Values in database are + // often wrong + inventory.Add(item); + } + } + finally + { + reader.Close(); + } + + cmd.Dispose(); + prim.Inventory.RestoreInventoryItems(inventory); + } + } + + public void StoreTerrain(double[,] ter, UUID regionID) + { + m_log.Info("[REGION DB]: Storing terrain"); + + lock (m_Connection) + { + MySqlCommand cmd = m_Connection.CreateCommand(); + + cmd.CommandText = "delete from terrain where " + + "RegionUUID = ?RegionUUID"; + cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + + ExecuteNonQuery(cmd); + + cmd.CommandText = "insert into terrain (RegionUUID, " + + "Revision, Heightfield) values (?RegionUUID, " + + "1, ?Heightfield)"; + + cmd.Parameters.AddWithValue("Heightfield", + SerializeTerrain(ter)); + + ExecuteNonQuery(cmd); + cmd.Dispose(); + } + } + + public double[,] LoadTerrain(UUID regionID) + { + double[,] terrain = null; + + lock (m_Connection) + { + MySqlCommand cmd = m_Connection.CreateCommand(); + cmd.CommandText = "select RegionUUID, Revision, Heightfield " + + "from terrain where RegionUUID = ?RegionUUID "+ + "order by Revision desc limit 1"; + cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + + IDataReader reader = ExecuteReader(cmd); + + try + { + while (reader.Read()) + { + terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; + terrain.Initialize(); + + MemoryStream mstr = new MemoryStream((byte[]) reader["Heightfield"]); + int rev = 0; + + BinaryReader br = new BinaryReader(mstr); + for (int x = 0; x < (int)Constants.RegionSize; x++) + { + for (int y = 0; y < (int)Constants.RegionSize; y++) + { + terrain[x, y] = br.ReadDouble(); + } + rev = Convert.ToInt32(reader["Revision"]); + } + m_log.InfoFormat("[REGION DB]: Loaded terrain " + + "revision r{0}", rev); + } + } + finally + { + reader.Close(); + } + cmd.Dispose(); + } + + return terrain; + } + + public void RemoveLandObject(UUID globalID) + { + lock (m_Connection) + { + MySqlCommand cmd = m_Connection.CreateCommand(); + + cmd.CommandText = "delete from land where UUID = ?UUID"; + + cmd.Parameters.AddWithValue("UUID", globalID.ToString()); + + ExecuteNonQuery(cmd); + cmd.Dispose(); + } + } + + public void StoreLandObject(ILandObject parcel) + { + lock (m_Connection) + { + MySqlCommand cmd = m_Connection.CreateCommand(); + + cmd.CommandText = "replace 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)"; + + FillLandCommand(cmd, parcel.landData, parcel.regionUUID); + + ExecuteNonQuery(cmd); + + cmd.CommandText = "delete from landaccesslist where " + + "LandUUID = ?UUID"; + + ExecuteNonQuery(cmd); + + cmd.Parameters.Clear(); + cmd.CommandText = "insert into landaccesslist (LandUUID, " + + "AccessUUID, Flags) values (?LandUUID, ?AccessUUID, " + + "?Flags)"; + + foreach (ParcelManager.ParcelAccessEntry entry in + parcel.landData.ParcelAccessList) + { + FillLandAccessCommand(cmd, entry, parcel.landData.GlobalID); + ExecuteNonQuery(cmd); + cmd.Parameters.Clear(); + } + cmd.Dispose(); + } + } + + public RegionSettings LoadRegionSettings(UUID regionUUID) + { + RegionSettings rs = null; + + lock (m_Connection) + { + MySqlCommand cmd = m_Connection.CreateCommand(); + + cmd.CommandText = "select * from regionsettings where " + + "regionUUID = ?RegionUUID"; + cmd.Parameters.AddWithValue("regionUUID", regionUUID); + + IDataReader reader = ExecuteReader(cmd); + + try + { + if (reader.Read()) + { + rs = BuildRegionSettings(reader); + rs.OnSave += StoreRegionSettings; + } + else + { + rs = new RegionSettings(); + rs.RegionUUID = regionUUID; + rs.OnSave += StoreRegionSettings; + + StoreRegionSettings(rs); + } + } + finally + { + reader.Close(); + } + cmd.Dispose(); + } + + return rs; + } + + public void StoreRegionSettings(RegionSettings rs) + { + lock (m_Connection) + { + MySqlCommand cmd = m_Connection.CreateCommand(); + + cmd.CommandText = "replace 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, Sandbox, sunvectorx, sunvectory, " + + "sunvectorz, loaded_creation_datetime, " + + "loaded_creation_id) values ( ?RegionUUID, ?BlockTerraform, " + + "?BlockFly, ?AllowDamage, ?RestrictPushing, " + + "?AllowLandResell, ?AllowLandJoinDivide, " + + "?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " + + "?Maturity, ?DisableScripts, ?DisableCollisions, " + + "?DisablePhysics, ?TerrainTexture1, " + + "?TerrainTexture2, ?TerrainTexture3, " + + "?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " + + "?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " + + "?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " + + "?WaterHeight, ?TerrainRaiseLimit, " + + "?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " + + "?SunPosition, ?Covenant, ?Sandbox, " + + "?SunVectorX, ?SunVectorY, ?SunVectorZ, " + + "?LoadedCreationDateTime, ?LoadedCreationID)"; + + FillRegionSettingsCommand(cmd, rs); + + ExecuteNonQuery(cmd); + cmd.Dispose(); + + } + } + + public List LoadLandObjects(UUID regionUUID) + { + List landData = new List(); + + lock (m_Connection) + { + MySqlCommand cmd = m_Connection.CreateCommand(); + + cmd.CommandText = "select * from land where " + + "RegionUUID = ?RegionUUID"; + + cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); + + IDataReader reader = ExecuteReader(cmd); + + try + { + while (reader.Read()) + { + LandData newLand = BuildLandData(reader); + landData.Add(newLand); + } + } + finally + { + reader.Close(); + } + + foreach (LandData land in landData) + { + cmd.Parameters.Clear(); + + cmd.CommandText = "select * from landaccesslist " + + "where LandUUID = ?LandUUID"; + + cmd.Parameters.AddWithValue("LandUUID", land.GlobalID.ToString()); + + reader = ExecuteReader(cmd); + + try + { + while (reader.Read()) + { + land.ParcelAccessList.Add(BuildLandAccessData(reader)); + } + } + finally + { + reader.Close(); + } + } + cmd.Dispose(); + } + + return landData; + } + + public void Shutdown() + { + } + + private SceneObjectPart BuildPrim(IDataReader row) + { + SceneObjectPart prim = new SceneObjectPart(); + prim.UUID = new UUID((String) row["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(row["CreationDate"]); + if (row["Name"] != DBNull.Value) + prim.Name = (String)row["Name"]; + else + prim.Name = string.Empty; + // various text fields + prim.Text = (String) row["Text"]; + prim.Color = Color.FromArgb(Convert.ToInt32(row["ColorA"]), + Convert.ToInt32(row["ColorR"]), + Convert.ToInt32(row["ColorG"]), + Convert.ToInt32(row["ColorB"])); + prim.Description = (String) row["Description"]; + prim.SitName = (String) row["SitName"]; + prim.TouchName = (String) row["TouchName"]; + // permissions + prim.ObjectFlags = Convert.ToUInt32(row["ObjectFlags"]); + prim.CreatorID = new UUID((String) row["CreatorID"]); + prim.OwnerID = new UUID((String) row["OwnerID"]); + prim.GroupID = new UUID((String) row["GroupID"]); + prim.LastOwnerID = new UUID((String) row["LastOwnerID"]); + prim.OwnerMask = Convert.ToUInt32(row["OwnerMask"]); + prim.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]); + prim.GroupMask = Convert.ToUInt32(row["GroupMask"]); + prim.EveryoneMask = Convert.ToUInt32(row["EveryoneMask"]); + prim.BaseMask = Convert.ToUInt32(row["BaseMask"]); + // vectors + prim.OffsetPosition = new Vector3( + Convert.ToSingle(row["PositionX"]), + Convert.ToSingle(row["PositionY"]), + Convert.ToSingle(row["PositionZ"]) + ); + prim.GroupPosition = new Vector3( + Convert.ToSingle(row["GroupPositionX"]), + Convert.ToSingle(row["GroupPositionY"]), + Convert.ToSingle(row["GroupPositionZ"]) + ); + prim.Velocity = new Vector3( + Convert.ToSingle(row["VelocityX"]), + Convert.ToSingle(row["VelocityY"]), + Convert.ToSingle(row["VelocityZ"]) + ); + prim.AngularVelocity = new Vector3( + Convert.ToSingle(row["AngularVelocityX"]), + Convert.ToSingle(row["AngularVelocityY"]), + Convert.ToSingle(row["AngularVelocityZ"]) + ); + prim.Acceleration = new Vector3( + Convert.ToSingle(row["AccelerationX"]), + Convert.ToSingle(row["AccelerationY"]), + Convert.ToSingle(row["AccelerationZ"]) + ); + // quaternions + prim.RotationOffset = new Quaternion( + Convert.ToSingle(row["RotationX"]), + Convert.ToSingle(row["RotationY"]), + Convert.ToSingle(row["RotationZ"]), + Convert.ToSingle(row["RotationW"]) + ); + prim.SitTargetPositionLL = new Vector3( + Convert.ToSingle(row["SitTargetOffsetX"]), + Convert.ToSingle(row["SitTargetOffsetY"]), + Convert.ToSingle(row["SitTargetOffsetZ"]) + ); + prim.SitTargetOrientationLL = new Quaternion( + Convert.ToSingle(row["SitTargetOrientX"]), + Convert.ToSingle(row["SitTargetOrientY"]), + Convert.ToSingle(row["SitTargetOrientZ"]), + Convert.ToSingle(row["SitTargetOrientW"]) + ); + + prim.PayPrice[0] = Convert.ToInt32(row["PayPrice"]); + prim.PayPrice[1] = Convert.ToInt32(row["PayButton1"]); + prim.PayPrice[2] = Convert.ToInt32(row["PayButton2"]); + prim.PayPrice[3] = Convert.ToInt32(row["PayButton3"]); + prim.PayPrice[4] = Convert.ToInt32(row["PayButton4"]); + + prim.Sound = new UUID(row["LoopedSound"].ToString()); + prim.SoundGain = Convert.ToSingle(row["LoopedSoundGain"]); + prim.SoundFlags = 1; // If it's persisted at all, it's looped + + if (!(row["TextureAnimation"] is DBNull)) + prim.TextureAnimation = (Byte[])row["TextureAnimation"]; + if (!(row["ParticleSystem"] is DBNull)) + prim.ParticleSystem = (Byte[])row["ParticleSystem"]; + + prim.RotationalVelocity = new Vector3( + Convert.ToSingle(row["OmegaX"]), + Convert.ToSingle(row["OmegaY"]), + Convert.ToSingle(row["OmegaZ"]) + ); + + prim.SetCameraEyeOffset(new Vector3( + Convert.ToSingle(row["CameraEyeOffsetX"]), + Convert.ToSingle(row["CameraEyeOffsetY"]), + Convert.ToSingle(row["CameraEyeOffsetZ"]) + )); + + prim.SetCameraAtOffset(new Vector3( + Convert.ToSingle(row["CameraAtOffsetX"]), + Convert.ToSingle(row["CameraAtOffsetY"]), + Convert.ToSingle(row["CameraAtOffsetZ"]) + )); + + if (Convert.ToInt16(row["ForceMouselook"]) != 0) + prim.SetForceMouselook(true); + + prim.ScriptAccessPin = Convert.ToInt32(row["ScriptAccessPin"]); + + if (Convert.ToInt16(row["AllowedDrop"]) != 0) + prim.AllowedDrop = true; + + if (Convert.ToInt16(row["DieAtEdge"]) != 0) + prim.DIE_AT_EDGE = true; + + prim.SalePrice = Convert.ToInt32(row["SalePrice"]); + prim.ObjectSaleType = unchecked((byte)Convert.ToSByte(row["SaleType"])); + + prim.Material = unchecked((byte)Convert.ToSByte(row["Material"])); + + if (!(row["ClickAction"] is DBNull)) + prim.ClickAction = unchecked((byte)Convert.ToSByte(row["ClickAction"])); + + prim.CollisionSound = new UUID(row["CollisionSound"].ToString()); + prim.CollisionSoundVolume = Convert.ToSingle(row["CollisionSoundVolume"]); + + if (Convert.ToInt16(row["PassTouches"]) != 0) + prim.PassTouches = true; + prim.LinkNum = Convert.ToInt32(row["LinkNumber"]); + + return prim; + } + + + /// + /// Build a prim inventory item from the persisted data. + /// + /// + /// + private static TaskInventoryItem BuildItem(IDataReader row) + { + TaskInventoryItem taskItem = new TaskInventoryItem(); + + taskItem.ItemID = new UUID((String)row["itemID"]); + taskItem.ParentPartID = new UUID((String)row["primID"]); + taskItem.AssetID = new UUID((String)row["assetID"]); + taskItem.ParentID = new UUID((String)row["parentFolderID"]); + + taskItem.InvType = Convert.ToInt32(row["invType"]); + taskItem.Type = Convert.ToInt32(row["assetType"]); + + taskItem.Name = (String)row["name"]; + taskItem.Description = (String)row["description"]; + taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]); + taskItem.CreatorID = new UUID((String)row["creatorID"]); + taskItem.OwnerID = new UUID((String)row["ownerID"]); + taskItem.LastOwnerID = new UUID((String)row["lastOwnerID"]); + taskItem.GroupID = new UUID((String)row["groupID"]); + + taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]); + taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]); + taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]); + taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]); + taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]); + taskItem.Flags = Convert.ToUInt32(row["flags"]); + + return taskItem; + } + + private static RegionSettings BuildRegionSettings(IDataReader row) + { + RegionSettings newSettings = new RegionSettings(); + + newSettings.RegionUUID = new UUID((string) 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((String) row["terrain_texture_1"]); + newSettings.TerrainTexture2 = new UUID((String) row["terrain_texture_2"]); + newSettings.TerrainTexture3 = new UUID((String) row["terrain_texture_3"]); + newSettings.TerrainTexture4 = new UUID((String) 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.SunVector = new Vector3 ( + Convert.ToSingle(row["sunvectorx"]), + Convert.ToSingle(row["sunvectory"]), + Convert.ToSingle(row["sunvectorz"]) + ); + newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]); + newSettings.SunPosition = Convert.ToDouble(row["sun_position"]); + newSettings.Covenant = new UUID((String) 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; + } + + /// + /// + /// + /// + /// + private static LandData BuildLandData(IDataReader row) + { + LandData newData = new LandData(); + + newData.GlobalID = new UUID((String) 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((String)row["OwnerUUID"]); + newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); + newData.Area = Convert.ToInt32(row["Area"]); + newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unimplemented + 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((String) 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((String) 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.Zero; + UUID snapshotID = UUID.Zero; + + UUID.TryParse((string)row["AuthBuyerID"], out authedbuyer); + UUID.TryParse((string)row["SnapshotUUID"], out snapshotID); + newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]); + newData.Dwell = Convert.ToInt32(row["Dwell"]); + + newData.AuthBuyerID = authedbuyer; + newData.SnapshotID = snapshotID; + 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; + m_log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name); + } + + newData.ParcelAccessList = new List(); + + return newData; + } + + /// + /// + /// + /// + /// + private static ParcelManager.ParcelAccessEntry BuildLandAccessData(IDataReader row) + { + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = new UUID((string) row["AccessUUID"]); + entry.Flags = (AccessList) Convert.ToInt32(row["Flags"]); + entry.Time = new DateTime(); + return entry; + } + + /// + /// + /// + /// + /// + 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(); + } + + /// + /// Fill the prim command with prim values + /// + /// + /// + /// + /// + private void FillPrimCommand(MySqlCommand cmd, SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) + { + cmd.Parameters.AddWithValue("UUID", prim.UUID.ToString()); + cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); + cmd.Parameters.AddWithValue("CreationDate", prim.CreationDate); + cmd.Parameters.AddWithValue("Name", prim.Name); + cmd.Parameters.AddWithValue("SceneGroupID", sceneGroupID.ToString()); + // the UUID of the root part for this SceneObjectGroup + // various text fields + cmd.Parameters.AddWithValue("Text", prim.Text); + cmd.Parameters.AddWithValue("ColorR", prim.Color.R); + cmd.Parameters.AddWithValue("ColorG", prim.Color.G); + cmd.Parameters.AddWithValue("ColorB", prim.Color.B); + cmd.Parameters.AddWithValue("ColorA", prim.Color.A); + cmd.Parameters.AddWithValue("Description", prim.Description); + cmd.Parameters.AddWithValue("SitName", prim.SitName); + cmd.Parameters.AddWithValue("TouchName", prim.TouchName); + // permissions + cmd.Parameters.AddWithValue("ObjectFlags", prim.ObjectFlags); + cmd.Parameters.AddWithValue("CreatorID", prim.CreatorID.ToString()); + cmd.Parameters.AddWithValue("OwnerID", prim.OwnerID.ToString()); + cmd.Parameters.AddWithValue("GroupID", prim.GroupID.ToString()); + cmd.Parameters.AddWithValue("LastOwnerID", prim.LastOwnerID.ToString()); + cmd.Parameters.AddWithValue("OwnerMask", prim.OwnerMask); + cmd.Parameters.AddWithValue("NextOwnerMask", prim.NextOwnerMask); + cmd.Parameters.AddWithValue("GroupMask", prim.GroupMask); + cmd.Parameters.AddWithValue("EveryoneMask", prim.EveryoneMask); + cmd.Parameters.AddWithValue("BaseMask", prim.BaseMask); + // vectors + cmd.Parameters.AddWithValue("PositionX", (double)prim.OffsetPosition.X); + cmd.Parameters.AddWithValue("PositionY", (double)prim.OffsetPosition.Y); + cmd.Parameters.AddWithValue("PositionZ", (double)prim.OffsetPosition.Z); + cmd.Parameters.AddWithValue("GroupPositionX", (double)prim.GroupPosition.X); + cmd.Parameters.AddWithValue("GroupPositionY", (double)prim.GroupPosition.Y); + cmd.Parameters.AddWithValue("GroupPositionZ", (double)prim.GroupPosition.Z); + cmd.Parameters.AddWithValue("VelocityX", (double)prim.Velocity.X); + cmd.Parameters.AddWithValue("VelocityY", (double)prim.Velocity.Y); + cmd.Parameters.AddWithValue("VelocityZ", (double)prim.Velocity.Z); + cmd.Parameters.AddWithValue("AngularVelocityX", (double)prim.AngularVelocity.X); + cmd.Parameters.AddWithValue("AngularVelocityY", (double)prim.AngularVelocity.Y); + cmd.Parameters.AddWithValue("AngularVelocityZ", (double)prim.AngularVelocity.Z); + cmd.Parameters.AddWithValue("AccelerationX", (double)prim.Acceleration.X); + cmd.Parameters.AddWithValue("AccelerationY", (double)prim.Acceleration.Y); + cmd.Parameters.AddWithValue("AccelerationZ", (double)prim.Acceleration.Z); + // quaternions + cmd.Parameters.AddWithValue("RotationX", (double)prim.RotationOffset.X); + cmd.Parameters.AddWithValue("RotationY", (double)prim.RotationOffset.Y); + cmd.Parameters.AddWithValue("RotationZ", (double)prim.RotationOffset.Z); + cmd.Parameters.AddWithValue("RotationW", (double)prim.RotationOffset.W); + + // Sit target + Vector3 sitTargetPos = prim.SitTargetPositionLL; + cmd.Parameters.AddWithValue("SitTargetOffsetX", (double)sitTargetPos.X); + cmd.Parameters.AddWithValue("SitTargetOffsetY", (double)sitTargetPos.Y); + cmd.Parameters.AddWithValue("SitTargetOffsetZ", (double)sitTargetPos.Z); + + Quaternion sitTargetOrient = prim.SitTargetOrientationLL; + cmd.Parameters.AddWithValue("SitTargetOrientW", (double)sitTargetOrient.W); + cmd.Parameters.AddWithValue("SitTargetOrientX", (double)sitTargetOrient.X); + cmd.Parameters.AddWithValue("SitTargetOrientY", (double)sitTargetOrient.Y); + cmd.Parameters.AddWithValue("SitTargetOrientZ", (double)sitTargetOrient.Z); + + cmd.Parameters.AddWithValue("PayPrice", prim.PayPrice[0]); + cmd.Parameters.AddWithValue("PayButton1", prim.PayPrice[1]); + cmd.Parameters.AddWithValue("PayButton2", prim.PayPrice[2]); + cmd.Parameters.AddWithValue("PayButton3", prim.PayPrice[3]); + cmd.Parameters.AddWithValue("PayButton4", prim.PayPrice[4]); + + if ((prim.SoundFlags & 1) != 0) // Looped + { + cmd.Parameters.AddWithValue("LoopedSound", prim.Sound.ToString()); + cmd.Parameters.AddWithValue("LoopedSoundGain", prim.SoundGain); + } + else + { + cmd.Parameters.AddWithValue("LoopedSound", UUID.Zero); + cmd.Parameters.AddWithValue("LoopedSoundGain", 0.0f); + } + + cmd.Parameters.AddWithValue("TextureAnimation", prim.TextureAnimation); + cmd.Parameters.AddWithValue("ParticleSystem", prim.ParticleSystem); + + cmd.Parameters.AddWithValue("OmegaX", (double)prim.RotationalVelocity.X); + cmd.Parameters.AddWithValue("OmegaY", (double)prim.RotationalVelocity.Y); + cmd.Parameters.AddWithValue("OmegaZ", (double)prim.RotationalVelocity.Z); + + cmd.Parameters.AddWithValue("CameraEyeOffsetX", (double)prim.GetCameraEyeOffset().X); + cmd.Parameters.AddWithValue("CameraEyeOffsetY", (double)prim.GetCameraEyeOffset().Y); + cmd.Parameters.AddWithValue("CameraEyeOffsetZ", (double)prim.GetCameraEyeOffset().Z); + + cmd.Parameters.AddWithValue("CameraAtOffsetX", (double)prim.GetCameraAtOffset().X); + cmd.Parameters.AddWithValue("CameraAtOffsetY", (double)prim.GetCameraAtOffset().Y); + cmd.Parameters.AddWithValue("CameraAtOffsetZ", (double)prim.GetCameraAtOffset().Z); + + if (prim.GetForceMouselook()) + cmd.Parameters.AddWithValue("ForceMouselook", 1); + else + cmd.Parameters.AddWithValue("ForceMouselook", 0); + + cmd.Parameters.AddWithValue("ScriptAccessPin", prim.ScriptAccessPin); + + if (prim.AllowedDrop) + cmd.Parameters.AddWithValue("AllowedDrop", 1); + else + cmd.Parameters.AddWithValue("AllowedDrop", 0); + + if (prim.DIE_AT_EDGE) + cmd.Parameters.AddWithValue("DieAtEdge", 1); + else + cmd.Parameters.AddWithValue("DieAtEdge", 0); + + cmd.Parameters.AddWithValue("SalePrice", prim.SalePrice); + cmd.Parameters.AddWithValue("SaleType", unchecked((sbyte)(prim.ObjectSaleType))); + + byte clickAction = prim.ClickAction; + cmd.Parameters.AddWithValue("ClickAction", unchecked((sbyte)(clickAction))); + + cmd.Parameters.AddWithValue("Material", unchecked((sbyte)(prim.Material))); + + cmd.Parameters.AddWithValue("CollisionSound", prim.CollisionSound.ToString()); + cmd.Parameters.AddWithValue("CollisionSoundVolume", prim.CollisionSoundVolume); + + if (prim.PassTouches) + cmd.Parameters.AddWithValue("PassTouches", 1); + else + cmd.Parameters.AddWithValue("PassTouches", 0); + + cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum); + } + + /// + /// + /// + /// + /// + private static void FillItemCommand(MySqlCommand cmd, TaskInventoryItem taskItem) + { + cmd.Parameters.AddWithValue("itemID", taskItem.ItemID); + cmd.Parameters.AddWithValue("primID", taskItem.ParentPartID); + cmd.Parameters.AddWithValue("assetID", taskItem.AssetID); + cmd.Parameters.AddWithValue("parentFolderID", taskItem.ParentID); + + cmd.Parameters.AddWithValue("invType", taskItem.InvType); + cmd.Parameters.AddWithValue("assetType", taskItem.Type); + + cmd.Parameters.AddWithValue("name", taskItem.Name); + cmd.Parameters.AddWithValue("description", taskItem.Description); + cmd.Parameters.AddWithValue("creationDate", taskItem.CreationDate); + cmd.Parameters.AddWithValue("creatorID", taskItem.CreatorID); + cmd.Parameters.AddWithValue("ownerID", taskItem.OwnerID); + cmd.Parameters.AddWithValue("lastOwnerID", taskItem.LastOwnerID); + cmd.Parameters.AddWithValue("groupID", taskItem.GroupID); + cmd.Parameters.AddWithValue("nextPermissions", taskItem.NextPermissions); + cmd.Parameters.AddWithValue("currentPermissions", taskItem.CurrentPermissions); + cmd.Parameters.AddWithValue("basePermissions", taskItem.BasePermissions); + cmd.Parameters.AddWithValue("everyonePermissions", taskItem.EveryonePermissions); + cmd.Parameters.AddWithValue("groupPermissions", taskItem.GroupPermissions); + cmd.Parameters.AddWithValue("flags", taskItem.Flags); + } + + /// + /// + /// + private static void FillRegionSettingsCommand(MySqlCommand cmd, RegionSettings settings) + { + cmd.Parameters.AddWithValue("RegionUUID", settings.RegionUUID.ToString()); + cmd.Parameters.AddWithValue("BlockTerraform", settings.BlockTerraform); + cmd.Parameters.AddWithValue("BlockFly", settings.BlockFly); + cmd.Parameters.AddWithValue("AllowDamage", settings.AllowDamage); + cmd.Parameters.AddWithValue("RestrictPushing", settings.RestrictPushing); + cmd.Parameters.AddWithValue("AllowLandResell", settings.AllowLandResell); + cmd.Parameters.AddWithValue("AllowLandJoinDivide", settings.AllowLandJoinDivide); + cmd.Parameters.AddWithValue("BlockShowInSearch", settings.BlockShowInSearch); + cmd.Parameters.AddWithValue("AgentLimit", settings.AgentLimit); + cmd.Parameters.AddWithValue("ObjectBonus", settings.ObjectBonus); + cmd.Parameters.AddWithValue("Maturity", settings.Maturity); + cmd.Parameters.AddWithValue("DisableScripts", settings.DisableScripts); + cmd.Parameters.AddWithValue("DisableCollisions", settings.DisableCollisions); + cmd.Parameters.AddWithValue("DisablePhysics", settings.DisablePhysics); + cmd.Parameters.AddWithValue("TerrainTexture1", settings.TerrainTexture1.ToString()); + cmd.Parameters.AddWithValue("TerrainTexture2", settings.TerrainTexture2.ToString()); + cmd.Parameters.AddWithValue("TerrainTexture3", settings.TerrainTexture3.ToString()); + cmd.Parameters.AddWithValue("TerrainTexture4", settings.TerrainTexture4.ToString()); + cmd.Parameters.AddWithValue("Elevation1NW", settings.Elevation1NW); + cmd.Parameters.AddWithValue("Elevation2NW", settings.Elevation2NW); + cmd.Parameters.AddWithValue("Elevation1NE", settings.Elevation1NE); + cmd.Parameters.AddWithValue("Elevation2NE", settings.Elevation2NE); + cmd.Parameters.AddWithValue("Elevation1SE", settings.Elevation1SE); + cmd.Parameters.AddWithValue("Elevation2SE", settings.Elevation2SE); + cmd.Parameters.AddWithValue("Elevation1SW", settings.Elevation1SW); + cmd.Parameters.AddWithValue("Elevation2SW", settings.Elevation2SW); + cmd.Parameters.AddWithValue("WaterHeight", settings.WaterHeight); + cmd.Parameters.AddWithValue("TerrainRaiseLimit", settings.TerrainRaiseLimit); + cmd.Parameters.AddWithValue("TerrainLowerLimit", settings.TerrainLowerLimit); + cmd.Parameters.AddWithValue("UseEstateSun", settings.UseEstateSun); + cmd.Parameters.AddWithValue("Sandbox", settings.Sandbox); + cmd.Parameters.AddWithValue("SunVectorX", settings.SunVector.X); + cmd.Parameters.AddWithValue("SunVectorY", settings.SunVector.Y); + cmd.Parameters.AddWithValue("SunVectorZ", settings.SunVector.Z); + cmd.Parameters.AddWithValue("FixedSun", settings.FixedSun); + cmd.Parameters.AddWithValue("SunPosition", settings.SunPosition); + cmd.Parameters.AddWithValue("Covenant", settings.Covenant.ToString()); + cmd.Parameters.AddWithValue("LoadedCreationDateTime", settings.LoadedCreationDateTime); + cmd.Parameters.AddWithValue("LoadedCreationID", settings.LoadedCreationID); + + } + + /// + /// + /// + /// + /// + /// + private static void FillLandCommand(MySqlCommand cmd, LandData land, UUID regionUUID) + { + cmd.Parameters.AddWithValue("UUID", land.GlobalID.ToString()); + cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); + cmd.Parameters.AddWithValue("LocalLandID", land.LocalID); + + // Bitmap is a byte[512] + cmd.Parameters.AddWithValue("Bitmap", land.Bitmap); + + cmd.Parameters.AddWithValue("Name", land.Name); + cmd.Parameters.AddWithValue("Description", land.Description); + cmd.Parameters.AddWithValue("OwnerUUID", land.OwnerID.ToString()); + cmd.Parameters.AddWithValue("IsGroupOwned", land.IsGroupOwned); + cmd.Parameters.AddWithValue("Area", land.Area); + cmd.Parameters.AddWithValue("AuctionID", land.AuctionID); //Unemplemented + cmd.Parameters.AddWithValue("Category", land.Category); //Enum libsecondlife.Parcel.ParcelCategory + cmd.Parameters.AddWithValue("ClaimDate", land.ClaimDate); + cmd.Parameters.AddWithValue("ClaimPrice", land.ClaimPrice); + cmd.Parameters.AddWithValue("GroupUUID", land.GroupID.ToString()); + cmd.Parameters.AddWithValue("SalePrice", land.SalePrice); + cmd.Parameters.AddWithValue("LandStatus", land.Status); //Enum. libsecondlife.Parcel.ParcelStatus + cmd.Parameters.AddWithValue("LandFlags", land.Flags); + cmd.Parameters.AddWithValue("LandingType", land.LandingType); + cmd.Parameters.AddWithValue("MediaAutoScale", land.MediaAutoScale); + cmd.Parameters.AddWithValue("MediaTextureUUID", land.MediaID.ToString()); + cmd.Parameters.AddWithValue("MediaURL", land.MediaURL); + cmd.Parameters.AddWithValue("MusicURL", land.MusicURL); + cmd.Parameters.AddWithValue("PassHours", land.PassHours); + cmd.Parameters.AddWithValue("PassPrice", land.PassPrice); + cmd.Parameters.AddWithValue("SnapshotUUID", land.SnapshotID.ToString()); + cmd.Parameters.AddWithValue("UserLocationX", land.UserLocation.X); + cmd.Parameters.AddWithValue("UserLocationY", land.UserLocation.Y); + cmd.Parameters.AddWithValue("UserLocationZ", land.UserLocation.Z); + cmd.Parameters.AddWithValue("UserLookAtX", land.UserLookAt.X); + cmd.Parameters.AddWithValue("UserLookAtY", land.UserLookAt.Y); + cmd.Parameters.AddWithValue("UserLookAtZ", land.UserLookAt.Z); + cmd.Parameters.AddWithValue("AuthBuyerID", land.AuthBuyerID); + cmd.Parameters.AddWithValue("OtherCleanTime", land.OtherCleanTime); + cmd.Parameters.AddWithValue("Dwell", land.Dwell); + } + + /// + /// + /// + /// + /// + /// + private static void FillLandAccessCommand(MySqlCommand cmd, ParcelManager.ParcelAccessEntry entry, UUID parcelID) + { + cmd.Parameters.AddWithValue("LandUUID", parcelID.ToString()); + cmd.Parameters.AddWithValue("AccessUUID", entry.AgentID.ToString()); + cmd.Parameters.AddWithValue("Flags", entry.Flags); + } + + /// + /// + /// + /// + /// + private PrimitiveBaseShape BuildShape(IDataReader row) + { + PrimitiveBaseShape s = new PrimitiveBaseShape(); + s.Scale = new Vector3( + Convert.ToSingle(row["ScaleX"]), + Convert.ToSingle(row["ScaleY"]), + Convert.ToSingle(row["ScaleZ"]) + ); + // paths + s.PCode = Convert.ToByte(row["PCode"]); + s.PathBegin = Convert.ToUInt16(row["PathBegin"]); + s.PathEnd = Convert.ToUInt16(row["PathEnd"]); + s.PathScaleX = Convert.ToByte(row["PathScaleX"]); + s.PathScaleY = Convert.ToByte(row["PathScaleY"]); + s.PathShearX = Convert.ToByte(row["PathShearX"]); + s.PathShearY = Convert.ToByte(row["PathShearY"]); + s.PathSkew = Convert.ToSByte(row["PathSkew"]); + s.PathCurve = Convert.ToByte(row["PathCurve"]); + s.PathRadiusOffset = Convert.ToSByte(row["PathRadiusOffset"]); + s.PathRevolutions = Convert.ToByte(row["PathRevolutions"]); + s.PathTaperX = Convert.ToSByte(row["PathTaperX"]); + s.PathTaperY = Convert.ToSByte(row["PathTaperY"]); + s.PathTwist = Convert.ToSByte(row["PathTwist"]); + s.PathTwistBegin = Convert.ToSByte(row["PathTwistBegin"]); + // profile + s.ProfileBegin = Convert.ToUInt16(row["ProfileBegin"]); + s.ProfileEnd = Convert.ToUInt16(row["ProfileEnd"]); + s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]); + s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]); + byte[] textureEntry = (byte[]) row["Texture"]; + s.TextureEntry = textureEntry; + + s.ExtraParams = (byte[]) row["ExtraParams"]; + + s.State = Convert.ToByte(row["State"]); + + return s; + } + + /// + /// + /// + /// + /// + private void FillShapeCommand(MySqlCommand cmd, SceneObjectPart prim) + { + PrimitiveBaseShape s = prim.Shape; + cmd.Parameters.AddWithValue("UUID", prim.UUID.ToString()); + // shape is an enum + cmd.Parameters.AddWithValue("Shape", 0); + // vectors + cmd.Parameters.AddWithValue("ScaleX", (double)s.Scale.X); + cmd.Parameters.AddWithValue("ScaleY", (double)s.Scale.Y); + cmd.Parameters.AddWithValue("ScaleZ", (double)s.Scale.Z); + // paths + cmd.Parameters.AddWithValue("PCode", s.PCode); + cmd.Parameters.AddWithValue("PathBegin", s.PathBegin); + cmd.Parameters.AddWithValue("PathEnd", s.PathEnd); + cmd.Parameters.AddWithValue("PathScaleX", s.PathScaleX); + cmd.Parameters.AddWithValue("PathScaleY", s.PathScaleY); + cmd.Parameters.AddWithValue("PathShearX", s.PathShearX); + cmd.Parameters.AddWithValue("PathShearY", s.PathShearY); + cmd.Parameters.AddWithValue("PathSkew", s.PathSkew); + cmd.Parameters.AddWithValue("PathCurve", s.PathCurve); + cmd.Parameters.AddWithValue("PathRadiusOffset", s.PathRadiusOffset); + cmd.Parameters.AddWithValue("PathRevolutions", s.PathRevolutions); + cmd.Parameters.AddWithValue("PathTaperX", s.PathTaperX); + cmd.Parameters.AddWithValue("PathTaperY", s.PathTaperY); + cmd.Parameters.AddWithValue("PathTwist", s.PathTwist); + cmd.Parameters.AddWithValue("PathTwistBegin", s.PathTwistBegin); + // profile + cmd.Parameters.AddWithValue("ProfileBegin", s.ProfileBegin); + cmd.Parameters.AddWithValue("ProfileEnd", s.ProfileEnd); + cmd.Parameters.AddWithValue("ProfileCurve", s.ProfileCurve); + cmd.Parameters.AddWithValue("ProfileHollow", s.ProfileHollow); + cmd.Parameters.AddWithValue("Texture", s.TextureEntry); + cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams); + cmd.Parameters.AddWithValue("State", s.State); + } + + public void StorePrimInventory(UUID primID, ICollection items) + { + lock (m_Connection) + { + RemoveItems(primID); + + MySqlCommand cmd = m_Connection.CreateCommand(); + + if (items.Count == 0) + return; + + cmd.CommandText = "insert into primitems ("+ + "invType, assetType, name, "+ + "description, creationDate, nextPermissions, "+ + "currentPermissions, basePermissions, "+ + "everyonePermissions, groupPermissions, "+ + "flags, itemID, primID, assetID, "+ + "parentFolderID, creatorID, ownerID, "+ + "groupID, lastOwnerID) values (?invType, "+ + "?assetType, ?name, ?description, "+ + "?creationDate, ?nextPermissions, "+ + "?currentPermissions, ?basePermissions, "+ + "?everyonePermissions, ?groupPermissions, "+ + "?flags, ?itemID, ?primID, ?assetID, "+ + "?parentFolderID, ?creatorID, ?ownerID, "+ + "?groupID, ?lastOwnerID)"; + + foreach (TaskInventoryItem item in items) + { + cmd.Parameters.Clear(); + + FillItemCommand(cmd, item); + + ExecuteNonQuery(cmd); + } + + cmd.Dispose(); + } + } + } +} diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index 4a16a702c4..ced26a462f 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -26,1569 +26,242 @@ */ using System; +using System.Collections; using System.Collections.Generic; using System.Data; -using System.Drawing; -using System.IO; -using System.Reflection; -using System.Threading; -using log4net; -using MySql.Data.MySqlClient; using OpenMetaverse; using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; +using MySql.Data.MySqlClient; namespace OpenSim.Data.MySQL { - /// - /// A MySQL Interface for the Region Server - /// - public class MySQLDataStore : IRegionDataStore + public class MySqlRegionData : MySqlFramework, IRegionData { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private string m_Realm; + private List m_ColumnNames = null; + private int m_LastExpire = 0; - private string m_ConnectionString; - - private MySqlConnection m_Connection = null; - - public void Initialise(string connectionString) + public MySqlRegionData(string connectionString, string realm) + : base(connectionString) { - m_ConnectionString = connectionString; + m_Realm = realm; - m_Connection = new MySqlConnection(m_ConnectionString); - - m_Connection.Open(); - - // Apply new Migrations - // - Assembly assem = GetType().Assembly; - Migration m = new Migration(m_Connection, assem, "RegionStore"); + Migration m = new Migration(m_Connection, GetType().Assembly, "GridStore"); m.Update(); + } + + public List Get(string regionName, UUID scopeID) + { + string command = "select * from `"+m_Realm+"` where regionName like ?regionName"; + if (scopeID != UUID.Zero) + command += " and ScopeID = ?scopeID"; + + MySqlCommand cmd = new MySqlCommand(command); + + cmd.Parameters.AddWithValue("?regionName", regionName); + cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); + + return RunCommand(cmd); + } + + public RegionData Get(int posX, int posY, UUID scopeID) + { + string command = "select * from `"+m_Realm+"` where locX = ?posX and locY = ?posY"; + if (scopeID != UUID.Zero) + command += " and ScopeID = ?scopeID"; + + MySqlCommand cmd = new MySqlCommand(command); + + cmd.Parameters.AddWithValue("?posX", posX.ToString()); + cmd.Parameters.AddWithValue("?posY", posY.ToString()); + cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); + + List ret = RunCommand(cmd); + if (ret == null) + return null; + + return ret[0]; + } + + public RegionData Get(UUID regionID, UUID scopeID) + { + string command = "select * from `"+m_Realm+"` where uuid = ?regionID"; + if (scopeID != UUID.Zero) + command += " and ScopeID = ?scopeID"; + + MySqlCommand cmd = new MySqlCommand(command); + + cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); + cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); + + List ret = RunCommand(cmd); + if (ret == null) + return null; + + return ret[0]; + } + + public List Get(int startX, int startY, int endX, int endY, UUID scopeID) + { + string command = "select * from `"+m_Realm+"` where locX between ?startX and ?endX and locY between ?startY and ?endY"; + if (scopeID != UUID.Zero) + command += " and ScopeID = ?scopeID"; + + MySqlCommand cmd = new MySqlCommand(command); + + cmd.Parameters.AddWithValue("?startX", startX.ToString()); + cmd.Parameters.AddWithValue("?startY", startY.ToString()); + cmd.Parameters.AddWithValue("?endX", endX.ToString()); + cmd.Parameters.AddWithValue("?endY", endY.ToString()); + cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); + + return RunCommand(cmd); + } + + public List RunCommand(MySqlCommand cmd) + { + List retList = new List(); + + IDataReader result = ExecuteReader(cmd); + + 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"]); + + 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); + } + + result.Close(); + CloseReaderCommand(cmd); + + if (retList.Count > 0) + return retList; + + return null; + } + + 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"); + + string[] fields = new List(data.Data.Keys).ToArray(); + + MySqlCommand cmd = new MySqlCommand(); + + string update = "update `"+m_Realm+"` set "; + bool first = true; + foreach (string field in fields) + { + if (!first) + update += ", "; + update += "`" + field + "` = ?"+field; + + first = false; + + cmd.Parameters.AddWithValue("?"+field, data.Data[field]); + } + + update += " where uuid = ?regionID"; + + if (data.ScopeID != UUID.Zero) + update += " and ScopeID = ?scopeID"; + + cmd.CommandText = update; + cmd.Parameters.AddWithValue("?regionID", data.RegionID.ToString()); + cmd.Parameters.AddWithValue("?scopeID", data.ScopeID.ToString()); + + if (ExecuteNonQuery(cmd) < 1) + { + string insert = "insert into `" + m_Realm + "` (`uuid`, `ScopeID`, `" + + String.Join("`, `", fields) + + "`) values ( ?regionID, ?scopeID, ?" + String.Join(", ?", fields) + ")"; + + cmd.CommandText = insert; + + if (ExecuteNonQuery(cmd) < 1) + { + cmd.Dispose(); + return false; + } + } - // Clean dropped attachments - // - MySqlCommand cmd = m_Connection.CreateCommand(); - cmd.CommandText = "delete from prims, primshapes using prims " + - "left join primshapes on prims.uuid = primshapes.uuid " + - "where PCode = 9 and State <> 0"; - ExecuteNonQuery(cmd); cmd.Dispose(); + + return true; } - private IDataReader ExecuteReader(MySqlCommand c) + public bool SetDataItem(UUID regionID, string item, string value) { - IDataReader r = null; - bool errorSeen = false; + MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + + "` set `" + item + "` = ?" + item + " where uuid = ?UUID"); - while (true) - { - try - { - r = c.ExecuteReader(); - } - catch (Exception) - { - Thread.Sleep(500); - m_Connection.Close(); - m_Connection = (MySqlConnection) ((ICloneable)m_Connection).Clone(); - m_Connection.Open(); - c.Connection = m_Connection; + cmd.Parameters.AddWithValue("?"+item, value); + cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); - if (!errorSeen) - { - errorSeen = true; - continue; - } - throw; - } + if (ExecuteNonQuery(cmd) > 0) + return true; - break; - } - - return r; + return false; } - private void ExecuteNonQuery(MySqlCommand c) + public bool Delete(UUID regionID) { - bool errorSeen = false; + MySqlCommand cmd = new MySqlCommand("delete from `" + m_Realm + + "` where uuid = ?UUID"); - while (true) - { - try - { - c.ExecuteNonQuery(); - } - catch (Exception) - { - Thread.Sleep(500); - m_Connection.Close(); - m_Connection = (MySqlConnection) ((ICloneable)m_Connection).Clone(); - m_Connection.Open(); - c.Connection = m_Connection; + cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); - if (!errorSeen) - { - errorSeen = true; - continue; - } - throw; - } + if (ExecuteNonQuery(cmd) > 0) + return true; - break; - } - } - - public void Dispose() {} - - public void StoreObject(SceneObjectGroup obj, UUID regionUUID) - { - uint flags = obj.RootPart.GetEffectiveObjectFlags(); - - // Eligibility check - // - if ((flags & (uint)PrimFlags.Temporary) != 0) - return; - if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0) - return; - - lock (m_Connection) - { - MySqlCommand cmd = m_Connection.CreateCommand(); - - foreach (SceneObjectPart prim in obj.Children.Values) - { - cmd.Parameters.Clear(); - - cmd.CommandText = "replace into prims ("+ - "UUID, CreationDate, "+ - "Name, Text, Description, "+ - "SitName, TouchName, ObjectFlags, "+ - "OwnerMask, NextOwnerMask, GroupMask, "+ - "EveryoneMask, BaseMask, PositionX, "+ - "PositionY, PositionZ, GroupPositionX, "+ - "GroupPositionY, GroupPositionZ, VelocityX, "+ - "VelocityY, VelocityZ, AngularVelocityX, "+ - "AngularVelocityY, AngularVelocityZ, "+ - "AccelerationX, AccelerationY, "+ - "AccelerationZ, RotationX, "+ - "RotationY, RotationZ, "+ - "RotationW, SitTargetOffsetX, "+ - "SitTargetOffsetY, SitTargetOffsetZ, "+ - "SitTargetOrientW, SitTargetOrientX, "+ - "SitTargetOrientY, SitTargetOrientZ, "+ - "RegionUUID, CreatorID, "+ - "OwnerID, GroupID, "+ - "LastOwnerID, SceneGroupID, "+ - "PayPrice, PayButton1, "+ - "PayButton2, PayButton3, "+ - "PayButton4, LoopedSound, "+ - "LoopedSoundGain, TextureAnimation, "+ - "OmegaX, OmegaY, OmegaZ, "+ - "CameraEyeOffsetX, CameraEyeOffsetY, "+ - "CameraEyeOffsetZ, CameraAtOffsetX, "+ - "CameraAtOffsetY, CameraAtOffsetZ, "+ - "ForceMouselook, ScriptAccessPin, "+ - "AllowedDrop, DieAtEdge, "+ - "SalePrice, SaleType, "+ - "ColorR, ColorG, ColorB, ColorA, "+ - "ParticleSystem, ClickAction, Material, "+ - "CollisionSound, CollisionSoundVolume, "+ - "PassTouches, "+ - "LinkNumber) 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)"; - - FillPrimCommand(cmd, prim, obj.UUID, regionUUID); - - ExecuteNonQuery(cmd); - - cmd.Parameters.Clear(); - - cmd.CommandText = "replace into primshapes ("+ - "UUID, Shape, ScaleX, ScaleY, "+ - "ScaleZ, PCode, PathBegin, PathEnd, "+ - "PathScaleX, PathScaleY, PathShearX, "+ - "PathShearY, PathSkew, PathCurve, "+ - "PathRadiusOffset, PathRevolutions, "+ - "PathTaperX, PathTaperY, PathTwist, "+ - "PathTwistBegin, ProfileBegin, ProfileEnd, "+ - "ProfileCurve, ProfileHollow, Texture, "+ - "ExtraParams, State) 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)"; - - FillShapeCommand(cmd, prim); - - ExecuteNonQuery(cmd); - } - cmd.Dispose(); - } - } - - public void RemoveObject(UUID obj, UUID regionUUID) - { - // Formerly, this used to check the region UUID. - // That makes no sense, as we remove the contents of a prim - // unconditionally, but the prim dependent on the region ID. - // So, we would destroy an object and cause hard to detect - // issues if we delete the contents only. Deleting it all may - // cause the loss of a prim, but is cleaner. - // It's also faster because it uses the primary key. - // - lock (m_Connection) - { - MySqlCommand cmd = m_Connection.CreateCommand(); - - cmd.CommandText = "select UUID from prims where "+ - "SceneGroupID= ?UUID"; - - cmd.Parameters.AddWithValue("UUID", obj.ToString()); - - List uuids = new List(); - - IDataReader reader = ExecuteReader(cmd); - - try - { - while (reader.Read()) - { - uuids.Add(new UUID(reader["UUID"].ToString())); - } - } - finally - { - reader.Close(); - } - - // delete the main prims - cmd.CommandText = "delete from prims where SceneGroupID= ?UUID"; - ExecuteNonQuery(cmd); - cmd.Dispose(); - - // there is no way this should be < 1 unless there is - // a very corrupt database, but in that case be extra - // safe anyway. - if (uuids.Count > 0) - { - RemoveShapes(uuids); - RemoveItems(uuids); - } - } - } - - /// - /// Remove all persisted items of the given prim. - /// The caller must acquire the necessrary synchronization locks - /// - /// the Item UUID - private void RemoveItems(UUID uuid) - { - lock (m_Connection) - { - MySqlCommand cmd = m_Connection.CreateCommand(); - - cmd.CommandText = "delete from primitems where " + - "PrimID = ?PrimID"; - - cmd.Parameters.AddWithValue("PrimID", uuid.ToString()); - - ExecuteNonQuery(cmd); - cmd.Dispose(); - } - } - - - /// - /// Remove all persisted shapes for a list of prims - /// The caller must acquire the necessrary synchronization locks - /// - /// the list of UUIDs - private void RemoveShapes(List uuids) - { - lock (m_Connection) - { - string sql = "delete from primshapes where "; - MySqlCommand cmd = m_Connection.CreateCommand(); - - for (int i = 0; i < uuids.Count; i++) - { - if ((i + 1) == uuids.Count) - {// end of the list - sql += "(UUID = ?UUID" + i + ")"; - } - else - { - sql += "(UUID = ?UUID" + i + ") or "; - } - } - cmd.CommandText = sql; - - for (int i = 0; i < uuids.Count; i++) - { - cmd.Parameters.AddWithValue("UUID" + i, uuids[i].ToString()); - } - - ExecuteNonQuery(cmd); - cmd.Dispose(); - } - } - - /// - /// Remove all persisted items for a list of prims - /// The caller must acquire the necessrary synchronization locks - /// - /// the list of UUIDs - private void RemoveItems(List uuids) - { - lock (m_Connection) - { - string sql = "delete from primitems where "; - MySqlCommand cmd = m_Connection.CreateCommand(); - - for (int i = 0; i < uuids.Count; i++) - { - if ((i + 1) == uuids.Count) - {// end of the list - sql += "(PrimID = ?PrimID" + i + ")"; - } - else - { - sql += "(PrimID = ?PrimID" + i + ") or "; - } - } - cmd.CommandText = sql; - - for (int i = 0; i < uuids.Count; i++) - { - cmd.Parameters.AddWithValue("PrimID" + i, uuids[i].ToString()); - } - - ExecuteNonQuery(cmd); - cmd.Dispose(); - } - } - - public List LoadObjects(UUID regionUUID) - { - UUID lastGroupID = UUID.Zero; - Dictionary objects = new Dictionary(); - Dictionary prims = new Dictionary(); - SceneObjectGroup grp = null; - - lock (m_Connection) - { - MySqlCommand cmd = m_Connection.CreateCommand(); - - cmd.CommandText = "select *, " + - "case when prims.UUID = SceneGroupID " + - "then 0 else 1 end as sort from prims " + - "left join primshapes on prims.UUID = primshapes.UUID "+ - "where RegionUUID = ?RegionUUID " + - "order by SceneGroupID asc, sort asc, LinkNumber asc"; - - cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); - - IDataReader reader = ExecuteReader(cmd); - - try - { - while (reader.Read()) - { - SceneObjectPart prim = BuildPrim(reader); - if (reader["Shape"] is DBNull) - prim.Shape = PrimitiveBaseShape.Default; - else - prim.Shape = BuildShape(reader); - - prims[prim.UUID] = prim; - - UUID groupID = new UUID(reader["SceneGroupID"].ToString()); - - 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 (prim.UUID != groupID && groupID != UUID.Zero) - { - m_log.WarnFormat( - "[REGION DB]: Found root prim {0} {1} at {2} where group was actually {3}. Forcing UUID to group UUID", - prim.Name, prim.UUID, prim.GroupPosition, groupID); - - prim.UUID = groupID; - } - - grp = new SceneObjectGroup(prim); - } - else - { - // Black magic to preserve link numbers - // - int link = prim.LinkNum; - - grp.AddPart(prim); - - if (link != 0) - prim.LinkNum = link; - } - } - } - finally - { - reader.Close(); - } - - if (grp != null) - objects[grp.UUID] = grp; - cmd.Dispose(); - } - - // 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(); - lock (m_Connection) - { - MySqlCommand itemCmd = m_Connection.CreateCommand(); - itemCmd.CommandText = "select distinct primID from primitems"; - IDataReader itemReader = ExecuteReader(itemCmd); - try - { - while (itemReader.Read()) - { - if (!(itemReader["primID"] is DBNull)) - { - UUID primID = new UUID(itemReader["primID"].ToString()); - if (prims.ContainsKey(primID)) - { - primsWithInventory.Add(prims[primID]); - } - } - } - } - finally - { - itemReader.Close(); - } - itemCmd.Dispose(); - } - - foreach (SceneObjectPart prim in primsWithInventory) - { - LoadItems(prim); - } - m_log.DebugFormat("[REGION DB]: Loaded {0} objects using {1} prims", objects.Count, prims.Count); - return new List(objects.Values); - } - - /// - /// Load in a prim's persisted inventory. - /// - /// The prim - private void LoadItems(SceneObjectPart prim) - { - lock (m_Connection) - { - MySqlCommand cmd = m_Connection.CreateCommand(); - - cmd.CommandText = "select * from primitems where "+ - "PrimID = ?PrimID"; - - cmd.Parameters.AddWithValue("PrimID", prim.UUID.ToString()); - - IDataReader reader = ExecuteReader(cmd); - List inventory = - new List(); - - try - { - while (reader.Read()) - { - TaskInventoryItem item = BuildItem(reader); - - item.ParentID = prim.UUID; // Values in database are - // often wrong - inventory.Add(item); - } - } - finally - { - reader.Close(); - } - - cmd.Dispose(); - prim.Inventory.RestoreInventoryItems(inventory); - } - } - - public void StoreTerrain(double[,] ter, UUID regionID) - { - m_log.Info("[REGION DB]: Storing terrain"); - - lock (m_Connection) - { - MySqlCommand cmd = m_Connection.CreateCommand(); - - cmd.CommandText = "delete from terrain where " + - "RegionUUID = ?RegionUUID"; - cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); - - ExecuteNonQuery(cmd); - - cmd.CommandText = "insert into terrain (RegionUUID, " + - "Revision, Heightfield) values (?RegionUUID, " + - "1, ?Heightfield)"; - - cmd.Parameters.AddWithValue("Heightfield", - SerializeTerrain(ter)); - - ExecuteNonQuery(cmd); - cmd.Dispose(); - } - } - - public double[,] LoadTerrain(UUID regionID) - { - double[,] terrain = null; - - lock (m_Connection) - { - MySqlCommand cmd = m_Connection.CreateCommand(); - cmd.CommandText = "select RegionUUID, Revision, Heightfield " + - "from terrain where RegionUUID = ?RegionUUID "+ - "order by Revision desc limit 1"; - cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); - - IDataReader reader = ExecuteReader(cmd); - - try - { - while (reader.Read()) - { - terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; - terrain.Initialize(); - - MemoryStream mstr = new MemoryStream((byte[]) reader["Heightfield"]); - int rev = 0; - - BinaryReader br = new BinaryReader(mstr); - for (int x = 0; x < (int)Constants.RegionSize; x++) - { - for (int y = 0; y < (int)Constants.RegionSize; y++) - { - terrain[x, y] = br.ReadDouble(); - } - rev = Convert.ToInt32(reader["Revision"]); - } - m_log.InfoFormat("[REGION DB]: Loaded terrain " + - "revision r{0}", rev); - } - } - finally - { - reader.Close(); - } - cmd.Dispose(); - } - - return terrain; - } - - public void RemoveLandObject(UUID globalID) - { - lock (m_Connection) - { - MySqlCommand cmd = m_Connection.CreateCommand(); - - cmd.CommandText = "delete from land where UUID = ?UUID"; - - cmd.Parameters.AddWithValue("UUID", globalID.ToString()); - - ExecuteNonQuery(cmd); - cmd.Dispose(); - } - } - - public void StoreLandObject(ILandObject parcel) - { - lock (m_Connection) - { - MySqlCommand cmd = m_Connection.CreateCommand(); - - cmd.CommandText = "replace 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)"; - - FillLandCommand(cmd, parcel.landData, parcel.regionUUID); - - ExecuteNonQuery(cmd); - - cmd.CommandText = "delete from landaccesslist where " + - "LandUUID = ?UUID"; - - ExecuteNonQuery(cmd); - - cmd.Parameters.Clear(); - cmd.CommandText = "insert into landaccesslist (LandUUID, " + - "AccessUUID, Flags) values (?LandUUID, ?AccessUUID, " + - "?Flags)"; - - foreach (ParcelManager.ParcelAccessEntry entry in - parcel.landData.ParcelAccessList) - { - FillLandAccessCommand(cmd, entry, parcel.landData.GlobalID); - ExecuteNonQuery(cmd); - cmd.Parameters.Clear(); - } - cmd.Dispose(); - } - } - - public RegionSettings LoadRegionSettings(UUID regionUUID) - { - RegionSettings rs = null; - - lock (m_Connection) - { - MySqlCommand cmd = m_Connection.CreateCommand(); - - cmd.CommandText = "select * from regionsettings where " + - "regionUUID = ?RegionUUID"; - cmd.Parameters.AddWithValue("regionUUID", regionUUID); - - IDataReader reader = ExecuteReader(cmd); - - try - { - if (reader.Read()) - { - rs = BuildRegionSettings(reader); - rs.OnSave += StoreRegionSettings; - } - else - { - rs = new RegionSettings(); - rs.RegionUUID = regionUUID; - rs.OnSave += StoreRegionSettings; - - StoreRegionSettings(rs); - } - } - finally - { - reader.Close(); - } - cmd.Dispose(); - } - - return rs; - } - - public void StoreRegionSettings(RegionSettings rs) - { - lock (m_Connection) - { - MySqlCommand cmd = m_Connection.CreateCommand(); - - cmd.CommandText = "replace 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, Sandbox, sunvectorx, sunvectory, " + - "sunvectorz, loaded_creation_datetime, " + - "loaded_creation_id) values ( ?RegionUUID, ?BlockTerraform, " + - "?BlockFly, ?AllowDamage, ?RestrictPushing, " + - "?AllowLandResell, ?AllowLandJoinDivide, " + - "?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " + - "?Maturity, ?DisableScripts, ?DisableCollisions, " + - "?DisablePhysics, ?TerrainTexture1, " + - "?TerrainTexture2, ?TerrainTexture3, " + - "?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " + - "?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " + - "?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " + - "?WaterHeight, ?TerrainRaiseLimit, " + - "?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " + - "?SunPosition, ?Covenant, ?Sandbox, " + - "?SunVectorX, ?SunVectorY, ?SunVectorZ, " + - "?LoadedCreationDateTime, ?LoadedCreationID)"; - - FillRegionSettingsCommand(cmd, rs); - - ExecuteNonQuery(cmd); - cmd.Dispose(); - - } - } - - public List LoadLandObjects(UUID regionUUID) - { - List landData = new List(); - - lock (m_Connection) - { - MySqlCommand cmd = m_Connection.CreateCommand(); - - cmd.CommandText = "select * from land where " + - "RegionUUID = ?RegionUUID"; - - cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); - - IDataReader reader = ExecuteReader(cmd); - - try - { - while (reader.Read()) - { - LandData newLand = BuildLandData(reader); - landData.Add(newLand); - } - } - finally - { - reader.Close(); - } - - foreach (LandData land in landData) - { - cmd.Parameters.Clear(); - - cmd.CommandText = "select * from landaccesslist " + - "where LandUUID = ?LandUUID"; - - cmd.Parameters.AddWithValue("LandUUID", land.GlobalID.ToString()); - - reader = ExecuteReader(cmd); - - try - { - while (reader.Read()) - { - land.ParcelAccessList.Add(BuildLandAccessData(reader)); - } - } - finally - { - reader.Close(); - } - } - cmd.Dispose(); - } - - return landData; - } - - public void Shutdown() - { - } - - private SceneObjectPart BuildPrim(IDataReader row) - { - SceneObjectPart prim = new SceneObjectPart(); - prim.UUID = new UUID((String) row["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(row["CreationDate"]); - if (row["Name"] != DBNull.Value) - prim.Name = (String)row["Name"]; - else - prim.Name = string.Empty; - // various text fields - prim.Text = (String) row["Text"]; - prim.Color = Color.FromArgb(Convert.ToInt32(row["ColorA"]), - Convert.ToInt32(row["ColorR"]), - Convert.ToInt32(row["ColorG"]), - Convert.ToInt32(row["ColorB"])); - prim.Description = (String) row["Description"]; - prim.SitName = (String) row["SitName"]; - prim.TouchName = (String) row["TouchName"]; - // permissions - prim.ObjectFlags = Convert.ToUInt32(row["ObjectFlags"]); - prim.CreatorID = new UUID((String) row["CreatorID"]); - prim.OwnerID = new UUID((String) row["OwnerID"]); - prim.GroupID = new UUID((String) row["GroupID"]); - prim.LastOwnerID = new UUID((String) row["LastOwnerID"]); - prim.OwnerMask = Convert.ToUInt32(row["OwnerMask"]); - prim.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]); - prim.GroupMask = Convert.ToUInt32(row["GroupMask"]); - prim.EveryoneMask = Convert.ToUInt32(row["EveryoneMask"]); - prim.BaseMask = Convert.ToUInt32(row["BaseMask"]); - // vectors - prim.OffsetPosition = new Vector3( - Convert.ToSingle(row["PositionX"]), - Convert.ToSingle(row["PositionY"]), - Convert.ToSingle(row["PositionZ"]) - ); - prim.GroupPosition = new Vector3( - Convert.ToSingle(row["GroupPositionX"]), - Convert.ToSingle(row["GroupPositionY"]), - Convert.ToSingle(row["GroupPositionZ"]) - ); - prim.Velocity = new Vector3( - Convert.ToSingle(row["VelocityX"]), - Convert.ToSingle(row["VelocityY"]), - Convert.ToSingle(row["VelocityZ"]) - ); - prim.AngularVelocity = new Vector3( - Convert.ToSingle(row["AngularVelocityX"]), - Convert.ToSingle(row["AngularVelocityY"]), - Convert.ToSingle(row["AngularVelocityZ"]) - ); - prim.Acceleration = new Vector3( - Convert.ToSingle(row["AccelerationX"]), - Convert.ToSingle(row["AccelerationY"]), - Convert.ToSingle(row["AccelerationZ"]) - ); - // quaternions - prim.RotationOffset = new Quaternion( - Convert.ToSingle(row["RotationX"]), - Convert.ToSingle(row["RotationY"]), - Convert.ToSingle(row["RotationZ"]), - Convert.ToSingle(row["RotationW"]) - ); - prim.SitTargetPositionLL = new Vector3( - Convert.ToSingle(row["SitTargetOffsetX"]), - Convert.ToSingle(row["SitTargetOffsetY"]), - Convert.ToSingle(row["SitTargetOffsetZ"]) - ); - prim.SitTargetOrientationLL = new Quaternion( - Convert.ToSingle(row["SitTargetOrientX"]), - Convert.ToSingle(row["SitTargetOrientY"]), - Convert.ToSingle(row["SitTargetOrientZ"]), - Convert.ToSingle(row["SitTargetOrientW"]) - ); - - prim.PayPrice[0] = Convert.ToInt32(row["PayPrice"]); - prim.PayPrice[1] = Convert.ToInt32(row["PayButton1"]); - prim.PayPrice[2] = Convert.ToInt32(row["PayButton2"]); - prim.PayPrice[3] = Convert.ToInt32(row["PayButton3"]); - prim.PayPrice[4] = Convert.ToInt32(row["PayButton4"]); - - prim.Sound = new UUID(row["LoopedSound"].ToString()); - prim.SoundGain = Convert.ToSingle(row["LoopedSoundGain"]); - prim.SoundFlags = 1; // If it's persisted at all, it's looped - - if (!(row["TextureAnimation"] is DBNull)) - prim.TextureAnimation = (Byte[])row["TextureAnimation"]; - if (!(row["ParticleSystem"] is DBNull)) - prim.ParticleSystem = (Byte[])row["ParticleSystem"]; - - prim.RotationalVelocity = new Vector3( - Convert.ToSingle(row["OmegaX"]), - Convert.ToSingle(row["OmegaY"]), - Convert.ToSingle(row["OmegaZ"]) - ); - - prim.SetCameraEyeOffset(new Vector3( - Convert.ToSingle(row["CameraEyeOffsetX"]), - Convert.ToSingle(row["CameraEyeOffsetY"]), - Convert.ToSingle(row["CameraEyeOffsetZ"]) - )); - - prim.SetCameraAtOffset(new Vector3( - Convert.ToSingle(row["CameraAtOffsetX"]), - Convert.ToSingle(row["CameraAtOffsetY"]), - Convert.ToSingle(row["CameraAtOffsetZ"]) - )); - - if (Convert.ToInt16(row["ForceMouselook"]) != 0) - prim.SetForceMouselook(true); - - prim.ScriptAccessPin = Convert.ToInt32(row["ScriptAccessPin"]); - - if (Convert.ToInt16(row["AllowedDrop"]) != 0) - prim.AllowedDrop = true; - - if (Convert.ToInt16(row["DieAtEdge"]) != 0) - prim.DIE_AT_EDGE = true; - - prim.SalePrice = Convert.ToInt32(row["SalePrice"]); - prim.ObjectSaleType = unchecked((byte)Convert.ToSByte(row["SaleType"])); - - prim.Material = unchecked((byte)Convert.ToSByte(row["Material"])); - - if (!(row["ClickAction"] is DBNull)) - prim.ClickAction = unchecked((byte)Convert.ToSByte(row["ClickAction"])); - - prim.CollisionSound = new UUID(row["CollisionSound"].ToString()); - prim.CollisionSoundVolume = Convert.ToSingle(row["CollisionSoundVolume"]); - - if (Convert.ToInt16(row["PassTouches"]) != 0) - prim.PassTouches = true; - prim.LinkNum = Convert.ToInt32(row["LinkNumber"]); - - return prim; - } - - - /// - /// Build a prim inventory item from the persisted data. - /// - /// - /// - private static TaskInventoryItem BuildItem(IDataReader row) - { - TaskInventoryItem taskItem = new TaskInventoryItem(); - - taskItem.ItemID = new UUID((String)row["itemID"]); - taskItem.ParentPartID = new UUID((String)row["primID"]); - taskItem.AssetID = new UUID((String)row["assetID"]); - taskItem.ParentID = new UUID((String)row["parentFolderID"]); - - taskItem.InvType = Convert.ToInt32(row["invType"]); - taskItem.Type = Convert.ToInt32(row["assetType"]); - - taskItem.Name = (String)row["name"]; - taskItem.Description = (String)row["description"]; - taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]); - taskItem.CreatorID = new UUID((String)row["creatorID"]); - taskItem.OwnerID = new UUID((String)row["ownerID"]); - taskItem.LastOwnerID = new UUID((String)row["lastOwnerID"]); - taskItem.GroupID = new UUID((String)row["groupID"]); - - taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]); - taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]); - taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]); - taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]); - taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]); - taskItem.Flags = Convert.ToUInt32(row["flags"]); - - return taskItem; - } - - private static RegionSettings BuildRegionSettings(IDataReader row) - { - RegionSettings newSettings = new RegionSettings(); - - newSettings.RegionUUID = new UUID((string) 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((String) row["terrain_texture_1"]); - newSettings.TerrainTexture2 = new UUID((String) row["terrain_texture_2"]); - newSettings.TerrainTexture3 = new UUID((String) row["terrain_texture_3"]); - newSettings.TerrainTexture4 = new UUID((String) 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.SunVector = new Vector3 ( - Convert.ToSingle(row["sunvectorx"]), - Convert.ToSingle(row["sunvectory"]), - Convert.ToSingle(row["sunvectorz"]) - ); - newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]); - newSettings.SunPosition = Convert.ToDouble(row["sun_position"]); - newSettings.Covenant = new UUID((String) 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; - } - - /// - /// - /// - /// - /// - private static LandData BuildLandData(IDataReader row) - { - LandData newData = new LandData(); - - newData.GlobalID = new UUID((String) 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((String)row["OwnerUUID"]); - newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); - newData.Area = Convert.ToInt32(row["Area"]); - newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unimplemented - 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((String) 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((String) 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.Zero; - UUID snapshotID = UUID.Zero; - - UUID.TryParse((string)row["AuthBuyerID"], out authedbuyer); - UUID.TryParse((string)row["SnapshotUUID"], out snapshotID); - newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]); - newData.Dwell = Convert.ToInt32(row["Dwell"]); - - newData.AuthBuyerID = authedbuyer; - newData.SnapshotID = snapshotID; - 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; - m_log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name); - } - - newData.ParcelAccessList = new List(); - - return newData; - } - - /// - /// - /// - /// - /// - private static ParcelManager.ParcelAccessEntry BuildLandAccessData(IDataReader row) - { - ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); - entry.AgentID = new UUID((string) row["AccessUUID"]); - entry.Flags = (AccessList) Convert.ToInt32(row["Flags"]); - entry.Time = new DateTime(); - return entry; - } - - /// - /// - /// - /// - /// - 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(); - } - - /// - /// Fill the prim command with prim values - /// - /// - /// - /// - /// - private void FillPrimCommand(MySqlCommand cmd, SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) - { - cmd.Parameters.AddWithValue("UUID", prim.UUID.ToString()); - cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); - cmd.Parameters.AddWithValue("CreationDate", prim.CreationDate); - cmd.Parameters.AddWithValue("Name", prim.Name); - cmd.Parameters.AddWithValue("SceneGroupID", sceneGroupID.ToString()); - // the UUID of the root part for this SceneObjectGroup - // various text fields - cmd.Parameters.AddWithValue("Text", prim.Text); - cmd.Parameters.AddWithValue("ColorR", prim.Color.R); - cmd.Parameters.AddWithValue("ColorG", prim.Color.G); - cmd.Parameters.AddWithValue("ColorB", prim.Color.B); - cmd.Parameters.AddWithValue("ColorA", prim.Color.A); - cmd.Parameters.AddWithValue("Description", prim.Description); - cmd.Parameters.AddWithValue("SitName", prim.SitName); - cmd.Parameters.AddWithValue("TouchName", prim.TouchName); - // permissions - cmd.Parameters.AddWithValue("ObjectFlags", prim.ObjectFlags); - cmd.Parameters.AddWithValue("CreatorID", prim.CreatorID.ToString()); - cmd.Parameters.AddWithValue("OwnerID", prim.OwnerID.ToString()); - cmd.Parameters.AddWithValue("GroupID", prim.GroupID.ToString()); - cmd.Parameters.AddWithValue("LastOwnerID", prim.LastOwnerID.ToString()); - cmd.Parameters.AddWithValue("OwnerMask", prim.OwnerMask); - cmd.Parameters.AddWithValue("NextOwnerMask", prim.NextOwnerMask); - cmd.Parameters.AddWithValue("GroupMask", prim.GroupMask); - cmd.Parameters.AddWithValue("EveryoneMask", prim.EveryoneMask); - cmd.Parameters.AddWithValue("BaseMask", prim.BaseMask); - // vectors - cmd.Parameters.AddWithValue("PositionX", (double)prim.OffsetPosition.X); - cmd.Parameters.AddWithValue("PositionY", (double)prim.OffsetPosition.Y); - cmd.Parameters.AddWithValue("PositionZ", (double)prim.OffsetPosition.Z); - cmd.Parameters.AddWithValue("GroupPositionX", (double)prim.GroupPosition.X); - cmd.Parameters.AddWithValue("GroupPositionY", (double)prim.GroupPosition.Y); - cmd.Parameters.AddWithValue("GroupPositionZ", (double)prim.GroupPosition.Z); - cmd.Parameters.AddWithValue("VelocityX", (double)prim.Velocity.X); - cmd.Parameters.AddWithValue("VelocityY", (double)prim.Velocity.Y); - cmd.Parameters.AddWithValue("VelocityZ", (double)prim.Velocity.Z); - cmd.Parameters.AddWithValue("AngularVelocityX", (double)prim.AngularVelocity.X); - cmd.Parameters.AddWithValue("AngularVelocityY", (double)prim.AngularVelocity.Y); - cmd.Parameters.AddWithValue("AngularVelocityZ", (double)prim.AngularVelocity.Z); - cmd.Parameters.AddWithValue("AccelerationX", (double)prim.Acceleration.X); - cmd.Parameters.AddWithValue("AccelerationY", (double)prim.Acceleration.Y); - cmd.Parameters.AddWithValue("AccelerationZ", (double)prim.Acceleration.Z); - // quaternions - cmd.Parameters.AddWithValue("RotationX", (double)prim.RotationOffset.X); - cmd.Parameters.AddWithValue("RotationY", (double)prim.RotationOffset.Y); - cmd.Parameters.AddWithValue("RotationZ", (double)prim.RotationOffset.Z); - cmd.Parameters.AddWithValue("RotationW", (double)prim.RotationOffset.W); - - // Sit target - Vector3 sitTargetPos = prim.SitTargetPositionLL; - cmd.Parameters.AddWithValue("SitTargetOffsetX", (double)sitTargetPos.X); - cmd.Parameters.AddWithValue("SitTargetOffsetY", (double)sitTargetPos.Y); - cmd.Parameters.AddWithValue("SitTargetOffsetZ", (double)sitTargetPos.Z); - - Quaternion sitTargetOrient = prim.SitTargetOrientationLL; - cmd.Parameters.AddWithValue("SitTargetOrientW", (double)sitTargetOrient.W); - cmd.Parameters.AddWithValue("SitTargetOrientX", (double)sitTargetOrient.X); - cmd.Parameters.AddWithValue("SitTargetOrientY", (double)sitTargetOrient.Y); - cmd.Parameters.AddWithValue("SitTargetOrientZ", (double)sitTargetOrient.Z); - - cmd.Parameters.AddWithValue("PayPrice", prim.PayPrice[0]); - cmd.Parameters.AddWithValue("PayButton1", prim.PayPrice[1]); - cmd.Parameters.AddWithValue("PayButton2", prim.PayPrice[2]); - cmd.Parameters.AddWithValue("PayButton3", prim.PayPrice[3]); - cmd.Parameters.AddWithValue("PayButton4", prim.PayPrice[4]); - - if ((prim.SoundFlags & 1) != 0) // Looped - { - cmd.Parameters.AddWithValue("LoopedSound", prim.Sound.ToString()); - cmd.Parameters.AddWithValue("LoopedSoundGain", prim.SoundGain); - } - else - { - cmd.Parameters.AddWithValue("LoopedSound", UUID.Zero); - cmd.Parameters.AddWithValue("LoopedSoundGain", 0.0f); - } - - cmd.Parameters.AddWithValue("TextureAnimation", prim.TextureAnimation); - cmd.Parameters.AddWithValue("ParticleSystem", prim.ParticleSystem); - - cmd.Parameters.AddWithValue("OmegaX", (double)prim.RotationalVelocity.X); - cmd.Parameters.AddWithValue("OmegaY", (double)prim.RotationalVelocity.Y); - cmd.Parameters.AddWithValue("OmegaZ", (double)prim.RotationalVelocity.Z); - - cmd.Parameters.AddWithValue("CameraEyeOffsetX", (double)prim.GetCameraEyeOffset().X); - cmd.Parameters.AddWithValue("CameraEyeOffsetY", (double)prim.GetCameraEyeOffset().Y); - cmd.Parameters.AddWithValue("CameraEyeOffsetZ", (double)prim.GetCameraEyeOffset().Z); - - cmd.Parameters.AddWithValue("CameraAtOffsetX", (double)prim.GetCameraAtOffset().X); - cmd.Parameters.AddWithValue("CameraAtOffsetY", (double)prim.GetCameraAtOffset().Y); - cmd.Parameters.AddWithValue("CameraAtOffsetZ", (double)prim.GetCameraAtOffset().Z); - - if (prim.GetForceMouselook()) - cmd.Parameters.AddWithValue("ForceMouselook", 1); - else - cmd.Parameters.AddWithValue("ForceMouselook", 0); - - cmd.Parameters.AddWithValue("ScriptAccessPin", prim.ScriptAccessPin); - - if (prim.AllowedDrop) - cmd.Parameters.AddWithValue("AllowedDrop", 1); - else - cmd.Parameters.AddWithValue("AllowedDrop", 0); - - if (prim.DIE_AT_EDGE) - cmd.Parameters.AddWithValue("DieAtEdge", 1); - else - cmd.Parameters.AddWithValue("DieAtEdge", 0); - - cmd.Parameters.AddWithValue("SalePrice", prim.SalePrice); - cmd.Parameters.AddWithValue("SaleType", unchecked((sbyte)(prim.ObjectSaleType))); - - byte clickAction = prim.ClickAction; - cmd.Parameters.AddWithValue("ClickAction", unchecked((sbyte)(clickAction))); - - cmd.Parameters.AddWithValue("Material", unchecked((sbyte)(prim.Material))); - - cmd.Parameters.AddWithValue("CollisionSound", prim.CollisionSound.ToString()); - cmd.Parameters.AddWithValue("CollisionSoundVolume", prim.CollisionSoundVolume); - - if (prim.PassTouches) - cmd.Parameters.AddWithValue("PassTouches", 1); - else - cmd.Parameters.AddWithValue("PassTouches", 0); - - cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum); - } - - /// - /// - /// - /// - /// - private static void FillItemCommand(MySqlCommand cmd, TaskInventoryItem taskItem) - { - cmd.Parameters.AddWithValue("itemID", taskItem.ItemID); - cmd.Parameters.AddWithValue("primID", taskItem.ParentPartID); - cmd.Parameters.AddWithValue("assetID", taskItem.AssetID); - cmd.Parameters.AddWithValue("parentFolderID", taskItem.ParentID); - - cmd.Parameters.AddWithValue("invType", taskItem.InvType); - cmd.Parameters.AddWithValue("assetType", taskItem.Type); - - cmd.Parameters.AddWithValue("name", taskItem.Name); - cmd.Parameters.AddWithValue("description", taskItem.Description); - cmd.Parameters.AddWithValue("creationDate", taskItem.CreationDate); - cmd.Parameters.AddWithValue("creatorID", taskItem.CreatorID); - cmd.Parameters.AddWithValue("ownerID", taskItem.OwnerID); - cmd.Parameters.AddWithValue("lastOwnerID", taskItem.LastOwnerID); - cmd.Parameters.AddWithValue("groupID", taskItem.GroupID); - cmd.Parameters.AddWithValue("nextPermissions", taskItem.NextPermissions); - cmd.Parameters.AddWithValue("currentPermissions", taskItem.CurrentPermissions); - cmd.Parameters.AddWithValue("basePermissions", taskItem.BasePermissions); - cmd.Parameters.AddWithValue("everyonePermissions", taskItem.EveryonePermissions); - cmd.Parameters.AddWithValue("groupPermissions", taskItem.GroupPermissions); - cmd.Parameters.AddWithValue("flags", taskItem.Flags); - } - - /// - /// - /// - private static void FillRegionSettingsCommand(MySqlCommand cmd, RegionSettings settings) - { - cmd.Parameters.AddWithValue("RegionUUID", settings.RegionUUID.ToString()); - cmd.Parameters.AddWithValue("BlockTerraform", settings.BlockTerraform); - cmd.Parameters.AddWithValue("BlockFly", settings.BlockFly); - cmd.Parameters.AddWithValue("AllowDamage", settings.AllowDamage); - cmd.Parameters.AddWithValue("RestrictPushing", settings.RestrictPushing); - cmd.Parameters.AddWithValue("AllowLandResell", settings.AllowLandResell); - cmd.Parameters.AddWithValue("AllowLandJoinDivide", settings.AllowLandJoinDivide); - cmd.Parameters.AddWithValue("BlockShowInSearch", settings.BlockShowInSearch); - cmd.Parameters.AddWithValue("AgentLimit", settings.AgentLimit); - cmd.Parameters.AddWithValue("ObjectBonus", settings.ObjectBonus); - cmd.Parameters.AddWithValue("Maturity", settings.Maturity); - cmd.Parameters.AddWithValue("DisableScripts", settings.DisableScripts); - cmd.Parameters.AddWithValue("DisableCollisions", settings.DisableCollisions); - cmd.Parameters.AddWithValue("DisablePhysics", settings.DisablePhysics); - cmd.Parameters.AddWithValue("TerrainTexture1", settings.TerrainTexture1.ToString()); - cmd.Parameters.AddWithValue("TerrainTexture2", settings.TerrainTexture2.ToString()); - cmd.Parameters.AddWithValue("TerrainTexture3", settings.TerrainTexture3.ToString()); - cmd.Parameters.AddWithValue("TerrainTexture4", settings.TerrainTexture4.ToString()); - cmd.Parameters.AddWithValue("Elevation1NW", settings.Elevation1NW); - cmd.Parameters.AddWithValue("Elevation2NW", settings.Elevation2NW); - cmd.Parameters.AddWithValue("Elevation1NE", settings.Elevation1NE); - cmd.Parameters.AddWithValue("Elevation2NE", settings.Elevation2NE); - cmd.Parameters.AddWithValue("Elevation1SE", settings.Elevation1SE); - cmd.Parameters.AddWithValue("Elevation2SE", settings.Elevation2SE); - cmd.Parameters.AddWithValue("Elevation1SW", settings.Elevation1SW); - cmd.Parameters.AddWithValue("Elevation2SW", settings.Elevation2SW); - cmd.Parameters.AddWithValue("WaterHeight", settings.WaterHeight); - cmd.Parameters.AddWithValue("TerrainRaiseLimit", settings.TerrainRaiseLimit); - cmd.Parameters.AddWithValue("TerrainLowerLimit", settings.TerrainLowerLimit); - cmd.Parameters.AddWithValue("UseEstateSun", settings.UseEstateSun); - cmd.Parameters.AddWithValue("Sandbox", settings.Sandbox); - cmd.Parameters.AddWithValue("SunVectorX", settings.SunVector.X); - cmd.Parameters.AddWithValue("SunVectorY", settings.SunVector.Y); - cmd.Parameters.AddWithValue("SunVectorZ", settings.SunVector.Z); - cmd.Parameters.AddWithValue("FixedSun", settings.FixedSun); - cmd.Parameters.AddWithValue("SunPosition", settings.SunPosition); - cmd.Parameters.AddWithValue("Covenant", settings.Covenant.ToString()); - cmd.Parameters.AddWithValue("LoadedCreationDateTime", settings.LoadedCreationDateTime); - cmd.Parameters.AddWithValue("LoadedCreationID", settings.LoadedCreationID); - - } - - /// - /// - /// - /// - /// - /// - private static void FillLandCommand(MySqlCommand cmd, LandData land, UUID regionUUID) - { - cmd.Parameters.AddWithValue("UUID", land.GlobalID.ToString()); - cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); - cmd.Parameters.AddWithValue("LocalLandID", land.LocalID); - - // Bitmap is a byte[512] - cmd.Parameters.AddWithValue("Bitmap", land.Bitmap); - - cmd.Parameters.AddWithValue("Name", land.Name); - cmd.Parameters.AddWithValue("Description", land.Description); - cmd.Parameters.AddWithValue("OwnerUUID", land.OwnerID.ToString()); - cmd.Parameters.AddWithValue("IsGroupOwned", land.IsGroupOwned); - cmd.Parameters.AddWithValue("Area", land.Area); - cmd.Parameters.AddWithValue("AuctionID", land.AuctionID); //Unemplemented - cmd.Parameters.AddWithValue("Category", land.Category); //Enum libsecondlife.Parcel.ParcelCategory - cmd.Parameters.AddWithValue("ClaimDate", land.ClaimDate); - cmd.Parameters.AddWithValue("ClaimPrice", land.ClaimPrice); - cmd.Parameters.AddWithValue("GroupUUID", land.GroupID.ToString()); - cmd.Parameters.AddWithValue("SalePrice", land.SalePrice); - cmd.Parameters.AddWithValue("LandStatus", land.Status); //Enum. libsecondlife.Parcel.ParcelStatus - cmd.Parameters.AddWithValue("LandFlags", land.Flags); - cmd.Parameters.AddWithValue("LandingType", land.LandingType); - cmd.Parameters.AddWithValue("MediaAutoScale", land.MediaAutoScale); - cmd.Parameters.AddWithValue("MediaTextureUUID", land.MediaID.ToString()); - cmd.Parameters.AddWithValue("MediaURL", land.MediaURL); - cmd.Parameters.AddWithValue("MusicURL", land.MusicURL); - cmd.Parameters.AddWithValue("PassHours", land.PassHours); - cmd.Parameters.AddWithValue("PassPrice", land.PassPrice); - cmd.Parameters.AddWithValue("SnapshotUUID", land.SnapshotID.ToString()); - cmd.Parameters.AddWithValue("UserLocationX", land.UserLocation.X); - cmd.Parameters.AddWithValue("UserLocationY", land.UserLocation.Y); - cmd.Parameters.AddWithValue("UserLocationZ", land.UserLocation.Z); - cmd.Parameters.AddWithValue("UserLookAtX", land.UserLookAt.X); - cmd.Parameters.AddWithValue("UserLookAtY", land.UserLookAt.Y); - cmd.Parameters.AddWithValue("UserLookAtZ", land.UserLookAt.Z); - cmd.Parameters.AddWithValue("AuthBuyerID", land.AuthBuyerID); - cmd.Parameters.AddWithValue("OtherCleanTime", land.OtherCleanTime); - cmd.Parameters.AddWithValue("Dwell", land.Dwell); - } - - /// - /// - /// - /// - /// - /// - private static void FillLandAccessCommand(MySqlCommand cmd, ParcelManager.ParcelAccessEntry entry, UUID parcelID) - { - cmd.Parameters.AddWithValue("LandUUID", parcelID.ToString()); - cmd.Parameters.AddWithValue("AccessUUID", entry.AgentID.ToString()); - cmd.Parameters.AddWithValue("Flags", entry.Flags); - } - - /// - /// - /// - /// - /// - private PrimitiveBaseShape BuildShape(IDataReader row) - { - PrimitiveBaseShape s = new PrimitiveBaseShape(); - s.Scale = new Vector3( - Convert.ToSingle(row["ScaleX"]), - Convert.ToSingle(row["ScaleY"]), - Convert.ToSingle(row["ScaleZ"]) - ); - // paths - s.PCode = Convert.ToByte(row["PCode"]); - s.PathBegin = Convert.ToUInt16(row["PathBegin"]); - s.PathEnd = Convert.ToUInt16(row["PathEnd"]); - s.PathScaleX = Convert.ToByte(row["PathScaleX"]); - s.PathScaleY = Convert.ToByte(row["PathScaleY"]); - s.PathShearX = Convert.ToByte(row["PathShearX"]); - s.PathShearY = Convert.ToByte(row["PathShearY"]); - s.PathSkew = Convert.ToSByte(row["PathSkew"]); - s.PathCurve = Convert.ToByte(row["PathCurve"]); - s.PathRadiusOffset = Convert.ToSByte(row["PathRadiusOffset"]); - s.PathRevolutions = Convert.ToByte(row["PathRevolutions"]); - s.PathTaperX = Convert.ToSByte(row["PathTaperX"]); - s.PathTaperY = Convert.ToSByte(row["PathTaperY"]); - s.PathTwist = Convert.ToSByte(row["PathTwist"]); - s.PathTwistBegin = Convert.ToSByte(row["PathTwistBegin"]); - // profile - s.ProfileBegin = Convert.ToUInt16(row["ProfileBegin"]); - s.ProfileEnd = Convert.ToUInt16(row["ProfileEnd"]); - s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]); - s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]); - byte[] textureEntry = (byte[]) row["Texture"]; - s.TextureEntry = textureEntry; - - s.ExtraParams = (byte[]) row["ExtraParams"]; - - s.State = Convert.ToByte(row["State"]); - - return s; - } - - /// - /// - /// - /// - /// - private void FillShapeCommand(MySqlCommand cmd, SceneObjectPart prim) - { - PrimitiveBaseShape s = prim.Shape; - cmd.Parameters.AddWithValue("UUID", prim.UUID.ToString()); - // shape is an enum - cmd.Parameters.AddWithValue("Shape", 0); - // vectors - cmd.Parameters.AddWithValue("ScaleX", (double)s.Scale.X); - cmd.Parameters.AddWithValue("ScaleY", (double)s.Scale.Y); - cmd.Parameters.AddWithValue("ScaleZ", (double)s.Scale.Z); - // paths - cmd.Parameters.AddWithValue("PCode", s.PCode); - cmd.Parameters.AddWithValue("PathBegin", s.PathBegin); - cmd.Parameters.AddWithValue("PathEnd", s.PathEnd); - cmd.Parameters.AddWithValue("PathScaleX", s.PathScaleX); - cmd.Parameters.AddWithValue("PathScaleY", s.PathScaleY); - cmd.Parameters.AddWithValue("PathShearX", s.PathShearX); - cmd.Parameters.AddWithValue("PathShearY", s.PathShearY); - cmd.Parameters.AddWithValue("PathSkew", s.PathSkew); - cmd.Parameters.AddWithValue("PathCurve", s.PathCurve); - cmd.Parameters.AddWithValue("PathRadiusOffset", s.PathRadiusOffset); - cmd.Parameters.AddWithValue("PathRevolutions", s.PathRevolutions); - cmd.Parameters.AddWithValue("PathTaperX", s.PathTaperX); - cmd.Parameters.AddWithValue("PathTaperY", s.PathTaperY); - cmd.Parameters.AddWithValue("PathTwist", s.PathTwist); - cmd.Parameters.AddWithValue("PathTwistBegin", s.PathTwistBegin); - // profile - cmd.Parameters.AddWithValue("ProfileBegin", s.ProfileBegin); - cmd.Parameters.AddWithValue("ProfileEnd", s.ProfileEnd); - cmd.Parameters.AddWithValue("ProfileCurve", s.ProfileCurve); - cmd.Parameters.AddWithValue("ProfileHollow", s.ProfileHollow); - cmd.Parameters.AddWithValue("Texture", s.TextureEntry); - cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams); - cmd.Parameters.AddWithValue("State", s.State); - } - - public void StorePrimInventory(UUID primID, ICollection items) - { - lock (m_Connection) - { - RemoveItems(primID); - - MySqlCommand cmd = m_Connection.CreateCommand(); - - if (items.Count == 0) - return; - - cmd.CommandText = "insert into primitems ("+ - "invType, assetType, name, "+ - "description, creationDate, nextPermissions, "+ - "currentPermissions, basePermissions, "+ - "everyonePermissions, groupPermissions, "+ - "flags, itemID, primID, assetID, "+ - "parentFolderID, creatorID, ownerID, "+ - "groupID, lastOwnerID) values (?invType, "+ - "?assetType, ?name, ?description, "+ - "?creationDate, ?nextPermissions, "+ - "?currentPermissions, ?basePermissions, "+ - "?everyonePermissions, ?groupPermissions, "+ - "?flags, ?itemID, ?primID, ?assetID, "+ - "?parentFolderID, ?creatorID, ?ownerID, "+ - "?groupID, ?lastOwnerID)"; - - foreach (TaskInventoryItem item in items) - { - cmd.Parameters.Clear(); - - FillItemCommand(cmd, item); - - ExecuteNonQuery(cmd); - } - - cmd.Dispose(); - } + return false; } } } From a251864e64223e8f797e20d016952b422685e447 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 16 Sep 2009 17:56:24 +0100 Subject: [PATCH 02/10] Add the migration for scoping grid data --- OpenSim/Data/MySQL/Resources/003_GridStore.sql | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 OpenSim/Data/MySQL/Resources/003_GridStore.sql diff --git a/OpenSim/Data/MySQL/Resources/003_GridStore.sql b/OpenSim/Data/MySQL/Resources/003_GridStore.sql new file mode 100644 index 0000000000..bc3fe7df7a --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/003_GridStore.sql @@ -0,0 +1,7 @@ +BEGIN; + +ALTER TABLE regions add column ScopeID char(36) not null default '00000000-0000-0000-0000-000000000000'; + +create index ScopeID on regions(ScopeID); + +COMMIT; From df7904c58b76eaa4fee771383e26b4b8e75d1abf Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 16 Sep 2009 18:20:08 +0100 Subject: [PATCH 03/10] Add the Null storage implementation for the RegionData service. Standalones have no regions table, so this is needed --- OpenSim/Data/Null/NullRegionData.cs | 136 ++++++++++++++++++++++++++++ prebuild.xml | 1 + 2 files changed, 137 insertions(+) create mode 100644 OpenSim/Data/Null/NullRegionData.cs diff --git a/OpenSim/Data/Null/NullRegionData.cs b/OpenSim/Data/Null/NullRegionData.cs new file mode 100644 index 0000000000..588b8ace5c --- /dev/null +++ b/OpenSim/Data/Null/NullRegionData.cs @@ -0,0 +1,136 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Data; + +namespace OpenSim.Data.Null +{ + public class NullRegionData : IRegionData + { + Dictionary m_regionData = new Dictionary(); + + public NullRegionData(string connectionString, string realm) + { + } + + public List Get(string regionName, UUID scopeID) + { + List ret = new List(); + + foreach(RegionData r in m_regionData.Values) + { + if (regionName.Contains("%")) + { + if (r.RegionName.Contains(regionName.Replace("%", ""))) + ret.Add(r); + } + else + { + if (r.RegionName == regionName) + ret.Add(r); + } + } + + if (ret.Count > 0) + return ret; + + return null; + } + + public RegionData Get(int posX, int posY, UUID scopeID) + { + List ret = new List(); + + foreach(RegionData r in m_regionData.Values) + { + if (r.posX == posX && r.posY == posY) + ret.Add(r); + } + + if (ret.Count > 0) + return ret[0]; + + return null; + } + + public RegionData Get(UUID regionID, UUID scopeID) + { + if (m_regionData.ContainsKey(regionID)) + return m_regionData[regionID]; + + return null; + } + + public List Get(int startX, int startY, int endX, int endY, UUID scopeID) + { + List ret = new List(); + + foreach(RegionData r in m_regionData.Values) + { + if (r.posX >= startX && r.posX <= endX && r.posY >= startY && r.posY <= endY) + ret.Add(r); + } + + if (ret.Count > 0) + return ret; + + return null; + } + + public bool Store(RegionData data) + { + m_regionData[data.RegionID] = data; + + return true; + } + + public bool SetDataItem(UUID regionID, string item, string value) + { + if (!m_regionData.ContainsKey(regionID)) + return false; + + m_regionData[regionID].Data[item] = value; + + return true; + } + + public bool Delete(UUID regionID) + { + if (!m_regionData.ContainsKey(regionID)) + return false; + + m_regionData.Remove(regionID); + + return true; + } + } +} diff --git a/prebuild.xml b/prebuild.xml index 87925eaf66..79c767c1f8 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1819,6 +1819,7 @@ ../../../bin/ + From f42d085ab17098709bcba0c816c9742a213d3c01 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Wed, 16 Sep 2009 15:06:08 -0700 Subject: [PATCH 04/10] SceneObjectGroup cleanup. Removes the default constructor and unnecessary null checks on m_rootPart --- .../Data/NHibernate/NHibernateRegionData.cs | 32 +++-- OpenSim/Data/SQLite/SQLiteRegionData.cs | 3 +- OpenSim/Data/Tests/BasicRegionTest.cs | 6 +- .../Examples/SimpleModule/ComplexObject.cs | 4 - .../Framework/Scenes/SceneObjectGroup.cs | 114 +++++------------- .../Serialization/SceneObjectSerializer.cs | 53 ++++---- .../Scenes/Tests/EntityManagerTests.cs | 4 +- .../Scenes/Tests/ScenePresenceTests.cs | 3 +- .../PointMetaEntity.cs | 3 +- 9 files changed, 80 insertions(+), 142 deletions(-) diff --git a/OpenSim/Data/NHibernate/NHibernateRegionData.cs b/OpenSim/Data/NHibernate/NHibernateRegionData.cs index 26ec5003d7..673ca6f7d1 100644 --- a/OpenSim/Data/NHibernate/NHibernateRegionData.cs +++ b/OpenSim/Data/NHibernate/NHibernateRegionData.cs @@ -178,25 +178,38 @@ namespace OpenSim.Data.NHibernate private SceneObjectGroup LoadObject(UUID uuid, UUID region) { - SceneObjectGroup group = new SceneObjectGroup(); - ICriteria criteria = manager.GetSession().CreateCriteria(typeof(SceneObjectPart)); criteria.Add(Expression.Eq("RegionID", region)); criteria.Add(Expression.Eq("ParentUUID", uuid)); criteria.AddOrder(Order.Asc("ParentID")); - foreach (SceneObjectPart p in criteria.List()) + IList parts = criteria.List(); + + SceneObjectGroup group = null; + + // Find the root part + for (int i = 0; i < parts.Count; i++) { - // root part - if (p.UUID == uuid) + if (parts[i].UUID == uuid) { - group.SetRootPart(p); + group = new SceneObjectGroup(parts[i]); + break; } - else + } + + // Add the children parts + if (group != null) + { + for (int i = 0; i < parts.Count; i++) { - group.AddPart(p); + if (parts[i].UUID != uuid) + group.AddPart(parts[i]); } } + else + { + m_log.Error("[NHIBERNATE]: LoadObject() Attempted to load a SceneObjectGroup with no root SceneObjectPart "); + } return group; } @@ -237,8 +250,7 @@ namespace OpenSim.Data.NHibernate // root part if (p.UUID == p.ParentUUID) { - SceneObjectGroup group = new SceneObjectGroup(); - group.SetRootPart(p); + SceneObjectGroup group = new SceneObjectGroup(p); SOG.Add(p.ParentUUID, group); } else diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs index 0259ac58f5..ea076fe657 100644 --- a/OpenSim/Data/SQLite/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs @@ -416,7 +416,6 @@ namespace OpenSim.Data.SQLite if (uuid == objID) //is new SceneObjectGroup ? { - SceneObjectGroup group = new SceneObjectGroup(); prim = buildPrim(primRow); DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString()); if (shapeRow != null) @@ -430,7 +429,7 @@ namespace OpenSim.Data.SQLite prim.Shape = PrimitiveBaseShape.Default; } - group.SetRootPart(prim); + SceneObjectGroup group = new SceneObjectGroup(prim); createdObjects.Add(group.UUID, group); retvals.Add(group); LoadItems(prim); diff --git a/OpenSim/Data/Tests/BasicRegionTest.cs b/OpenSim/Data/Tests/BasicRegionTest.cs index 8474921b90..c66ab7c886 100644 --- a/OpenSim/Data/Tests/BasicRegionTest.cs +++ b/OpenSim/Data/Tests/BasicRegionTest.cs @@ -322,9 +322,8 @@ namespace OpenSim.Data.Tests // This is necessary or object will not be inserted in DB sop.ObjectFlags = 0; - SceneObjectGroup sog = new SceneObjectGroup(); + SceneObjectGroup sog = new SceneObjectGroup(sop); sog.SetScene(scene); // Reguired by nhibernate database module. - sog.SetRootPart(sop); // Inserts group in DB db.StoreObject(sog,region3); @@ -1003,9 +1002,8 @@ namespace OpenSim.Data.Tests sop.UUID = uuid; sop.Shape = PrimitiveBaseShape.Default; - SceneObjectGroup sog = new SceneObjectGroup(); + SceneObjectGroup sog = new SceneObjectGroup(sop); sog.SetScene(scene); - sog.SetRootPart(sop); return sog; } diff --git a/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs b/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs index f9c3fa68c1..3809749fa5 100644 --- a/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs +++ b/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs @@ -73,10 +73,6 @@ namespace OpenSim.Region.Examples.SimpleModule base.UpdateMovement(); } - public ComplexObject() - { - } - public ComplexObject(Scene scene, ulong regionHandle, UUID ownerID, uint localID, Vector3 pos) : base(ownerID, pos, PrimitiveBaseShape.Default) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 6ba7e41309..3c17bbe9dd 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -250,16 +250,7 @@ namespace OpenSim.Region.Framework.Scenes /// public override Vector3 AbsolutePosition { - get - { - if (m_rootPart == null) - { - throw new NullReferenceException( - string.Format("[SCENE OBJECT GROUP]: Object {0} has no root part.", m_uuid)); - } - - return m_rootPart.GroupPosition; - } + get { return m_rootPart.GroupPosition; } set { Vector3 val = value; @@ -291,41 +282,19 @@ namespace OpenSim.Region.Framework.Scenes public override uint LocalId { - get - { - if (m_rootPart == null) - { - m_log.Error("[SCENE OBJECT GROUP]: Unable to find the rootpart for a LocalId Request!"); - return 0; - } - - return m_rootPart.LocalId; - } + get { return m_rootPart.LocalId; } set { m_rootPart.LocalId = value; } } public override UUID UUID { - get { - if (m_rootPart == null) - { - m_log.Error("Got a null rootpart while requesting UUID. Called from: ", new Exception()); - return UUID.Zero; - } - else return m_rootPart.UUID; - } + get { return m_rootPart.UUID; } set { m_rootPart.UUID = value; } } public UUID OwnerID { - get - { - if (m_rootPart == null) - return UUID.Zero; - - return m_rootPart.OwnerID; - } + get { return m_rootPart.OwnerID; } set { m_rootPart.OwnerID = value; } } @@ -366,7 +335,7 @@ namespace OpenSim.Region.Framework.Scenes { m_isSelected = value; // Tell physics engine that group is selected - if (m_rootPart != null && m_rootPart.PhysActor != null) + if (m_rootPart.PhysActor != null) { m_rootPart.PhysActor.Selected = value; // Pass it on to the children. @@ -398,13 +367,6 @@ namespace OpenSim.Region.Framework.Scenes #region Constructors - /// - /// Constructor - /// - public SceneObjectGroup() - { - } - /// /// This constructor creates a SceneObjectGroup using a pre-existing SceneObjectPart. /// The original SceneObjectPart will be used rather than a copy, preserving @@ -419,9 +381,8 @@ namespace OpenSim.Region.Framework.Scenes /// Constructor. This object is added to the scene later via AttachToScene() /// public SceneObjectGroup(UUID ownerID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape) - { - Vector3 rootOffset = new Vector3(0, 0, 0); - SetRootPart(new SceneObjectPart(ownerID, shape, pos, rot, rootOffset)); + { + SetRootPart(new SceneObjectPart(ownerID, shape, pos, rot, Vector3.Zero)); } /// @@ -462,11 +423,7 @@ namespace OpenSim.Region.Framework.Scenes public UUID GetFromItemID() { - if (m_rootPart != null) - { - return m_rootPart.FromItemID; - } - return UUID.Zero; + return m_rootPart.FromItemID; } /// @@ -958,11 +915,7 @@ namespace OpenSim.Region.Framework.Scenes public byte GetAttachmentPoint() { - if (m_rootPart != null) - { - return m_rootPart.Shape.State; - } - return (byte)0; + return m_rootPart.Shape.State; } public void ClearPartAttachmentData() @@ -1071,7 +1024,10 @@ namespace OpenSim.Region.Framework.Scenes /// /// public void SetRootPart(SceneObjectPart part) - { + { + if (part == null) + throw new ArgumentNullException("Cannot give SceneObjectGroup a null root SceneObjectPart"); + part.SetParent(this); m_rootPart = part; if (!IsAttachment) @@ -1224,7 +1180,7 @@ namespace OpenSim.Region.Framework.Scenes if (!silent) { - if (m_rootPart != null && part == m_rootPart) + if (part == m_rootPart) avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); } } @@ -1447,7 +1403,7 @@ namespace OpenSim.Region.Framework.Scenes /// internal void SendPartFullUpdate(IClientAPI remoteClient, SceneObjectPart part, uint clientFlags) { - if (m_rootPart != null && m_rootPart.UUID == part.UUID) + if (m_rootPart.UUID == part.UUID) { if (IsAttachment) { @@ -1881,12 +1837,6 @@ namespace OpenSim.Region.Framework.Scenes if (m_isDeleted) return; - // This is what happens when an orphanced link set child prim's - // group was queued when it was linked - // - if (m_rootPart == null) - return; - // Even temporary objects take part in physics (e.g. temp-on-rez bullets) //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) // return; @@ -3129,26 +3079,22 @@ namespace OpenSim.Region.Framework.Scenes int yaxis = 4; int zaxis = 8; - if (m_rootPart != null) + setX = ((axis & xaxis) != 0) ? true : false; + setY = ((axis & yaxis) != 0) ? true : false; + setZ = ((axis & zaxis) != 0) ? true : false; + + float setval = (rotate10 > 0) ? 1f : 0f; + + if (setX) + m_rootPart.RotationAxis.X = setval; + if (setY) + m_rootPart.RotationAxis.Y = setval; + if (setZ) + m_rootPart.RotationAxis.Z = setval; + + if (setX || setY || setZ) { - setX = ((axis & xaxis) != 0) ? true : false; - setY = ((axis & yaxis) != 0) ? true : false; - setZ = ((axis & zaxis) != 0) ? true : false; - - float setval = (rotate10 > 0) ? 1f : 0f; - - if (setX) - m_rootPart.RotationAxis.X = setval; - if (setY) - m_rootPart.RotationAxis.Y = setval; - if (setZ) - m_rootPart.RotationAxis.Z = setval; - - if (setX || setY || setZ) - { - m_rootPart.SetPhysicsAxisRotation(); - } - + m_rootPart.SetPhysicsAxisRotation(); } } diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 5ae81cd071..fe741589bf 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -65,8 +65,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); //int time = System.Environment.TickCount; - SceneObjectGroup sceneObject = new SceneObjectGroup(); - // libomv.types changes UUID to Guid xmlData = xmlData.Replace("", ""); xmlData = xmlData.Replace("", ""); @@ -88,17 +86,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization parts = doc.GetElementsByTagName("RootPart"); if (parts.Count == 0) - { throw new Exception("Invalid Xml format - no root part"); - } - else - { - sr = new StringReader(parts[0].InnerXml); - reader = new XmlTextReader(sr); - sceneObject.SetRootPart(SceneObjectPart.FromXml(fromUserInventoryItemID, reader)); - reader.Close(); - sr.Close(); - } + + sr = new StringReader(parts[0].InnerXml); + reader = new XmlTextReader(sr); + SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(fromUserInventoryItemID, reader)); + reader.Close(); + sr.Close(); parts = doc.GetElementsByTagName("Part"); @@ -119,16 +113,15 @@ namespace OpenSim.Region.Framework.Scenes.Serialization // Script state may, or may not, exist. Not having any, is NOT // ever a problem. sceneObject.LoadScriptState(doc); + + return sceneObject; } catch (Exception e) { m_log.ErrorFormat( "[SERIALIZER]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData); + return null; } - - //m_log.DebugFormat("[SERIALIZER]: Finished deserialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time); - - return sceneObject; } /// @@ -194,8 +187,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization { //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); //int time = System.Environment.TickCount; - - SceneObjectGroup sceneObject = new SceneObjectGroup(); // libomv.types changes UUID to Guid xmlData = xmlData.Replace("", ""); @@ -212,21 +203,23 @@ namespace OpenSim.Region.Framework.Scenes.Serialization XmlNodeList parts = doc.GetElementsByTagName("SceneObjectPart"); - // Process the root part first - if (parts.Count > 0) + if (parts.Count == 0) { - StringReader sr = new StringReader(parts[0].OuterXml); - XmlTextReader reader = new XmlTextReader(sr); - sceneObject.SetRootPart(SceneObjectPart.FromXml(reader)); - reader.Close(); - sr.Close(); + m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed: No SceneObjectPart nodes. xml was " + xmlData); + return null; } + StringReader sr = new StringReader(parts[0].OuterXml); + XmlTextReader reader = new XmlTextReader(sr); + SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader)); + reader.Close(); + sr.Close(); + // Then deal with the rest for (int i = 1; i < parts.Count; i++) { - StringReader sr = new StringReader(parts[i].OuterXml); - XmlTextReader reader = new XmlTextReader(sr); + sr = new StringReader(parts[i].OuterXml); + reader = new XmlTextReader(sr); SceneObjectPart part = SceneObjectPart.FromXml(reader); sceneObject.AddPart(part); part.StoreUndoState(); @@ -238,15 +231,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization // ever a problem. sceneObject.LoadScriptState(doc); + return sceneObject; } catch (Exception e) { m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData); + return null; } - - //m_log.DebugFormat("[SERIALIZER]: Finished deserialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time); - - return sceneObject; } /// diff --git a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs index bb8f27d35d..3b0e77f4bd 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs @@ -128,7 +128,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests private SceneObjectGroup NewSOG() { - SceneObjectGroup sog = new SceneObjectGroup(); SceneObjectPart sop = new SceneObjectPart(UUID.Random(), PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero); sop.Name = RandomName(); sop.Description = sop.Name; @@ -136,9 +135,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests sop.SitName = RandomName(); sop.TouchName = RandomName(); sop.ObjectFlags |= (uint)PrimFlags.Phantom; - - sog.SetRootPart(sop); + SceneObjectGroup sog = new SceneObjectGroup(sop); scene.AddNewSceneObject(sog, false); return sog; diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs index 7fb2d25878..19c0fea4c8 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs @@ -407,9 +407,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests sop.Shape.State = 1; sop.OwnerID = agent; - SceneObjectGroup sog = new SceneObjectGroup(); + SceneObjectGroup sog = new SceneObjectGroup(sop); sog.SetScene(scene); - sog.SetRootPart(sop); return sog; } diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs index 59b7289546..fbe43d6450 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs @@ -66,7 +66,6 @@ namespace OpenSim.Region.OptionalModules.ContentManagement private void CreatePointEntity(Scene scene, UUID uuid, Vector3 groupPos) { - SceneObjectGroup x = new SceneObjectGroup(); SceneObjectPart y = new SceneObjectPart(); //Initialize part @@ -93,8 +92,8 @@ namespace OpenSim.Region.OptionalModules.ContentManagement y.TrimPermissions(); //Initialize group and add part as root part + SceneObjectGroup x = new SceneObjectGroup(y); x.SetScene(scene); - x.SetRootPart(y); x.RegionHandle = scene.RegionInfo.RegionHandle; x.SetScene(scene); From 69ef95693ae6451e2c754b22190557f3bf15777b Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 17 Sep 2009 15:38:17 +0100 Subject: [PATCH 05/10] Thank you, mcortez, for a patch to address showing users in group list Removed patch 0005, which was unrelated and likely accidental, and further didn't apply. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 102 +++++++++++++----- .../XmlRpcGroupsServicesConnectorModule.cs | 42 +++++--- 2 files changed, 100 insertions(+), 44 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 37e1ed4dc7..d5cbfd43f7 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -281,7 +281,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) { - GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); + GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID); remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); } @@ -485,6 +488,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups bucket[18] = 0; //dunno } + m_groupData.AddGroupNotice(GetClientGroupRequestID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); if (OnNewGroupNotice != null) { @@ -494,7 +498,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Send notice out to everyone that wants notices foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), GroupID)) { - if (member.AcceptNotices) + if (m_debugEnabled) + { + UserProfileData targetUserProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(member.AgentID); + if (targetUserProfile != null) + { + m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUserProfile.Name, member.AcceptNotices); + } + else + { + m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, member.AgentID, member.AcceptNotices); + } + } + + if (member.AcceptNotices) { // Build notice IIM GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); @@ -614,13 +631,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); List data = m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), groupID); - if (m_debugEnabled) - { - foreach (GroupMembersData member in data) - { - m_log.DebugFormat("[GROUPS]: {0} {1}", member.AgentID, member.Title); - } - } return data; @@ -632,14 +642,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List data = m_groupData.GetGroupRoles(GetClientGroupRequestID(remoteClient), groupID); - if (m_debugEnabled) - { - foreach (GroupRolesData member in data) - { - m_log.DebugFormat("[GROUPS]: {0} {1}", member.Title, member.Members); - } - } - return data; } @@ -650,14 +652,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List data = m_groupData.GetGroupRoleMembers(GetClientGroupRequestID(remoteClient), groupID); - if (m_debugEnabled) - { - foreach (GroupRoleMembersData member in data) - { - m_log.DebugFormat("[GROUPS]: Av: {0} Role: {1}", member.MemberID, member.RoleID); - } - } - return data; @@ -808,7 +802,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // TODO: Security Checks? + // Security Checks are handled in the Groups Service. GroupRequestID grID = GetClientGroupRequestID(remoteClient); @@ -825,6 +819,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups case OpenMetaverse.GroupRoleUpdate.UpdateAll: case OpenMetaverse.GroupRoleUpdate.UpdateData: case OpenMetaverse.GroupRoleUpdate.UpdatePowers: + if (m_debugEnabled) + { + GroupPowers gp = (GroupPowers)powers; + m_log.DebugFormat("[GROUPS]: Role ({0}) updated with Powers ({1}) ({2})", name, powers.ToString(), gp.ToString()); + } m_groupData.UpdateGroupRole(grID, groupID, roleID, name, description, title, powers); break; @@ -1195,6 +1194,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (GroupMembershipData membership in data) { + if (remoteClient.AgentId != dataForAgentID) + { + if (!membership.ListInProfile) + { + // If we're sending group info to remoteclient about another agent, + // filter out groups the other agent doesn't want to share. + continue; + } + } + OSDMap GroupDataMap = new OSDMap(6); OSDMap NewGroupDataMap = new OSDMap(1); @@ -1281,11 +1290,46 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // to the core Groups Stub remoteClient.SendGroupMembership(new GroupMembershipData[0]); - GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), dataForAgentID).ToArray(); + GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, dataForAgentID); + SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); + remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray); - SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipData); - remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipData); + } + /// + /// Get a list of groups memberships for the agent that are marked "ListInProfile" + /// + /// + /// + private GroupMembershipData[] GetProfileListedGroupMemberships(IClientAPI requestingClient, UUID dataForAgentID) + { + List membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(requestingClient), dataForAgentID); + GroupMembershipData[] membershipArray; + + if (requestingClient.AgentId != dataForAgentID) + { + Predicate showInProfile = delegate(GroupMembershipData membership) + { + return membership.ListInProfile; + }; + + membershipArray = membershipData.FindAll(showInProfile).ToArray(); + } + else + { + membershipArray = membershipData.ToArray(); + } + + if (m_debugEnabled) + { + m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); + foreach (GroupMembershipData membership in membershipArray) + { + m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2}", dataForAgentID, membership.GroupName, membership.GroupTitle); + } + } + + return membershipArray; } private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index b3eaa37e06..805c3d4c83 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -855,16 +855,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups IList parameters = new ArrayList(); parameters.Add(param); - XmlRpcRequest req; - if (!m_disableKeepAlive) - { - req = new XmlRpcRequest(function, parameters); - } - else - { - // This seems to solve a major problem on some windows servers - req = new NoKeepAliveXmlRpcRequest(function, parameters); - } + ConfigurableKeepAliveXmlRpcRequest req; + req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive); XmlRpcResponse resp = null; @@ -874,10 +866,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } catch (Exception e) { + + m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString()); - + foreach( string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine },StringSplitOptions.None)) + { + m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", ResponseLine); + } + foreach (string key in param.Keys) { m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString()); @@ -961,20 +959,24 @@ namespace Nwc.XmlRpc using System.Reflection; /// Class supporting the request side of an XML-RPC transaction. - public class NoKeepAliveXmlRpcRequest : XmlRpcRequest + public class ConfigurableKeepAliveXmlRpcRequest : XmlRpcRequest { private Encoding _encoding = new ASCIIEncoding(); private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer(); private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer(); + private bool _disableKeepAlive = true; + + public string RequestResponse = String.Empty; /// Instantiate an XmlRpcRequest for a specified method and parameters. /// String designating the object.method on the server the request /// should be directed to. /// ArrayList of XML-RPC type parameters to invoke the request with. - public NoKeepAliveXmlRpcRequest(String methodName, IList parameters) + public ConfigurableKeepAliveXmlRpcRequest(String methodName, IList parameters, bool disableKeepAlive) { MethodName = methodName; _params = parameters; + _disableKeepAlive = disableKeepAlive; } /// Send the request to the server. @@ -989,7 +991,7 @@ namespace Nwc.XmlRpc request.Method = "POST"; request.ContentType = "text/xml"; request.AllowWriteStreamBuffering = true; - request.KeepAlive = false; + request.KeepAlive = !_disableKeepAlive; Stream stream = request.GetRequestStream(); XmlTextWriter xml = new XmlTextWriter(stream, _encoding); @@ -1000,7 +1002,17 @@ namespace Nwc.XmlRpc HttpWebResponse response = (HttpWebResponse)request.GetResponse(); StreamReader input = new StreamReader(response.GetResponseStream()); - XmlRpcResponse resp = (XmlRpcResponse)_deserializer.Deserialize(input); + string inputXml = input.ReadToEnd(); + XmlRpcResponse resp; + try + { + resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml); + } + catch (Exception e) + { + RequestResponse = inputXml; + throw e; + } input.Close(); response.Close(); return resp; From 88294d9ebfcbaf1a382bb71a1fcacbe90913fbd8 Mon Sep 17 00:00:00 2001 From: Alan M Webb Date: Wed, 16 Sep 2009 17:31:14 -0400 Subject: [PATCH 06/10] While running a test case I had written to pursue problems with llDie() not always completely working, I discovered I was getting a lot (60+ over 6000 iterations of the test case) null pointer exceptions in various physics related checks in SceneObjectPart. It was apparent that the (frequent) checks for PhysActor being non-null is an insufficient protection in a highly asynchronous environment. The null reference exceptions are one example of failure, but it could also happen that a sequence started with one instance of a PhysicsActor might finish with another? Anyway, I have implemented a safer mechanism that should stop the errors. I re-ran my test case with the fix in place, and completed nearly 1000 iterations without a single occurrence. SceneObjectPart is seriously in need of rejigging, if not for this reason, then for its ridiculous size. Signed-off-by: dr scofield (aka dirk husemann) --- .../Framework/Scenes/SceneObjectPart.cs | 265 ++++++++++-------- 1 file changed, 152 insertions(+), 113 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b0d279c1a1..51bb1145dd 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -415,9 +415,10 @@ namespace OpenSim.Region.Framework.Scenes set { m_name = value; - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - PhysActor.SOPName = value; + pa.SOPName = value; } } } @@ -427,10 +428,11 @@ namespace OpenSim.Region.Framework.Scenes get { return (byte) m_material; } set { + PhysicsActor pa = PhysActor; m_material = (Material)value; - if (PhysActor != null) + if (pa != null) { - PhysActor.SetMaterial((int)value); + pa.SetMaterial((int)value); } } } @@ -501,11 +503,12 @@ namespace OpenSim.Region.Framework.Scenes get { // If this is a linkset, we don't want the physics engine mucking up our group position here. - if (PhysActor != null && _parentID == 0) + PhysicsActor pa = PhysActor; + if (pa != null && _parentID == 0) { - m_groupPosition.X = PhysActor.Position.X; - m_groupPosition.Y = PhysActor.Position.Y; - m_groupPosition.Z = PhysActor.Position.Z; + m_groupPosition.X = pa.Position.X; + m_groupPosition.Y = pa.Position.Y; + m_groupPosition.Z = pa.Position.Z; } if (IsAttachment) @@ -525,26 +528,27 @@ namespace OpenSim.Region.Framework.Scenes m_groupPosition = value; - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { try { // Root prim actually goes at Position if (_parentID == 0) { - PhysActor.Position = new PhysicsVector(value.X, value.Y, value.Z); + pa.Position = new PhysicsVector(value.X, value.Y, value.Z); } else { // To move the child prim in respect to the group position and rotation we have to calculate Vector3 resultingposition = GetWorldPosition(); - PhysActor.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z); + pa.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z); Quaternion resultingrot = GetWorldRotation(); - PhysActor.Orientation = resultingrot; + pa.Orientation = resultingrot; } // Tell the physics engines that this prim changed. - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); } catch (Exception e) { @@ -577,15 +581,16 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup != null && !ParentGroup.IsDeleted) { - if (_parentID != 0 && PhysActor != null) + PhysicsActor pa = PhysActor; + if (_parentID != 0 && pa != null) { Vector3 resultingposition = GetWorldPosition(); - PhysActor.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z); + pa.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z); Quaternion resultingrot = GetWorldRotation(); - PhysActor.Orientation = resultingrot; + pa.Orientation = resultingrot; // Tell the physics engines that this prim changed. - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); } } } @@ -595,13 +600,14 @@ namespace OpenSim.Region.Framework.Scenes { get { + PhysicsActor pa = PhysActor; // We don't want the physics engine mucking up the rotations in a linkset - if ((_parentID == 0) && (Shape.PCode != 9 || Shape.State == 0) && (PhysActor != null)) + if ((_parentID == 0) && (Shape.PCode != 9 || Shape.State == 0) && (pa != null)) { - if (PhysActor.Orientation.X != 0 || PhysActor.Orientation.Y != 0 - || PhysActor.Orientation.Z != 0 || PhysActor.Orientation.W != 0) + if (pa.Orientation.X != 0 || pa.Orientation.Y != 0 + || pa.Orientation.Z != 0 || pa.Orientation.W != 0) { - m_rotationOffset = PhysActor.Orientation; + m_rotationOffset = pa.Orientation; } } @@ -610,27 +616,28 @@ namespace OpenSim.Region.Framework.Scenes set { + PhysicsActor pa = PhysActor; StoreUndoState(); m_rotationOffset = value; - if (PhysActor != null) + if (pa != null) { try { // Root prim gets value directly if (_parentID == 0) { - PhysActor.Orientation = value; + pa.Orientation = value; //m_log.Info("[PART]: RO1:" + PhysActor.Orientation.ToString()); } else { // Child prim we have to calculate it's world rotationwel Quaternion resultingrotation = GetWorldRotation(); - PhysActor.Orientation = resultingrotation; + pa.Orientation = resultingrotation; //m_log.Info("[PART]: RO2:" + PhysActor.Orientation.ToString()); } - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); //} } catch (Exception ex) @@ -650,13 +657,14 @@ namespace OpenSim.Region.Framework.Scenes //if (PhysActor.Velocity.X != 0 || PhysActor.Velocity.Y != 0 //|| PhysActor.Velocity.Z != 0) //{ - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - if (PhysActor.IsPhysical) + if (pa.IsPhysical) { - m_velocity.X = PhysActor.Velocity.X; - m_velocity.Y = PhysActor.Velocity.Y; - m_velocity.Z = PhysActor.Velocity.Z; + m_velocity.X = pa.Velocity.X; + m_velocity.Y = pa.Velocity.Y; + m_velocity.Z = pa.Velocity.Z; } } @@ -666,12 +674,13 @@ namespace OpenSim.Region.Framework.Scenes set { m_velocity = value; - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - if (PhysActor.IsPhysical) + if (pa.IsPhysical) { - PhysActor.Velocity = new PhysicsVector(value.X, value.Y, value.Z); - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + pa.Velocity = new PhysicsVector(value.X, value.Y, value.Z); + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); } } } @@ -688,9 +697,10 @@ namespace OpenSim.Region.Framework.Scenes { get { - if ((PhysActor != null) && PhysActor.IsPhysical) + PhysicsActor pa = PhysActor; + if ((pa != null) && pa.IsPhysical) { - m_angularVelocity.FromBytes(PhysActor.RotationalVelocity.GetBytes(), 0); + m_angularVelocity.FromBytes(pa.RotationalVelocity.GetBytes(), 0); } return m_angularVelocity; } @@ -709,10 +719,11 @@ namespace OpenSim.Region.Framework.Scenes get { return m_description; } set { + PhysicsActor pa = PhysActor; m_description = value; - if (PhysActor != null) + if (pa != null) { - PhysActor.SOPDescription = value; + pa.SOPDescription = value; } } } @@ -806,14 +817,15 @@ namespace OpenSim.Region.Framework.Scenes if (m_shape != null) { m_shape.Scale = value; - if (PhysActor != null && m_parentGroup != null) + PhysicsActor pa = PhysActor; + if (pa != null && m_parentGroup != null) { if (m_parentGroup.Scene != null) { if (m_parentGroup.Scene.PhysicsScene != null) { - PhysActor.Size = new PhysicsVector(m_shape.Scale.X, m_shape.Scale.Y, m_shape.Scale.Z); - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + pa.Size = new PhysicsVector(m_shape.Scale.X, m_shape.Scale.Y, m_shape.Scale.Z); + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); } } } @@ -1343,13 +1355,14 @@ if (m_shape != null) { RigidBody); // Basic Physics returns null.. joy joy joy. - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info - PhysActor.SOPDescription = this.Description; - PhysActor.LocalID = LocalId; + pa.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info + pa.SOPDescription = this.Description; + pa.LocalID = LocalId; DoPhysicsPropertyUpdate(RigidBody, true); - PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); + pa.SetVolumeDetect(VolumeDetectActive ? 1 : 0); } } } @@ -1563,23 +1576,24 @@ if (m_shape != null) { } else { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - if (UsePhysics != PhysActor.IsPhysical || isNew) + if (UsePhysics != pa.IsPhysical || isNew) { - if (PhysActor.IsPhysical) // implies UsePhysics==false for this block + if (pa.IsPhysical) // implies UsePhysics==false for this block { if (!isNew) ParentGroup.Scene.RemovePhysicalPrim(1); - PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; - PhysActor.OnOutOfBounds -= PhysicsOutOfBounds; - PhysActor.delink(); + pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; + pa.OnOutOfBounds -= PhysicsOutOfBounds; + pa.delink(); if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) { // destroy all joints connected to this now deactivated body - m_parentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(PhysActor); + m_parentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); } // stop client-side interpolation of all joint proxy objects that have just been deleted @@ -1598,7 +1612,7 @@ if (m_shape != null) { //RotationalVelocity = new Vector3(0, 0, 0); } - PhysActor.IsPhysical = UsePhysics; + pa.IsPhysical = UsePhysics; // If we're not what we're supposed to be in the physics scene, recreate ourselves. @@ -1612,19 +1626,19 @@ if (m_shape != null) { { ParentGroup.Scene.AddPhysicalPrim(1); - PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; - PhysActor.OnOutOfBounds += PhysicsOutOfBounds; + pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; + pa.OnOutOfBounds += PhysicsOutOfBounds; if (_parentID != 0 && _parentID != LocalId) { if (ParentGroup.RootPart.PhysActor != null) { - PhysActor.link(ParentGroup.RootPart.PhysActor); + pa.link(ParentGroup.RootPart.PhysActor); } } } } } - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); } } } @@ -1690,9 +1704,10 @@ if (m_shape != null) { public Vector3 GetGeometricCenter() { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - return new Vector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z); + return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z); } else { @@ -1702,9 +1717,10 @@ if (m_shape != null) { public float GetMass() { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - return PhysActor.Mass; + return pa.Mass; } else { @@ -1714,8 +1730,9 @@ if (m_shape != null) { public PhysicsVector GetForce() { - if (PhysActor != null) - return PhysActor.Force; + PhysicsActor pa = PhysActor; + if (pa != null) + return pa.Force; else return new PhysicsVector(); } @@ -2094,11 +2111,15 @@ if (m_shape != null) { public void PhysicsRequestingTerseUpdate() { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0); + Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); - if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) + if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | + m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | + m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | + m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) { m_parentGroup.AbsolutePosition = newpos; return; @@ -2294,14 +2315,15 @@ if (m_shape != null) { if (texture != null) m_shape.SculptData = texture.Data; - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { // Tricks physics engine into thinking we've changed the part shape. PrimitiveBaseShape m_newshape = m_shape.Copy(); - PhysActor.Shape = m_newshape; + pa.Shape = m_newshape; m_shape = m_newshape; - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); } } } @@ -2520,9 +2542,10 @@ if (m_shape != null) { public void SetBuoyancy(float fvalue) { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - PhysActor.Buoyancy = fvalue; + pa.Buoyancy = fvalue; } } @@ -2538,56 +2561,62 @@ if (m_shape != null) { public void SetFloatOnWater(int floatYN) { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { if (floatYN == 1) { - PhysActor.FloatOnWater = true; + pa.FloatOnWater = true; } else { - PhysActor.FloatOnWater = false; + pa.FloatOnWater = false; } } } public void SetForce(PhysicsVector force) { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - PhysActor.Force = force; + pa.Force = force; } } public void SetVehicleType(int type) { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - PhysActor.VehicleType = type; + pa.VehicleType = type; } } public void SetVehicleFloatParam(int param, float value) { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - PhysActor.VehicleFloatParam(param, value); + pa.VehicleFloatParam(param, value); } } public void SetVehicleVectorParam(int param, PhysicsVector value) { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - PhysActor.VehicleVectorParam(param, value); + pa.VehicleVectorParam(param, value); } } public void SetVehicleRotationParam(int param, Quaternion rotation) { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - PhysActor.VehicleRotationParam(param, rotation); + pa.VehicleRotationParam(param, rotation); } } @@ -2615,10 +2644,11 @@ if (m_shape != null) { public void SetPhysicsAxisRotation() { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - PhysActor.LockAngularMotion(RotationAxis); - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + pa.LockAngularMotion(RotationAxis); + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); } } @@ -3350,8 +3380,9 @@ if (m_shape != null) { { IsVD = false; // Switch it of for the course of this routine VolumeDetectActive = false; // and also permanently - if (PhysActor != null) - PhysActor.SetVolumeDetect(0); // Let physics know about it too + PhysicsActor pa = PhysActor; + if (pa != null) + pa.SetVolumeDetect(0); // Let physics know about it too } else { @@ -3399,18 +3430,21 @@ if (m_shape != null) { if (IsPhantom || IsAttachment) // note: this may have been changed above in the case of joints { AddFlag(PrimFlags.Phantom); - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); + m_parentGroup.Scene.PhysicsScene.RemovePrim(pa); /// that's not wholesome. Had to make Scene public - PhysActor = null; + pa = null; } } else // Not phantom { RemFlag(PrimFlags.Phantom); - if (PhysActor == null) + // This is NOT safe!! + PhysicsActor pa = PhysActor; + if (pa == null) { // It's not phantom anymore. So make sure the physics engine get's knowledge of it PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( @@ -3421,9 +3455,9 @@ if (m_shape != null) { RotationOffset, UsePhysics); - if (PhysActor != null) + if (pa != null) { - PhysActor.LocalID = LocalId; + pa.LocalID = LocalId; DoPhysicsPropertyUpdate(UsePhysics, true); if (m_parentGroup != null) { @@ -3442,14 +3476,14 @@ if (m_shape != null) { (CollisionSound != UUID.Zero) ) { - PhysActor.OnCollisionUpdate += PhysicsCollision; - PhysActor.SubscribeEvents(1000); + pa.OnCollisionUpdate += PhysicsCollision; + pa.SubscribeEvents(1000); } } } else // it already has a physical representation { - PhysActor.IsPhysical = UsePhysics; + pa.IsPhysical = UsePhysics; DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim if (m_parentGroup != null) @@ -3472,9 +3506,10 @@ if (m_shape != null) { // Defensive programming calls for a check here. // Better would be throwing an exception that could be catched by a unit test as the internal // logic should make sure, this Physactor is always here. - if (this.PhysActor != null) + PhysicsActor pa = this.PhysActor; + if (pa != null) { - PhysActor.SetVolumeDetect(1); + pa.SetVolumeDetect(1); AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active this.VolumeDetectActive = true; } @@ -3482,10 +3517,11 @@ if (m_shape != null) { } else { // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like - // (mumbles, well, at least if you have infinte CPU powers :-)) - if (this.PhysActor != null) + // (mumbles, well, at least if you have infinte CPU powers :-) ) + PhysicsActor pa = this.PhysActor; + if (pa != null) { - PhysActor.SetVolumeDetect(0); + pa.SetVolumeDetect(0); } this.VolumeDetectActive = false; } @@ -3543,10 +3579,11 @@ if (m_shape != null) { m_shape.PathTaperY = shapeBlock.PathTaperY; m_shape.PathTwist = shapeBlock.PathTwist; m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - PhysActor.Shape = m_shape; - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + pa.Shape = m_shape; + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); } // This is what makes vehicle trailers work @@ -3647,19 +3684,21 @@ if (m_shape != null) { ) { // subscribe to physics updates. - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - PhysActor.OnCollisionUpdate += PhysicsCollision; - PhysActor.SubscribeEvents(1000); + pa.OnCollisionUpdate += PhysicsCollision; + pa.SubscribeEvents(1000); } } else { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + if (pa != null) { - PhysActor.UnSubscribeEvents(); - PhysActor.OnCollisionUpdate -= PhysicsCollision; + pa.UnSubscribeEvents(); + pa.OnCollisionUpdate -= PhysicsCollision; } } From 6779abf7f59e518b0cd18e52dd91a500049dfda6 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 17 Sep 2009 23:39:58 +0100 Subject: [PATCH 07/10] Remove The legacy inventory and asset servers. Bump interface version to 6 --- .../Servers/BaseGetAssetStreamHandler.cs | 205 ------- .../Servers/GetAssetStreamHandler.cs | 63 --- .../Servers/PostAssetStreamHandler.cs | 72 --- OpenSim/Framework/Servers/VersionInfo.cs | 2 +- OpenSim/Grid/AssetServer/Main.cs | 146 ----- .../AssetServer/Properties/AssemblyInfo.cs | 63 --- .../InventoryServer/AuthedSessionCache.cs | 133 ----- .../InventoryServer/GridInventoryService.cs | 256 --------- .../InventoryServer/InventoryServiceBase.cs | 519 ------------------ OpenSim/Grid/InventoryServer/Main.cs | 182 ------ prebuild.xml | 64 --- 11 files changed, 1 insertion(+), 1704 deletions(-) delete mode 100644 OpenSim/Framework/Servers/BaseGetAssetStreamHandler.cs delete mode 100644 OpenSim/Framework/Servers/GetAssetStreamHandler.cs delete mode 100644 OpenSim/Framework/Servers/PostAssetStreamHandler.cs delete mode 100644 OpenSim/Grid/AssetServer/Main.cs delete mode 100644 OpenSim/Grid/AssetServer/Properties/AssemblyInfo.cs delete mode 100644 OpenSim/Grid/InventoryServer/AuthedSessionCache.cs delete mode 100644 OpenSim/Grid/InventoryServer/GridInventoryService.cs delete mode 100644 OpenSim/Grid/InventoryServer/InventoryServiceBase.cs delete mode 100644 OpenSim/Grid/InventoryServer/Main.cs diff --git a/OpenSim/Framework/Servers/BaseGetAssetStreamHandler.cs b/OpenSim/Framework/Servers/BaseGetAssetStreamHandler.cs deleted file mode 100644 index 8372ae7af1..0000000000 --- a/OpenSim/Framework/Servers/BaseGetAssetStreamHandler.cs +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Reflection; -using System.Text; -using System.Text.RegularExpressions; -using System.Xml; -using System.Xml.Serialization; -using log4net; -using OpenMetaverse; -using OpenSim.Framework.Servers.HttpServer; -using OpenSim.Framework.Statistics; - -namespace OpenSim.Framework.Servers -{ - public abstract class BaseGetAssetStreamHandler : BaseStreamHandler - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - protected BaseGetAssetStreamHandler(string httpMethod, string path) : base(httpMethod, path) - { - } - - protected abstract AssetBase GetAsset(UUID assetID); - - public override byte[] Handle(string path, Stream request, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - byte[] result = new byte[] { }; - - string[] p = SplitParams(path); - - if (p.Length > 0) - { - UUID assetID; - - if (!UUID.TryParse(p[0], out assetID)) - { - m_log.DebugFormat( - "[REST]: GET:/asset ignoring request with malformed UUID {0}", p[0]); - return result; - } - - if (StatsManager.AssetStats != null) - { - StatsManager.AssetStats.AddRequest(); - } - - AssetBase asset = GetAsset(assetID); - - if (asset != null) - { - if (p.Length > 1 && p[1] == "data") - { - httpResponse.StatusCode = (int)HttpStatusCode.OK; - httpResponse.ContentType = SLAssetTypeToContentType(asset.Type); - result = asset.Data; - } - else - { - result = GetXml(asset); - } - } - else - { - m_log.DebugFormat("[REST]: GET:/asset failed to find {0}", assetID); - - httpResponse.StatusCode = (int)HttpStatusCode.NotFound; - - if (StatsManager.AssetStats != null) - { - StatsManager.AssetStats.AddNotFoundRequest(); - } - } - } - - return result; - } - - public static byte[] GetXml(AssetBase asset) - { - byte[] result; - XmlSerializer xs = new XmlSerializer(typeof(AssetBase)); - MemoryStream ms = new MemoryStream(); - XmlTextWriter xw = new XmlTextWriter(ms, Encoding.UTF8); - xw.Formatting = Formatting.Indented; - xs.Serialize(xw, asset); - xw.Flush(); - - ms.Seek(0, SeekOrigin.Begin); - //StreamReader sr = new StreamReader(ms); - - result = ms.GetBuffer(); - - Array.Resize(ref result, (int)ms.Length); - return result; - } - - public string ProcessAssetDataString(string data) - { - Regex regex = new Regex("(creator_id|owner_id)\\s+(\\S+)"); - - // IUserService userService = null; - - data = regex.Replace(data, delegate(Match m) - { - string result = String.Empty; - -// string key = m.Groups[1].Captures[0].Value; -// -// string value = m.Groups[2].Captures[0].Value; -// -// Guid userUri; -// -// switch (key) -// { -// case "creator_id": -// userUri = new Guid(value); -// // result = "creator_url " + userService(userService, userUri); -// break; -// -// case "owner_id": -// userUri = new Guid(value); -// // result = "owner_url " + ResolveUserUri(userService, userUri); -// break; -// } - - return result; - }); - - return data; - } - - private string SLAssetTypeToContentType(int assetType) - { - switch (assetType) - { - case 0: - return "image/jp2"; - case 1: - return "application/ogg"; - case 2: - return "application/x-metaverse-callingcard"; - case 3: - return "application/x-metaverse-landmark"; - case 5: - return "application/x-metaverse-clothing"; - case 6: - return "application/x-metaverse-primitive"; - case 7: - return "application/x-metaverse-notecard"; - case 8: - return "application/x-metaverse-folder"; - case 10: - return "application/x-metaverse-lsl"; - case 11: - return "application/x-metaverse-lso"; - case 12: - return "image/tga"; - case 13: - return "application/x-metaverse-bodypart"; - case 17: - return "audio/x-wav"; - case 19: - return "image/jpeg"; - case 20: - return "application/x-metaverse-animation"; - case 21: - return "application/x-metaverse-gesture"; - case 22: - return "application/x-metaverse-simstate"; - default: - return "application/octet-stream"; - } - } - } -} diff --git a/OpenSim/Framework/Servers/GetAssetStreamHandler.cs b/OpenSim/Framework/Servers/GetAssetStreamHandler.cs deleted file mode 100644 index c6958deb71..0000000000 --- a/OpenSim/Framework/Servers/GetAssetStreamHandler.cs +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.IO; -using System.Reflection; -using System.Text; -using System.Text.RegularExpressions; -using System.Xml; -using System.Xml.Serialization; -using log4net; -using OpenMetaverse; -using OpenSim.Data; -using OpenSim.Framework; -using OpenSim.Framework.Servers; -using OpenSim.Framework.Servers.HttpServer; -using OpenSim.Framework.Statistics; -using System.Net; - -namespace OpenSim.Framework.Servers -{ - public class GetAssetStreamHandler : BaseGetAssetStreamHandler - { - // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private readonly IAssetDataPlugin m_assetProvider; - - public GetAssetStreamHandler(IAssetDataPlugin assetProvider) - : base("GET", "/assets") - { - m_assetProvider = assetProvider; - } - - protected override AssetBase GetAsset(UUID assetID) - { - return m_assetProvider.GetAsset(assetID); - } - } -} diff --git a/OpenSim/Framework/Servers/PostAssetStreamHandler.cs b/OpenSim/Framework/Servers/PostAssetStreamHandler.cs deleted file mode 100644 index 8bf406cc5a..0000000000 --- a/OpenSim/Framework/Servers/PostAssetStreamHandler.cs +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System.IO; -using System.Reflection; -using System.Xml.Serialization; -using log4net; -using OpenMetaverse; -using OpenSim.Data; -using OpenSim.Framework; -using OpenSim.Framework.Servers.HttpServer; - -namespace OpenSim.Framework.Servers -{ - public class PostAssetStreamHandler : BaseStreamHandler - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - // private OpenAsset_Main m_assetManager; - private IAssetDataPlugin m_assetProvider; - - public override byte[] Handle(string path, Stream request, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - string param = GetParam(path); - - UUID assetId; - if (param.Length > 0) - UUID.TryParse(param, out assetId); - // byte[] txBuffer = new byte[4096]; - - XmlSerializer xs = new XmlSerializer(typeof (AssetBase)); - AssetBase asset = (AssetBase) xs.Deserialize(request); - - m_log.InfoFormat("[REST]: Creating asset {0}", asset.FullID); - m_assetProvider.StoreAsset(asset); - - return new byte[] {}; - } - - public PostAssetStreamHandler(IAssetDataPlugin assetProvider) - : base("POST", "/assets") - { - // m_assetManager = assetManager; - m_assetProvider = assetProvider; - } - } -} diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index 743ca69d6e..6f9b00c218 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -69,6 +69,6 @@ namespace OpenSim /// of the code that is too old. /// /// - public readonly static int MajorInterfaceVersion = 5; + public readonly static int MajorInterfaceVersion = 6; } } diff --git a/OpenSim/Grid/AssetServer/Main.cs b/OpenSim/Grid/AssetServer/Main.cs deleted file mode 100644 index ac8f8880c4..0000000000 --- a/OpenSim/Grid/AssetServer/Main.cs +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.IO; -using System.Reflection; -using log4net; -using log4net.Config; -using OpenMetaverse; -using OpenSim.Data; -using OpenSim.Framework; -using OpenSim.Framework.AssetLoader.Filesystem; -using OpenSim.Framework.Console; -using OpenSim.Framework.Servers; -using OpenSim.Framework.Servers.HttpServer; -using OpenSim.Framework.Statistics; - -namespace OpenSim.Grid.AssetServer -{ - /// - /// An asset server - /// - public class OpenAsset_Main : BaseOpenSimServer - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - public static OpenAsset_Main assetserver; - - // Temporarily hardcoded - should be a plugin - protected IAssetLoader assetLoader = new AssetLoaderFileSystem(); - - private IAssetDataPlugin m_assetProvider; - - public static void Main(string[] args) - { - XmlConfigurator.Configure(); - - assetserver = new OpenAsset_Main(); - assetserver.Startup(); - - assetserver.Work(); - } - - private void Work() - { - m_console.Output("Enter help for a list of commands"); - - while (true) - { - m_console.Prompt(); - } - } - - public OpenAsset_Main() - { - m_console = new LocalConsole("Asset"); - - MainConsole.Instance = m_console; - } - - protected override void StartupSpecific() - { - AssetConfig config = new AssetConfig("ASSET SERVER", (Path.Combine(Util.configDir(), "AssetServer_Config.xml"))); - - m_log.Info("[ASSET]: Setting up asset DB"); - setupDB(config); - - m_log.Info("[ASSET]: Loading default asset set from '" + config.AssetSetsLocation + "'"); - LoadDefaultAssets(config.AssetSetsLocation); - - m_log.Info("[ASSET]: Starting HTTP process"); - m_httpServer = new BaseHttpServer(config.HttpPort); - - m_stats = StatsManager.StartCollectingAssetStats(); - - AddHttpHandlers(); - - m_httpServer.Start(); - - base.StartupSpecific(); - } - - protected void AddHttpHandlers() - { - m_httpServer.AddStreamHandler(new GetAssetStreamHandler(m_assetProvider)); - m_httpServer.AddStreamHandler(new PostAssetStreamHandler(m_assetProvider)); - } - - public byte[] GetAssetData(UUID assetID, bool isTexture) - { - return null; - } - - public void setupDB(AssetConfig config) - { - try - { - m_assetProvider = DataPluginFactory.LoadDataPlugin(config.DatabaseProvider, config.DatabaseConnect); - if (m_assetProvider == null) - { - m_log.Error("[ASSET]: Failed to load a database plugin, server halting"); - Environment.Exit(-1); - } - } - catch (Exception e) - { - m_log.Warn("[ASSET]: setupDB() - Exception occured"); - m_log.Warn("[ASSET]: " + e.ToString()); - } - } - - public void LoadDefaultAssets(string pAssetSetsLocation) - { - assetLoader.ForEachDefaultXmlAsset(pAssetSetsLocation, StoreAsset); - } - - protected void StoreAsset(AssetBase asset) - { - m_assetProvider.StoreAsset(asset); - } - } -} diff --git a/OpenSim/Grid/AssetServer/Properties/AssemblyInfo.cs b/OpenSim/Grid/AssetServer/Properties/AssemblyInfo.cs deleted file mode 100644 index 5d67e3f81f..0000000000 --- a/OpenSim/Grid/AssetServer/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System.Reflection; -using System.Runtime.InteropServices; - -// General information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly : AssemblyTitle("OGS-AssetServer")] -[assembly : AssemblyDescription("")] -[assembly : AssemblyConfiguration("")] -[assembly : AssemblyCompany("http://opensimulator.org")] -[assembly : AssemblyProduct("OGS-AssetServer")] -[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")] -[assembly : AssemblyTrademark("")] -[assembly : AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly : ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly : Guid("b541b244-3d1d-4625-9003-bc2a3a6a39a4")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// - -[assembly : AssemblyVersion("0.6.5.*")] -[assembly : AssemblyFileVersion("0.6.5.0")] diff --git a/OpenSim/Grid/InventoryServer/AuthedSessionCache.cs b/OpenSim/Grid/InventoryServer/AuthedSessionCache.cs deleted file mode 100644 index dadf34a4ed..0000000000 --- a/OpenSim/Grid/InventoryServer/AuthedSessionCache.cs +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; - -namespace OpenSim.Grid.InventoryServer -{ - public class AuthedSessionCache - { - public class CacheData - { - private static readonly DateTime UNIX_EPOCH = new DateTime(1970, 1, 1); - private string m_session_id; - private string m_agent_id; - private int m_expire; - - private int get_current_unix_time() - { - return (int)(DateTime.UtcNow - UNIX_EPOCH).TotalSeconds; - } - - public CacheData(string sid, string aid) - { - m_session_id = sid; - m_agent_id = aid; - m_expire = get_current_unix_time() + DEFAULT_LIFETIME; - } - - public CacheData(string sid, string aid, int time_now) - { - m_session_id = sid; - m_agent_id = aid; - m_expire = time_now + DEFAULT_LIFETIME; - } - - public string SessionID - { - get { return m_session_id; } - set { m_session_id = value; } - } - - public string AgentID - { - get { return m_agent_id; } - set { m_agent_id = value; } - } - - public bool isExpired - { - get { return m_expire < get_current_unix_time(); } - } - - public void Renew() - { - m_expire = get_current_unix_time() + DEFAULT_LIFETIME; - } - } - - private static readonly int DEFAULT_LIFETIME = 30; - private Dictionary m_authed_sessions = new Dictionary(); - // private int m_session_lifetime = DEFAULT_LIFETIME; - - public AuthedSessionCache() - { - // m_session_lifetime = DEFAULT_LIFETIME; - } - - public AuthedSessionCache(int timeout) - { - // m_session_lifetime = timeout; - } - - public CacheData getCachedSession(string session_id, string agent_id) - { - CacheData ret = null; - lock (m_authed_sessions) - { - if (m_authed_sessions.ContainsKey(session_id)) - { - CacheData cached_session = m_authed_sessions[session_id]; - if (!cached_session.isExpired && cached_session.AgentID == agent_id) - { - ret = m_authed_sessions[session_id]; - // auto renew - m_authed_sessions[session_id].Renew(); - } - } - } - return ret; - } - - public void Add(string session_id, string agent_id) - { - CacheData data = new CacheData(session_id, agent_id); - lock (m_authed_sessions) - { - if (m_authed_sessions.ContainsKey(session_id)) - { - m_authed_sessions[session_id] = data; - } - else - { - m_authed_sessions.Add(session_id, data); - } - } - } - } -} diff --git a/OpenSim/Grid/InventoryServer/GridInventoryService.cs b/OpenSim/Grid/InventoryServer/GridInventoryService.cs deleted file mode 100644 index 0704faa9a6..0000000000 --- a/OpenSim/Grid/InventoryServer/GridInventoryService.cs +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Net; -using System.Reflection; -using log4net; -using Nwc.XmlRpc; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Framework.Communications.Cache; - -namespace OpenSim.Grid.InventoryServer -{ - /// - /// Used on a grid server to satisfy external inventory requests - /// - public class GridInventoryService : InventoryServiceBase - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private bool m_doLookup = false; - - public bool DoLookup - { - get { return m_doLookup; } - set { m_doLookup = value; } - } - - private static readonly int INVENTORY_DEFAULT_SESSION_TIME = 30; // secs - - private string m_userserver_url; - private AuthedSessionCache m_session_cache = new AuthedSessionCache(INVENTORY_DEFAULT_SESSION_TIME); - - public GridInventoryService(string userserver_url) - { - m_userserver_url = userserver_url; - } - - /// - /// Check that the source of an inventory request is one that we trust. - /// - /// - /// - public bool CheckTrustSource(IPEndPoint peer) - { - if (m_doLookup) - { - m_log.InfoFormat("[GRID AGENT INVENTORY]: Checking trusted source {0}", peer); - UriBuilder ub = new UriBuilder(m_userserver_url); - IPAddress[] uaddrs = Dns.GetHostAddresses(ub.Host); - foreach (IPAddress uaddr in uaddrs) - { - if (uaddr.Equals(peer.Address)) - { - return true; - } - } - - m_log.WarnFormat( - "[GRID AGENT INVENTORY]: Rejecting request since source {0} was not in the list of trusted sources", - peer); - - return false; - } - else - { - return true; - } - } - - /// - /// Check that the source of an inventory request for a particular agent is a current session belonging to - /// that agent. - /// - /// - /// - /// - public bool CheckAuthSession(string session_id, string avatar_id) - { - if (m_doLookup) - { - m_log.InfoFormat("[GRID AGENT INVENTORY]: checking authed session {0} {1}", session_id, avatar_id); - - if (m_session_cache.getCachedSession(session_id, avatar_id) == null) - { - // cache miss, ask userserver - Hashtable requestData = new Hashtable(); - requestData["avatar_uuid"] = avatar_id; - requestData["session_id"] = session_id; - ArrayList SendParams = new ArrayList(); - SendParams.Add(requestData); - XmlRpcRequest UserReq = new XmlRpcRequest("check_auth_session", SendParams); - XmlRpcResponse UserResp = UserReq.Send(m_userserver_url, 3000); - - Hashtable responseData = (Hashtable)UserResp.Value; - if (responseData.ContainsKey("auth_session") && responseData["auth_session"].ToString() == "TRUE") - { - m_log.Info("[GRID AGENT INVENTORY]: got authed session from userserver"); - // add to cache; the session time will be automatically renewed - m_session_cache.Add(session_id, avatar_id); - return true; - } - } - else - { - // cache hits - m_log.Info("[GRID AGENT INVENTORY]: got authed session from cache"); - return true; - } - - m_log.Warn("[GRID AGENT INVENTORY]: unknown session_id, request rejected"); - return false; - } - else - { - return true; - } - } - - /// - /// Return a user's entire inventory - /// - /// - /// The user's inventory. If an inventory cannot be found then an empty collection is returned. - public InventoryCollection GetUserInventory(Guid rawUserID) - { - UUID userID = new UUID(rawUserID); - - m_log.InfoFormat("[GRID AGENT INVENTORY]: Processing request for inventory of {0}", userID); - - // Uncomment me to simulate a slow responding inventory server - //Thread.Sleep(16000); - - InventoryCollection invCollection = new InventoryCollection(); - - List allFolders = GetInventorySkeleton(userID); - - if (null == allFolders) - { - m_log.WarnFormat("[GRID AGENT INVENTORY]: No inventory found for user {0}", rawUserID); - - return invCollection; - } - - List allItems = new List(); - - foreach (InventoryFolderBase folder in allFolders) - { - List items = RequestFolderItems(folder.ID); - - if (items != null) - { - allItems.InsertRange(0, items); - } - } - - invCollection.UserID = userID; - invCollection.Folders = allFolders; - invCollection.Items = allItems; - - // foreach (InventoryFolderBase folder in invCollection.Folders) - // { - // m_log.DebugFormat("[GRID AGENT INVENTORY]: Sending back folder {0} {1}", folder.Name, folder.ID); - // } - // - // foreach (InventoryItemBase item in invCollection.Items) - // { - // m_log.DebugFormat("[GRID AGENT INVENTORY]: Sending back item {0} {1}, folder {2}", item.Name, item.ID, item.Folder); - // } - - m_log.InfoFormat( - "[GRID AGENT INVENTORY]: Sending back inventory response to user {0} containing {1} folders and {2} items", - invCollection.UserID, invCollection.Folders.Count, invCollection.Items.Count); - - return invCollection; - } - - public List GetFolderItems(Guid folderID) - { - List allItems = new List(); - - - List items = RequestFolderItems(new UUID(folderID)); - - if (items != null) - { - allItems.InsertRange(0, items); - } - m_log.InfoFormat( - "[GRID AGENT INVENTORY]: Sending back inventory response containing {0} items", allItems.Count.ToString()); - return allItems; - } - - /// - /// Guid to UUID wrapper for same name IInventoryServices method - /// - /// - /// - public List GetInventorySkeleton(Guid rawUserID) - { - UUID userID = new UUID(rawUserID); - return GetInventorySkeleton(userID); - } - - /// - /// Create an inventory for the given user. - /// - /// - /// - public bool CreateUsersInventory(Guid rawUserID) - { - UUID userID = new UUID(rawUserID); - - m_log.InfoFormat("[GRID AGENT INVENTORY]: Creating new set of inventory folders for user {0}", userID); - - return CreateNewUserInventory(userID); - } - - public List GetActiveGestures(Guid rawUserID) - { - UUID userID = new UUID(rawUserID); - - m_log.InfoFormat("[GRID AGENT INVENTORY]: fetching active gestures for user {0}", userID); - - return GetActiveGestures(userID); - } - } -} diff --git a/OpenSim/Grid/InventoryServer/InventoryServiceBase.cs b/OpenSim/Grid/InventoryServer/InventoryServiceBase.cs deleted file mode 100644 index f8b494994e..0000000000 --- a/OpenSim/Grid/InventoryServer/InventoryServiceBase.cs +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System.Collections.Generic; -using System.Reflection; -using log4net; -using OpenMetaverse; -using OpenSim.Data; -using OpenSim.Framework; -using OpenSim.Framework.Communications; - -namespace OpenSim.Grid.InventoryServer -{ - /// - /// Abstract base class used by local and grid implementations of an inventory service. - /// - public abstract class InventoryServiceBase : IInterServiceInventoryServices - { - - private static readonly ILog m_log - = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - protected List m_plugins = new List(); - - #region Plugin methods - - /// - /// Add a new inventory data plugin - plugins will be requested in the order they were added. - /// - /// The plugin that will provide data - public void AddPlugin(IInventoryDataPlugin plugin) - { - m_plugins.Add(plugin); - } - - /// - /// Adds a list of inventory data plugins, as described by `provider' - /// and `connect', to `m_plugins'. - /// - /// - /// The filename of the inventory server plugin DLL. - /// - /// - /// The connection string for the storage backend. - /// - public void AddPlugin(string provider, string connect) - { - m_plugins.AddRange(DataPluginFactory.LoadDataPlugins(provider, connect)); - } - - #endregion - - #region IInventoryServices methods - - public string Host - { - get { return "default"; } - } - - public List GetInventorySkeleton(UUID userId) - { -// m_log.DebugFormat("[AGENT INVENTORY]: Getting inventory skeleton for {0}", userId); - - InventoryFolderBase rootFolder = RequestRootFolder(userId); - - // Agent has no inventory structure yet. - if (null == rootFolder) - { - return null; - } - - List userFolders = new List(); - - userFolders.Add(rootFolder); - - foreach (IInventoryDataPlugin plugin in m_plugins) - { - IList folders = plugin.getFolderHierarchy(rootFolder.ID); - userFolders.AddRange(folders); - } - -// foreach (InventoryFolderBase folder in userFolders) -// { -// m_log.DebugFormat("[AGENT INVENTORY]: Got folder {0} {1}", folder.name, folder.folderID); -// } - - return userFolders; - } - - // See IInventoryServices - public virtual bool HasInventoryForUser(UUID userID) - { - return false; - } - - // See IInventoryServices - public virtual InventoryFolderBase RequestRootFolder(UUID userID) - { - // Retrieve the first root folder we get from the list of plugins. - foreach (IInventoryDataPlugin plugin in m_plugins) - { - InventoryFolderBase rootFolder = plugin.getUserRootFolder(userID); - if (rootFolder != null) - return rootFolder; - } - - // Return nothing if no plugin was able to supply a root folder - return null; - } - - // See IInventoryServices - public bool CreateNewUserInventory(UUID user) - { - InventoryFolderBase existingRootFolder = RequestRootFolder(user); - - if (null != existingRootFolder) - { - m_log.WarnFormat( - "[AGENT INVENTORY]: Did not create a new inventory for user {0} since they already have " - + "a root inventory folder with id {1}", - user, existingRootFolder.ID); - } - else - { - UsersInventory inven = new UsersInventory(); - inven.CreateNewInventorySet(user); - AddNewInventorySet(inven); - - return true; - } - - return false; - } - - public List GetActiveGestures(UUID userId) - { - List activeGestures = new List(); - foreach (IInventoryDataPlugin plugin in m_plugins) - { - activeGestures.AddRange(plugin.fetchActiveGestures(userId)); - } - - return activeGestures; - } - - #endregion - - #region Methods used by GridInventoryService - - public List RequestSubFolders(UUID parentFolderID) - { - List inventoryList = new List(); - - foreach (IInventoryDataPlugin plugin in m_plugins) - { - inventoryList.AddRange(plugin.getInventoryFolders(parentFolderID)); - } - - return inventoryList; - } - - public List RequestFolderItems(UUID folderID) - { - List itemsList = new List(); - - foreach (IInventoryDataPlugin plugin in m_plugins) - { - itemsList.AddRange(plugin.getInventoryInFolder(folderID)); - } - - return itemsList; - } - - #endregion - - // See IInventoryServices - public virtual bool AddFolder(InventoryFolderBase folder) - { - m_log.DebugFormat( - "[AGENT INVENTORY]: Adding folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID); - - foreach (IInventoryDataPlugin plugin in m_plugins) - { - plugin.addInventoryFolder(folder); - } - - // FIXME: Should return false on failure - return true; - } - - // See IInventoryServices - public virtual bool UpdateFolder(InventoryFolderBase folder) - { - m_log.DebugFormat( - "[AGENT INVENTORY]: Updating folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID); - - foreach (IInventoryDataPlugin plugin in m_plugins) - { - plugin.updateInventoryFolder(folder); - } - - // FIXME: Should return false on failure - return true; - } - - // See IInventoryServices - public virtual bool MoveFolder(InventoryFolderBase folder) - { - m_log.DebugFormat( - "[AGENT INVENTORY]: Moving folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID); - - foreach (IInventoryDataPlugin plugin in m_plugins) - { - plugin.moveInventoryFolder(folder); - } - - // FIXME: Should return false on failure - return true; - } - - // See IInventoryServices - public virtual bool AddItem(InventoryItemBase item) - { - m_log.DebugFormat( - "[AGENT INVENTORY]: Adding item {0} {1} to folder {2}", item.Name, item.ID, item.Folder); - - foreach (IInventoryDataPlugin plugin in m_plugins) - { - plugin.addInventoryItem(item); - } - - // FIXME: Should return false on failure - return true; - } - - // See IInventoryServices - public virtual bool UpdateItem(InventoryItemBase item) - { - m_log.InfoFormat( - "[AGENT INVENTORY]: Updating item {0} {1} in folder {2}", item.Name, item.ID, item.Folder); - - foreach (IInventoryDataPlugin plugin in m_plugins) - { - plugin.updateInventoryItem(item); - } - - // FIXME: Should return false on failure - return true; - } - - // See IInventoryServices - public virtual bool DeleteItem(InventoryItemBase item) - { - m_log.InfoFormat( - "[AGENT INVENTORY]: Deleting item {0} {1} from folder {2}", item.Name, item.ID, item.Folder); - - foreach (IInventoryDataPlugin plugin in m_plugins) - { - plugin.deleteInventoryItem(item.ID); - } - - // FIXME: Should return false on failure - return true; - } - - public virtual InventoryItemBase QueryItem(InventoryItemBase item) - { - foreach (IInventoryDataPlugin plugin in m_plugins) - { - InventoryItemBase result = plugin.queryInventoryItem(item.ID); - if (result != null) - return result; - } - - return null; - } - - public virtual InventoryFolderBase QueryFolder(InventoryFolderBase item) - { - foreach (IInventoryDataPlugin plugin in m_plugins) - { - InventoryFolderBase result = plugin.queryInventoryFolder(item.ID); - if (result != null) - return result; - } - - return null; - } - - /// - /// Purge a folder of all items items and subfolders. - /// - /// FIXME: Really nasty in a sense, because we have to query the database to get information we may - /// already know... Needs heavy refactoring. - /// - /// - public virtual bool PurgeFolder(InventoryFolderBase folder) - { - m_log.DebugFormat( - "[AGENT INVENTORY]: Purging folder {0} {1} of its contents", folder.Name, folder.ID); - - List subFolders = RequestSubFolders(folder.ID); - - foreach (InventoryFolderBase subFolder in subFolders) - { -// m_log.DebugFormat("[AGENT INVENTORY]: Deleting folder {0} {1}", subFolder.Name, subFolder.ID); - - foreach (IInventoryDataPlugin plugin in m_plugins) - { - plugin.deleteInventoryFolder(subFolder.ID); - } - } - - List items = RequestFolderItems(folder.ID); - - foreach (InventoryItemBase item in items) - { - DeleteItem(item); - } - - // FIXME: Should return false on failure - return true; - } - - private void AddNewInventorySet(UsersInventory inventory) - { - foreach (InventoryFolderBase folder in inventory.Folders.Values) - { - AddFolder(folder); - } - } - - public InventoryItemBase GetInventoryItem(UUID itemID) - { - foreach (IInventoryDataPlugin plugin in m_plugins) - { - InventoryItemBase item = plugin.getInventoryItem(itemID); - if (item != null) - return item; - } - - return null; - } - - /// - /// Used to create a new user inventory. - /// - private class UsersInventory - { - public Dictionary Folders = new Dictionary(); - public Dictionary Items = new Dictionary(); - - public virtual void CreateNewInventorySet(UUID user) - { - InventoryFolderBase folder = new InventoryFolderBase(); - - folder.ParentID = UUID.Zero; - folder.Owner = user; - folder.ID = UUID.Random(); - folder.Name = "My Inventory"; - folder.Type = (short)AssetType.Folder; - folder.Version = 1; - Folders.Add(folder.ID, folder); - - UUID rootFolder = folder.ID; - - folder = new InventoryFolderBase(); - folder.ParentID = rootFolder; - folder.Owner = user; - folder.ID = UUID.Random(); - folder.Name = "Animations"; - folder.Type = (short)AssetType.Animation; - folder.Version = 1; - Folders.Add(folder.ID, folder); - - folder = new InventoryFolderBase(); - folder.ParentID = rootFolder; - folder.Owner = user; - folder.ID = UUID.Random(); - folder.Name = "Body Parts"; - folder.Type = (short)AssetType.Bodypart; - folder.Version = 1; - Folders.Add(folder.ID, folder); - - folder = new InventoryFolderBase(); - folder.ParentID = rootFolder; - folder.Owner = user; - folder.ID = UUID.Random(); - folder.Name = "Calling Cards"; - folder.Type = (short)AssetType.CallingCard; - folder.Version = 1; - Folders.Add(folder.ID, folder); - - folder = new InventoryFolderBase(); - folder.ParentID = rootFolder; - folder.Owner = user; - folder.ID = UUID.Random(); - folder.Name = "Clothing"; - folder.Type = (short)AssetType.Clothing; - folder.Version = 1; - Folders.Add(folder.ID, folder); - - folder = new InventoryFolderBase(); - folder.ParentID = rootFolder; - folder.Owner = user; - folder.ID = UUID.Random(); - folder.Name = "Gestures"; - folder.Type = (short)AssetType.Gesture; - folder.Version = 1; - Folders.Add(folder.ID, folder); - - folder = new InventoryFolderBase(); - folder.ParentID = rootFolder; - folder.Owner = user; - folder.ID = UUID.Random(); - folder.Name = "Landmarks"; - folder.Type = (short)AssetType.Landmark; - folder.Version = 1; - Folders.Add(folder.ID, folder); - - folder = new InventoryFolderBase(); - folder.ParentID = rootFolder; - folder.Owner = user; - folder.ID = UUID.Random(); - folder.Name = "Lost And Found"; - folder.Type = (short)AssetType.LostAndFoundFolder; - folder.Version = 1; - Folders.Add(folder.ID, folder); - - folder = new InventoryFolderBase(); - folder.ParentID = rootFolder; - folder.Owner = user; - folder.ID = UUID.Random(); - folder.Name = "Notecards"; - folder.Type = (short)AssetType.Notecard; - folder.Version = 1; - Folders.Add(folder.ID, folder); - - folder = new InventoryFolderBase(); - folder.ParentID = rootFolder; - folder.Owner = user; - folder.ID = UUID.Random(); - folder.Name = "Objects"; - folder.Type = (short)AssetType.Object; - folder.Version = 1; - Folders.Add(folder.ID, folder); - - folder = new InventoryFolderBase(); - folder.ParentID = rootFolder; - folder.Owner = user; - folder.ID = UUID.Random(); - folder.Name = "Photo Album"; - folder.Type = (short)AssetType.SnapshotFolder; - folder.Version = 1; - Folders.Add(folder.ID, folder); - - folder = new InventoryFolderBase(); - folder.ParentID = rootFolder; - folder.Owner = user; - folder.ID = UUID.Random(); - folder.Name = "Scripts"; - folder.Type = (short)AssetType.LSLText; - folder.Version = 1; - Folders.Add(folder.ID, folder); - - folder = new InventoryFolderBase(); - folder.ParentID = rootFolder; - folder.Owner = user; - folder.ID = UUID.Random(); - folder.Name = "Sounds"; - folder.Type = (short)AssetType.Sound; - folder.Version = 1; - Folders.Add(folder.ID, folder); - - folder = new InventoryFolderBase(); - folder.ParentID = rootFolder; - folder.Owner = user; - folder.ID = UUID.Random(); - folder.Name = "Textures"; - folder.Type = (short)AssetType.Texture; - folder.Version = 1; - Folders.Add(folder.ID, folder); - - folder = new InventoryFolderBase(); - folder.ParentID = rootFolder; - folder.Owner = user; - folder.ID = UUID.Random(); - folder.Name = "Trash"; - folder.Type = (short)AssetType.TrashFolder; - folder.Version = 1; - Folders.Add(folder.ID, folder); - } - } - } -} diff --git a/OpenSim/Grid/InventoryServer/Main.cs b/OpenSim/Grid/InventoryServer/Main.cs deleted file mode 100644 index 6106d934f9..0000000000 --- a/OpenSim/Grid/InventoryServer/Main.cs +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using log4net; -using log4net.Config; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Framework.Communications.Services; -using OpenSim.Framework.Console; -using OpenSim.Framework.Servers; -using OpenSim.Framework.Servers.HttpServer; - -namespace OpenSim.Grid.InventoryServer -{ - public class OpenInventory_Main : BaseOpenSimServer - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private GridInventoryService m_inventoryService; - //private HGInventoryService m_directInventoryService; - - public const string LogName = "INVENTORY"; - - public static void Main(string[] args) - { - XmlConfigurator.Configure(); - - OpenInventory_Main theServer = new OpenInventory_Main(); - theServer.Startup(); - - theServer.Work(); - } - - public OpenInventory_Main() - { - m_console = new LocalConsole("Inventory"); - MainConsole.Instance = m_console; - } - - protected override void StartupSpecific() - { - InventoryConfig config = new InventoryConfig(LogName, (Path.Combine(Util.configDir(), "InventoryServer_Config.xml"))); - - m_inventoryService = new GridInventoryService(config.UserServerURL); - m_inventoryService.DoLookup = config.SessionLookUp; - m_inventoryService.AddPlugin(config.DatabaseProvider, config.DatabaseConnect); - - - m_log.Info("[" + LogName + "]: Starting HTTP server ..."); - - m_httpServer = new BaseHttpServer(config.HttpPort); - - AddHttpHandlers(config.RegionAccessToAgentsInventory); - - m_httpServer.Start(); - - m_log.Info("[" + LogName + "]: Started HTTP server"); - - base.StartupSpecific(); - - m_console.Commands.AddCommand("inventoryserver", false, "add user", - "add user", - "Add a random user inventory", HandleAddUser); - } - - protected void AddHttpHandlers(bool regionAccess) - { - if (regionAccess) - { - m_httpServer.AddStreamHandler( - new RestDeserialiseSecureHandler( - "POST", "/GetInventory/", m_inventoryService.GetUserInventory, m_inventoryService.CheckAuthSession)); - - m_httpServer.AddStreamHandler( - new RestDeserialiseSecureHandler( - "POST", "/UpdateFolder/", m_inventoryService.UpdateFolder, m_inventoryService.CheckAuthSession)); - - m_httpServer.AddStreamHandler( - new RestDeserialiseSecureHandler( - "POST", "/MoveFolder/", m_inventoryService.MoveFolder, m_inventoryService.CheckAuthSession)); - - m_httpServer.AddStreamHandler( - new RestDeserialiseSecureHandler( - "POST", "/PurgeFolder/", m_inventoryService.PurgeFolder, m_inventoryService.CheckAuthSession)); - - m_httpServer.AddStreamHandler( - new RestDeserialiseSecureHandler( - "POST", "/DeleteItem/", m_inventoryService.DeleteItem, m_inventoryService.CheckAuthSession)); - - m_httpServer.AddStreamHandler( - new RestDeserialiseSecureHandler( - "POST", "/QueryItem/", m_inventoryService.QueryItem, m_inventoryService.CheckAuthSession)); - - m_httpServer.AddStreamHandler( - new RestDeserialiseSecureHandler( - "POST", "/QueryFolder/", m_inventoryService.QueryFolder, m_inventoryService.CheckAuthSession)); - - } - - m_httpServer.AddStreamHandler( - new RestDeserialiseTrustedHandler( - "POST", "/CreateInventory/", m_inventoryService.CreateUsersInventory, m_inventoryService.CheckTrustSource)); - - m_httpServer.AddStreamHandler( - new RestDeserialiseSecureHandler( - "POST", "/NewFolder/", m_inventoryService.AddFolder, m_inventoryService.CheckAuthSession)); - - m_httpServer.AddStreamHandler( - new RestDeserialiseTrustedHandler( - "POST", "/CreateFolder/", m_inventoryService.AddFolder, m_inventoryService.CheckTrustSource)); - - m_httpServer.AddStreamHandler( - new RestDeserialiseSecureHandler( - "POST", "/NewItem/", m_inventoryService.AddItem, m_inventoryService.CheckAuthSession)); - - m_httpServer.AddStreamHandler( - new RestDeserialiseTrustedHandler( - "POST", "/AddNewItem/", m_inventoryService.AddItem, m_inventoryService.CheckTrustSource)); - - m_httpServer.AddStreamHandler( - new RestDeserialiseTrustedHandler>( - "POST", "/GetItems/", m_inventoryService.GetFolderItems, m_inventoryService.CheckTrustSource)); - - // for persistent active gestures - m_httpServer.AddStreamHandler( - new RestDeserialiseTrustedHandler> - ("POST", "/ActiveGestures/", m_inventoryService.GetActiveGestures, m_inventoryService.CheckTrustSource)); - - // WARNING: Root folders no longer just delivers the root and immediate child folders (e.g - // system folders such as Objects, Textures), but it now returns the entire inventory skeleton. - // It would have been better to rename this request, but complexities in the BaseHttpServer - // (e.g. any http request not found is automatically treated as an xmlrpc request) make it easier - // to do this for now. - m_httpServer.AddStreamHandler( - new RestDeserialiseTrustedHandler> - ("POST", "/RootFolders/", m_inventoryService.GetInventorySkeleton, m_inventoryService.CheckTrustSource)); - } - - private void Work() - { - m_console.Output("Enter help for a list of commands\n"); - - while (true) - { - m_console.Prompt(); - } - } - - private void HandleAddUser(string module, string[] args) - { - m_inventoryService.CreateUsersInventory(UUID.Random().Guid); - } - } -} diff --git a/prebuild.xml b/prebuild.xml index 79c767c1f8..9498d7d688 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -956,38 +956,6 @@ - - - - ../../../bin/ - - - - - ../../../bin/ - - - - ../../../bin/ - - - - - - - - - - - - - - - - - - - @@ -1068,38 +1036,6 @@ - - - - ../../../bin/ - - - - - ../../../bin/ - - - - ../../../bin/ - - - - - - - - - - - - - - - - - - - From 6461243e7c780d79244184a8d4b100303f4cda27 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 17 Sep 2009 23:55:06 +0100 Subject: [PATCH 08/10] Remove the methods for full inventory fetch from the connector. Remove tests for the old, removed asset handlers --- .../Tests/GetAssetStreamHandlerTests.cs | 135 ------------------ .../Inventory/InventoryServiceConnector.cs | 36 +---- .../Setup/BaseRequestHandlerTestHelper.cs | 12 +- .../Setup/GetAssetStreamHandlerTestHelpers.cs | 122 ---------------- 4 files changed, 2 insertions(+), 303 deletions(-) delete mode 100644 OpenSim/Framework/Servers/Tests/GetAssetStreamHandlerTests.cs delete mode 100644 OpenSim/Tests/Common/Setup/GetAssetStreamHandlerTestHelpers.cs diff --git a/OpenSim/Framework/Servers/Tests/GetAssetStreamHandlerTests.cs b/OpenSim/Framework/Servers/Tests/GetAssetStreamHandlerTests.cs deleted file mode 100644 index be3f5187cf..0000000000 --- a/OpenSim/Framework/Servers/Tests/GetAssetStreamHandlerTests.cs +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Net; -using System.Text; -using HttpServer; -using NUnit.Framework; -using OpenSim.Data; -using OpenSim.Framework.Servers.HttpServer; -using OpenSim.Tests.Common; -using OpenSim.Tests.Common.Mock; -using OpenSim.Tests.Common.Setup; - -namespace OpenSim.Framework.Servers.Tests -{ - [TestFixture] - public class GetAssetStreamHandlerTests - { - private const string ASSETS_PATH = "/assets"; - - [Test] - public void TestConstructor() - { - TestHelper.InMethod(); - - // GetAssetStreamHandler handler = - new GetAssetStreamHandler(null); - } - - [Test] - public void TestGetParams() - { - TestHelper.InMethod(); - - GetAssetStreamHandler handler = new GetAssetStreamHandler(null); - BaseRequestHandlerTestHelper.BaseTestGetParams(handler, ASSETS_PATH); - } - - [Test] - public void TestSplitParams() - { - TestHelper.InMethod(); - - GetAssetStreamHandler handler = new GetAssetStreamHandler(null); - BaseRequestHandlerTestHelper.BaseTestSplitParams(handler, ASSETS_PATH); - } - - [Test] - public void TestHandleNoParams() - { - TestHelper.InMethod(); - - GetAssetStreamHandler handler = new GetAssetStreamHandler(null); - - BaseRequestHandlerTestHelper.BaseTestHandleNoParams(handler, ASSETS_PATH); - } - - [Test] - public void TestHandleMalformedGuid() - { - TestHelper.InMethod(); - - GetAssetStreamHandler handler = new GetAssetStreamHandler(null); - - BaseRequestHandlerTestHelper.BaseTestHandleMalformedGuid(handler, ASSETS_PATH); - } - - [Test] - public void TestHandleFetchMissingAsset() - { - GetAssetStreamHandler handler; - OSHttpResponse response; - CreateTestEnvironment(out handler, out response); - - GetAssetStreamHandlerTestHelpers.BaseFetchMissingAsset(handler, response); - } - - [Test] - public void TestHandleFetchExistingAssetData() - { - GetAssetStreamHandler handler; - OSHttpResponse response; - AssetBase asset = CreateTestEnvironment(out handler, out response); - - GetAssetStreamHandlerTestHelpers.BaseFetchExistingAssetDataTest(asset, handler, response); - } - - [Test] - public void TestHandleFetchExistingAssetXml() - { - GetAssetStreamHandler handler; - OSHttpResponse response; - AssetBase asset = CreateTestEnvironment(out handler, out response); - - GetAssetStreamHandlerTestHelpers.BaseFetchExistingAssetXmlTest(asset, handler, response); - } - - private static AssetBase CreateTestEnvironment(out GetAssetStreamHandler handler, out OSHttpResponse response) - { - AssetBase asset = GetAssetStreamHandlerTestHelpers.CreateCommonTestResources(out response); - - IAssetDataPlugin assetDataPlugin = new TestAssetDataPlugin(); - handler = new GetAssetStreamHandler(assetDataPlugin); - - assetDataPlugin.StoreAsset(asset); - return asset; - } - } -} diff --git a/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs b/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs index cef678ddd0..5443891539 100644 --- a/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs +++ b/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs @@ -236,42 +236,8 @@ namespace OpenSim.Services.Connectors } catch (Exception e) { - // Maybe we're talking to an old inventory server. Try this other thing. - m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetFolderContent operation failed, {0} {1} (old server?). Trying GetInventory.", + m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetFolderContent operation failed, {0} {1} (old server?).", e.Source, e.Message); - - InventoryCollection inventory; - List folders = null; - try - { - inventory = SynchronousRestSessionObjectPoster.BeginPostObject( - "POST", m_ServerURI + "/GetInventory/", new Guid(userID), sessionID.ToString(), userID.ToString()); - if (inventory != null) - folders = inventory.Folders; - } - catch (Exception ex) - { - m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetInventory operation also failed, {0} {1}. Giving up.", - e.Source, ex.Message); - return new InventoryCollection(); - } - - if ((folders != null) && (folders.Count > 0)) - { - m_log.DebugFormat("[INVENTORY CONNECTOR]: Received entire inventory ({0} folders) for user {1}", - folders.Count, userID); - - folders = folders.FindAll(delegate(InventoryFolderBase f) { return f.ParentID == folderID; }); - List items = inventory.Items; - if (items != null) - { - items = items.FindAll(delegate(InventoryItemBase i) { return i.Folder == folderID; }); - } - - inventory.Items = items; - inventory.Folders = folders; - return inventory; - } } InventoryCollection nullCollection = new InventoryCollection(); diff --git a/OpenSim/Tests/Common/Setup/BaseRequestHandlerTestHelper.cs b/OpenSim/Tests/Common/Setup/BaseRequestHandlerTestHelper.cs index e8583718d2..eaf8b39ac0 100644 --- a/OpenSim/Tests/Common/Setup/BaseRequestHandlerTestHelper.cs +++ b/OpenSim/Tests/Common/Setup/BaseRequestHandlerTestHelper.cs @@ -72,15 +72,5 @@ namespace OpenSim.Tests.Common.Setup public static byte[] EmptyByteArray = new byte[] {}; - public static void BaseTestHandleNoParams(BaseGetAssetStreamHandler handler, string assetsPath) - { - Assert.AreEqual(EmptyByteArray, handler.Handle(assetsPath, null, null, null), "Failed on empty params."); - Assert.AreEqual(EmptyByteArray, handler.Handle(assetsPath + "/", null, null, null), "Failed on single slash."); - } - - public static void BaseTestHandleMalformedGuid(BaseGetAssetStreamHandler handler, string assetsPath) - { - Assert.AreEqual(EmptyByteArray, handler.Handle(assetsPath + "/badGuid", null, null, null), "Failed on bad guid."); - } } -} \ No newline at end of file +} diff --git a/OpenSim/Tests/Common/Setup/GetAssetStreamHandlerTestHelpers.cs b/OpenSim/Tests/Common/Setup/GetAssetStreamHandlerTestHelpers.cs deleted file mode 100644 index ffa7283a61..0000000000 --- a/OpenSim/Tests/Common/Setup/GetAssetStreamHandlerTestHelpers.cs +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Text; -using System.Xml; -using System.Xml.Serialization; -using NUnit.Framework; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Framework.Servers; -using OpenSim.Framework.Servers.HttpServer; -using OpenSim.Server.Base; -using OpenSim.Tests.Common.Mock; - -namespace OpenSim.Tests.Common.Setup -{ - public class GetAssetStreamHandlerTestHelpers - { - private const string EXPECTED_CONTENT_TYPE = "application/x-metaverse-callingcard"; - - public static void BaseFetchExistingAssetXmlTest(AssetBase asset, BaseGetAssetStreamHandler handler, OSHttpResponse response) - { - byte[] expected = BaseGetAssetStreamHandler.GetXml(asset); - - byte[] actual = handler.Handle("/assets/" + asset.ID , null, null, response); - - Assert.Greater(actual.Length, 10, "Too short xml on fetching xml without trailing slash."); - Assert.AreEqual(expected, actual, "Failed on fetching xml without trailing slash."); - // Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on first fetch."); - - actual = handler.Handle("/assets/" + asset.ID + "/", null, null, response); - Assert.Greater(actual.Length, 10, "Too short xml on fetching xml with trailing slash."); - Assert.AreEqual(expected, actual, "Failed on fetching xml with trailing slash."); - // Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on second fetch."); - - actual = handler.Handle("/assets/" + asset.ID + "/badData", null, null, response); - Assert.Greater(actual.Length, 10, "Too short xml on fetching xml with bad trailing data."); - Assert.AreEqual(expected, actual, "Failed on fetching xml with bad trailing trailing slash."); - // Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on second fetch."); - } - - public static void BaseFetchExistingAssetDataTest(AssetBase asset, BaseGetAssetStreamHandler handler, OSHttpResponse response) - { - Assert.AreEqual(asset.Data, handler.Handle("/assets/" + asset.ID + "/data", null, null, response), "Failed on fetching data without trailing slash."); - Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on first fetch."); - Assert.AreEqual(EXPECTED_CONTENT_TYPE, response.ContentType, "Wrong http content type on first fetch."); - - Assert.AreEqual(asset.Data, handler.Handle("/assets/" + asset.ID + "/data/", null, null, response), "Failed on fetching data with trailing slash."); - Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on second fetch."); - Assert.AreEqual(EXPECTED_CONTENT_TYPE, response.ContentType, "Wrong http content type on second fetch."); - } - - public static void BaseFetchExistingAssetMetaDataTest(AssetBase asset, BaseGetAssetStreamHandler handler, OSHttpResponse response) - { - XmlSerializer xs = new XmlSerializer(typeof(AssetMetadata)); - - byte[] expected = ServerUtils.SerializeResult(xs, asset.Metadata); - - Assert.AreEqual(expected, handler.Handle("/assets/" + asset.ID + "/metadata", null, null, response), "Failed on fetching data without trailing slash."); - Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on first fetch."); - Assert.AreEqual(EXPECTED_CONTENT_TYPE, response.ContentType, "Wrong http content type on first fetch."); - - Assert.AreEqual(expected, handler.Handle("/assets/" + asset.ID + "/metadata/", null, null, response), "Failed on fetching data with trailing slash."); - Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on second fetch."); - Assert.AreEqual(EXPECTED_CONTENT_TYPE, response.ContentType, "Wrong http content type on second fetch."); - } - - public static AssetBase CreateCommonTestResources(out OSHttpResponse response) - { - AssetBase asset = CreateTestAsset(); - response = new TestOSHttpResponse(); - return asset; - } - - public static AssetBase CreateTestAsset() - { - byte[] expected = new byte[] { 1,2,3 }; - AssetBase asset = new AssetBase(); - asset.ID = Guid.NewGuid().ToString(); - asset.Data = expected; - asset.Type = 2; - - return asset; - } - - public static void BaseFetchMissingAsset(BaseGetAssetStreamHandler handler, OSHttpResponse response) - { - Assert.AreEqual( - BaseRequestHandlerTestHelper.EmptyByteArray, - handler.Handle("/assets/" + Guid.NewGuid(), null, null, response), "Failed on bad guid."); - Assert.AreEqual((int)HttpStatusCode.NotFound, response.StatusCode, "Response code wrong in BaseFetchMissingAsset"); - } - } -} From 56edbe9b60e5ed5f1388e2d1d4d2a0d82cdeaf6d Mon Sep 17 00:00:00 2001 From: nlin Date: Fri, 18 Sep 2009 11:26:52 +0900 Subject: [PATCH 09/10] Alternate algorithm for fixing avatar capsule tilt (Mantis #2905) Eliminate dynamic capsule wobble. Instead introduce a small, fixed tilt, and allow the tilt to rotate with the avatar while moving; the tilt always faces away from the direction of avatar movement. The rotation while moving should eliminate direction-dependent behavior (e.g. only being able to climb on top of prims from certain directions). Falling animation is still too frequently invoked. Ideally the tilt should be completely eliminated, but doing so currently causes the avatar to fall through the terrain. --- .../Region/Framework/Scenes/ScenePresence.cs | 2 +- .../Region/Physics/OdePlugin/ODECharacter.cs | 132 ++++++++++-------- 2 files changed, 73 insertions(+), 61 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 23fe2d3312..6772f75d60 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2269,7 +2269,7 @@ namespace OpenSim.Region.Framework.Scenes { //Record the time we enter this state so we know whether to "land" or not m_animPersistUntil = DateTime.Now.Ticks; - return "FALLDOWN"; + return "FALLDOWN"; // this falling animation is invoked too frequently when capsule tilt correction is used - why? } } } diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index dd58a4e2d0..a00ba11d14 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -107,6 +107,7 @@ namespace OpenSim.Region.Physics.OdePlugin public float MinimumGroundFlightOffset = 3f; private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes. + private float m_tiltMagnitudeWhenProjectedOnXYPlane = 0.1131371f; // used to introduce a fixed tilt because a straight-up capsule falls through terrain, probably a bug in terrain collider private float m_buoyancy = 0f; @@ -477,7 +478,71 @@ namespace OpenSim.Region.Physics.OdePlugin } } } - + + private void AlignAvatarTiltWithCurrentDirectionOfMovement(PhysicsVector movementVector) + { + movementVector.Z = 0f; + float magnitude = (float)Math.Sqrt((double)(movementVector.X * movementVector.X + movementVector.Y * movementVector.Y)); + if (magnitude < 0.1f) return; + + // normalize the velocity vector + float invMagnitude = 1.0f / magnitude; + movementVector.X *= invMagnitude; + movementVector.Y *= invMagnitude; + + // if we change the capsule heading too often, the capsule can fall down + // therefore we snap movement vector to just 1 of 4 predefined directions (ne, nw, se, sw), + // meaning only 4 possible capsule tilt orientations + if (movementVector.X > 0) + { + // east + if (movementVector.Y > 0) + { + // northeast + movementVector.X = (float)Math.Sqrt(2.0); + movementVector.Y = (float)Math.Sqrt(2.0); + } + else + { + // southeast + movementVector.X = (float)Math.Sqrt(2.0); + movementVector.Y = -(float)Math.Sqrt(2.0); + } + } + else + { + // west + if (movementVector.Y > 0) + { + // northwest + movementVector.X = -(float)Math.Sqrt(2.0); + movementVector.Y = (float)Math.Sqrt(2.0); + } + else + { + // southwest + movementVector.X = -(float)Math.Sqrt(2.0); + movementVector.Y = -(float)Math.Sqrt(2.0); + } + } + + + // movementVector.Z is zero + + // calculate tilt components based on desired amount of tilt and current (snapped) heading. + // the "-" sign is to force the tilt to be OPPOSITE the direction of movement. + float xTiltComponent = -movementVector.X * m_tiltMagnitudeWhenProjectedOnXYPlane; + float yTiltComponent = -movementVector.Y * m_tiltMagnitudeWhenProjectedOnXYPlane; + + //m_log.Debug("[PHYSICS] changing avatar tilt"); + d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, xTiltComponent); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, xTiltComponent); // must be same as lowstop, else a different, spurious tilt is introduced + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, yTiltComponent); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, yTiltComponent); // same as lowstop + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, 0f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop + } + /// /// This creates the Avatar's physical Surrogate at the position supplied /// @@ -576,71 +641,13 @@ namespace OpenSim.Region.Physics.OdePlugin // (with -0..0 motor stops) falls into the terrain for reasons yet // to be comprehended in their entirety. #endregion + AlignAvatarTiltWithCurrentDirectionOfMovement(new PhysicsVector(0,0,0)); d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, 0.08f); d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f); d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, 0.08f); d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.08f); // must be same as lowstop, else a different, spurious tilt is introduced d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.08f); // same as lowstop - #region Documentation of capsule motor StopERP and StopCFM parameters - // In addition to the above tilt, we allow a dynamic tilt, or - // wobble, to emerge as the capsule is pushed around the environment. - // We do this with an experimentally determined combination of - // StopERP and StopCFM which make the above motor stops soft. - // The softness of the stops should be tweaked according to two - // requirements: - // - // 1. Motor stops should be weak enough to allow enough wobble such - // that the capsule can tilt slightly more when moving, to allow - // "gliding" over obstacles: - // - // - // .-. - // / / - // / / - // _ / / _ - // / \ .-. / / / \ - // | | ----> / / / / | | - // | | / / `-' | | - // | | / / +------+ | | - // | | / / | | | | - // | | / / | | | | - // \_/ `-' +------+ \_/ - // ---------------------------------------------------------- - // - // Note that requirement 1 is made complicated by the ever-present - // slight avatar tilt (assigned in the above code to prevent avatar - // from falling through terrain), which introduces a direction-dependent - // bias into the wobble (wobbling against the existing tilt is harder - // than wobbling with the tilt), which makes it easier to walk over - // prims from some directions. I have tried to minimize this effect by - // minimizing the avatar tilt to the minimum that prevents the avatar from - // falling through the terrain. - // - // 2. Motor stops should be strong enough to prevent the capsule - // from being forced all the way to the ground; otherwise the - // capsule could slip underneath obstacles like this: - // _ _ - // / \ +------+ / \ - // | | ----> | | | | - // | | | | | | - // | | .--.___ +------+ | | - // | | `--.__`--.__ | | - // | | `--.__`--. | | - // \_/ `--' \_/ - // ---------------------------------------------------------- - // - // - // It is strongly recommended you enable USE_DRAWSTUFF if you want to - // tweak these values, to see how the capsule is reacting in various - // situations. - #endregion - d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM, 0.0035f); - d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM2, 0.0035f); - d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM3, 0.0035f); - d.JointSetAMotorParam(Amotor, (int)dParam.StopERP, 0.8f); - d.JointSetAMotorParam(Amotor, (int)dParam.StopERP2, 0.8f); - d.JointSetAMotorParam(Amotor, (int)dParam.StopERP3, 0.8f); } // Fudge factor is 1f by default, we're setting it to 0. We don't want it to Fudge or the @@ -939,6 +946,7 @@ namespace OpenSim.Region.Physics.OdePlugin PhysicsVector vec = new PhysicsVector(); d.Vector3 vel = d.BodyGetLinearVel(Body); + float movementdivisor = 1f; if (!m_alwaysRun) @@ -1052,6 +1060,10 @@ namespace OpenSim.Region.Physics.OdePlugin if (PhysicsVector.isFinite(vec)) { doForce(vec); + if (!_zeroFlag) + { + AlignAvatarTiltWithCurrentDirectionOfMovement(new PhysicsVector(vec.X, vec.Y, vec.Z)); + } } else { From 4f3975f04e7bbaf7b7b8e286831714240ced5e6d Mon Sep 17 00:00:00 2001 From: Rob Smart Date: Fri, 18 Sep 2009 14:11:38 +0100 Subject: [PATCH 10/10] addition of a new script function osSetParcelSIPAddress(string SIPAddress), now including iVoiceModule This patch allows the land owner to dynamically set the SIP address of a particular land parcel from script. This allows predetermined SIP addresses to be used, making it easier to allow non OpenSim users to join a regions voice channel. Signed-off-by: dr scofield (aka dirk husemann) --- .../Framework/Interfaces/IVoiceModule.cs | 45 +++++++++++++++ .../FreeSwitchVoice/FreeSwitchVoiceModule.cs | 55 ++++++++++++++++++- .../Shared/Api/Implementation/OSSL_Api.cs | 29 ++++++++++ .../Shared/Api/Interface/IOSSL_Api.cs | 1 + .../Shared/Api/Runtime/OSSL_Stub.cs | 5 ++ 5 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 OpenSim/Region/Framework/Interfaces/IVoiceModule.cs diff --git a/OpenSim/Region/Framework/Interfaces/IVoiceModule.cs b/OpenSim/Region/Framework/Interfaces/IVoiceModule.cs new file mode 100644 index 0000000000..2e555fa092 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IVoiceModule.cs @@ -0,0 +1,45 @@ +/* + * 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.IO; +using OpenMetaverse; + +namespace OpenSim.Region.Framework.Interfaces +{ + public interface IVoiceModule + { + + /// + /// Set the SIP url to be used by a parcel, this will allow manual setting of a SIP address + /// for a particular piece of land, allowing region owners to use preconfigured SIP conference channels. + /// This is used by osSetParcelSIPAddress + /// + void setLandSIPAddress(string SIPAddress,UUID GlobalID); + + } +} diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 65c5274a57..6b30959239 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -53,7 +53,7 @@ using System.Text.RegularExpressions; namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { - public class FreeSwitchVoiceModule : IRegionModule + public class FreeSwitchVoiceModule : IRegionModule, IVoiceModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -101,13 +101,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private FreeSwitchDialplan m_FreeSwitchDialplan; private readonly Dictionary m_UUIDName = new Dictionary(); + private Dictionary m_ParcelAddress = new Dictionary(); + + private Scene m_scene; private IConfig m_config; public void Initialise(Scene scene, IConfigSource config) { - + m_scene = scene; m_config = config.Configs["FreeSwitchVoice"]; if (null == m_config) @@ -230,6 +233,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { OnRegisterCaps(scene, agentID, caps); }; + + try { @@ -255,6 +260,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public void PostInitialise() { + if(m_pluginEnabled) + { + m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene"); + + // register the voice interface for this module, so the script engine can call us + m_scene.RegisterModuleInterface(this); + } } public void Close() @@ -270,7 +282,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { get { return true; } } - + + // + // implementation of IVoiceModule, called by osSetParcelSIPAddress script function + // + public void setLandSIPAddress(string SIPAddress,UUID GlobalID) + { + m_log.DebugFormat("[FreeSwitchVoice]: setLandSIPAddress parcel id {0}: setting sip address {1}", + GlobalID, SIPAddress); + + lock (m_ParcelAddress) + { + if (m_ParcelAddress.ContainsKey(GlobalID.ToString())) + { + m_ParcelAddress[GlobalID.ToString()] = SIPAddress; + } + else + { + m_ParcelAddress.Add(GlobalID.ToString(), SIPAddress); + } + } + } // // OnRegisterCaps is invoked via the scene.EventManager @@ -776,6 +808,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // Create parcel voice channel. If no parcel exists, then the voice channel ID is the same // as the directory ID. Otherwise, it reflects the parcel's ID. + + lock (m_ParcelAddress) + { + if (m_ParcelAddress.ContainsKey( land.GlobalID.ToString() )) + { + m_log.DebugFormat("[FreeSwitchVoice]: parcel id {0}: using sip address {1}", + land.GlobalID, m_ParcelAddress[land.GlobalID.ToString()]); + return m_ParcelAddress[land.GlobalID.ToString()]; + } + } if (land.LocalID != 1 && (land.Flags & (uint)ParcelFlags.UseEstateVoiceChan) == 0) { @@ -797,6 +839,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // the personal speech indicators as well unless some siren14-3d codec magic happens. we dont have siren143d so we'll settle for the personal speech indicator. channelUri = String.Format("sip:conf-{0}@{1}", "x" + Convert.ToBase64String(encoding.GetBytes(landUUID)), m_freeSwitchRealm); + lock (m_ParcelAddress) + { + if (!m_ParcelAddress.ContainsKey(land.GlobalID.ToString())) + { + m_ParcelAddress.Add(land.GlobalID.ToString(),channelUri); + } + } return channelUri; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 726b37a077..ccdd4c50a9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -1164,6 +1164,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api land.SetMediaUrl(url); } + + public void osSetParcelSIPAddress(string SIPAddress) + { + // What actually is the difference to the LL function? + // + CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelMediaURL"); + + m_host.AddScriptLPS(1); + + + ILandObject land + = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); + + if (land.landData.OwnerID != m_host.ObjectOwner) + { + OSSLError("osSetParcelSIPAddress: Sorry, you need to own the land to use this function"); + return; + } + + // get the voice module + IVoiceModule voiceModule = World.RequestModuleInterface(); + + if (voiceModule != null) + voiceModule.setLandSIPAddress(SIPAddress,land.landData.GlobalID); + else + OSSLError("osSetParcelSIPAddress: No voice module enabled for this land"); + + + } public string osGetScriptEngineName() { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 49aa45a017..d8d3c31dd4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -75,6 +75,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces bool osConsoleCommand(string Command); void osSetParcelMediaURL(string url); void osSetPrimFloatOnWater(int floatYN); + void osSetParcelSIPAddress(string SIPAddress); // Avatar Info Commands string osGetAgentIP(string agent); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 8f52d99418..d0df3902ad 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -183,6 +183,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { m_OSSL_Functions.osSetParcelMediaURL(url); } + + public void osSetParcelSIPAddress(string SIPAddress) + { + m_OSSL_Functions.osSetParcelSIPAddress(SIPAddress); + } public void osSetPrimFloatOnWater(int floatYN) {