From 755ad9e3e0447b60299b08a18624064d1d64141b Mon Sep 17 00:00:00 2001 From: MW Date: Mon, 4 Feb 2008 12:04:02 +0000 Subject: [PATCH] First part of avatar persistence, currently only really works in standalone mode (with accounts_authenticate set to true), it also only currently has a mysql database connector. (sqlite one will follow soon). It also uses the tribalmedia database system, so this needs checking to see if the old problems with mono have been fixed. To use, see the appearance section in opensim.ini.example, set "persist = true", then add the correct connection string for your database.(see mysql-AvatarAppearance.sql in share folder for a example of the table mysql table structure). This could possible be used in a very small grid, but would mean each region server would need to connect to the same mysql database. But the work to move the code to one of the grid servers shouldn't be too much. --- .../Communications/Cache/GridAssetClient.cs | 2 + .../Communications/RestClient/RestClient.cs | 1 + .../Data.MySQL/MySQLDatabaseMapper.cs | 9 +- OpenSim/Framework/Data/OpenSimDataReader.cs | 4 +- .../Data/OpenSimDatabaseConnector.cs | 26 ++- .../Data/OpenSimObjectFieldMapper.cs | 4 +- OpenSim/Framework/Data/OpenSimTableMapper.cs | 3 +- .../Data/PrimitiveBaseShapeTableMapper.cs | 6 +- OpenSim/Region/Application/Application.cs | 3 +- OpenSim/Region/ClientStack/ClientView.cs | 1 + .../ClientStack/RegionApplicationBase.cs | 2 +- OpenSim/Region/Environment/ModuleLoader.cs | 1 + .../Modules/AppearanceTableMapper.cs | 216 ++++++++++++++++++ .../Modules/AvatarFactoryModule.cs | 64 +++++- .../Region/Environment/PermissionManager.cs | 49 ++-- .../Environment/Scenes/AvatarAppearance.cs | 12 + .../Environment/Scenes/SceneObjectPart.cs | 3 + .../BaseDatabaseConnector.cs | 1 + bin/OpenSim.ini.example | 4 + prebuild.xml | 2 + share/sql/mysql-AvatarAppearance.sql | 42 ++++ 21 files changed, 403 insertions(+), 52 deletions(-) create mode 100644 OpenSim/Region/Environment/Modules/AppearanceTableMapper.cs create mode 100644 share/sql/mysql-AvatarAppearance.sql diff --git a/OpenSim/Framework/Communications/Cache/GridAssetClient.cs b/OpenSim/Framework/Communications/Cache/GridAssetClient.cs index cf54fa4484..2f0727f26a 100644 --- a/OpenSim/Framework/Communications/Cache/GridAssetClient.cs +++ b/OpenSim/Framework/Communications/Cache/GridAssetClient.cs @@ -95,11 +95,13 @@ namespace OpenSim.Framework.Communications.Cache // RestClient rc = new RestClient(_assetServerUrl); MainLog.Instance.Verbose("ASSET", "Storing asset"); //rc.AddResourcePath("assets"); + // rc.RequestMethod = "POST"; // rc.Request(s); //MainLog.Instance.Verbose("ASSET", "Stored {0}", rc); MainLog.Instance.Verbose("ASSET", "Sending to " + _assetServerUrl + "/assets/"); RestObjectPoster.BeginPostObject(_assetServerUrl + "/assets/", asset); + } catch (Exception e) { diff --git a/OpenSim/Framework/Communications/RestClient/RestClient.cs b/OpenSim/Framework/Communications/RestClient/RestClient.cs index e4da4dcfd1..76bad645a8 100644 --- a/OpenSim/Framework/Communications/RestClient/RestClient.cs +++ b/OpenSim/Framework/Communications/RestClient/RestClient.cs @@ -389,6 +389,7 @@ namespace OpenSim.Framework.Communications dst.Write(buf, 0, length); length = src.Read(buf, 0, 1024); } + _response = (HttpWebResponse) _request.GetResponse(); // IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request); diff --git a/OpenSim/Framework/Data.MySQL/MySQLDatabaseMapper.cs b/OpenSim/Framework/Data.MySQL/MySQLDatabaseMapper.cs index 275ce4707c..5d636bd0b3 100644 --- a/OpenSim/Framework/Data.MySQL/MySQLDatabaseMapper.cs +++ b/OpenSim/Framework/Data.MySQL/MySQLDatabaseMapper.cs @@ -1,10 +1,11 @@ using System.Data.Common; using MySql.Data.MySqlClient; -// using TribalMedia.Framework.Data; + //using TribalMedia.Framework.Data; + -/* namespace OpenSim.Framework.Data.MySQL { + /* public class MySQLDatabaseMapper : OpenSimDatabaseConnector { public MySQLDatabaseMapper(string connectionString) @@ -22,6 +23,6 @@ namespace OpenSim.Framework.Data.MySQL { return "?" + fieldName; } - } + }*/ } -*/ + diff --git a/OpenSim/Framework/Data/OpenSimDataReader.cs b/OpenSim/Framework/Data/OpenSimDataReader.cs index c7b6470c52..d113f14b79 100644 --- a/OpenSim/Framework/Data/OpenSimDataReader.cs +++ b/OpenSim/Framework/Data/OpenSimDataReader.cs @@ -4,7 +4,7 @@ using System.Data; using System.Text; using libsecondlife; -/* + using TribalMedia.Framework.Data; namespace OpenSim.Framework.Data @@ -39,4 +39,4 @@ namespace OpenSim.Framework.Data } } } -*/ + diff --git a/OpenSim/Framework/Data/OpenSimDatabaseConnector.cs b/OpenSim/Framework/Data/OpenSimDatabaseConnector.cs index 155bdc12f0..aba9329981 100644 --- a/OpenSim/Framework/Data/OpenSimDatabaseConnector.cs +++ b/OpenSim/Framework/Data/OpenSimDatabaseConnector.cs @@ -1,6 +1,8 @@ using System.Data; +using System.Data.Common; using libsecondlife; -/* +using MySql.Data.MySqlClient; + using TribalMedia.Framework.Data; namespace OpenSim.Framework.Data @@ -26,5 +28,25 @@ namespace OpenSim.Framework.Data return new OpenSimDataReader(reader); } } + + + public class MySQLDatabaseMapper : OpenSimDatabaseConnector + { + public MySQLDatabaseMapper(string connectionString) + : base(connectionString) + { + } + + public override DbConnection GetNewConnection() + { + MySqlConnection connection = new MySqlConnection(m_connectionString); + return connection; + } + + public override string CreateParamName(string fieldName) + { + return "?" + fieldName; + } + } } -*/ + diff --git a/OpenSim/Framework/Data/OpenSimObjectFieldMapper.cs b/OpenSim/Framework/Data/OpenSimObjectFieldMapper.cs index 8d5b9cf4a9..269f8634c0 100644 --- a/OpenSim/Framework/Data/OpenSimObjectFieldMapper.cs +++ b/OpenSim/Framework/Data/OpenSimObjectFieldMapper.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Data.Common; using System.Text; using libsecondlife; -/* + using TribalMedia.Framework.Data; namespace OpenSim.Framework.Data @@ -73,4 +73,4 @@ namespace OpenSim.Framework.Data } } } -*/ + diff --git a/OpenSim/Framework/Data/OpenSimTableMapper.cs b/OpenSim/Framework/Data/OpenSimTableMapper.cs index f596b45eca..e5deae0dc3 100644 --- a/OpenSim/Framework/Data/OpenSimTableMapper.cs +++ b/OpenSim/Framework/Data/OpenSimTableMapper.cs @@ -1,5 +1,5 @@ using System.Data; -/* + using TribalMedia.Framework.Data; namespace OpenSim.Framework.Data @@ -11,4 +11,3 @@ namespace OpenSim.Framework.Data } } } -*/ diff --git a/OpenSim/Framework/Data/PrimitiveBaseShapeTableMapper.cs b/OpenSim/Framework/Data/PrimitiveBaseShapeTableMapper.cs index 227a98e239..ec9689a479 100644 --- a/OpenSim/Framework/Data/PrimitiveBaseShapeTableMapper.cs +++ b/OpenSim/Framework/Data/PrimitiveBaseShapeTableMapper.cs @@ -1,9 +1,9 @@ using System; using OpenSim.Framework; -//using TribalMedia.Framework.Data; +using TribalMedia.Framework.Data; using libsecondlife; -/* + namespace OpenSim.Framework.Data { public class PrimitiveBaseShapeRowMapper : BaseRowMapper @@ -142,4 +142,4 @@ namespace OpenSim.Framework.Data } } } -*/ + diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs index 2045b56188..4c4d315567 100644 --- a/OpenSim/Region/Application/Application.cs +++ b/OpenSim/Region/Application/Application.cs @@ -58,7 +58,7 @@ namespace OpenSim } Console.WriteLine("Starting...\n"); - + Culture.SetCurrentCulture(); ArgvConfigSource configSource = new ArgvConfigSource(args); @@ -75,6 +75,7 @@ namespace OpenSim OpenSimMain sim = new OpenSimMain(configSource); sim.StartUp(); + while (true) { diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 7f62d4db9d..167e4c3093 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -351,6 +351,7 @@ namespace OpenSim.Region.ClientStack if (m_debug > 0) { string info = String.Empty; + if (m_debug < 255 && packet.Type == PacketType.AgentUpdate) return; if (m_debug < 254 && packet.Type == PacketType.ViewerEffect) diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs index 4dce9e78e5..d6cf7c3b6f 100644 --- a/OpenSim/Region/ClientStack/RegionApplicationBase.cs +++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs @@ -1,7 +1,7 @@ /* * 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 diff --git a/OpenSim/Region/Environment/ModuleLoader.cs b/OpenSim/Region/Environment/ModuleLoader.cs index 41d8caccff..76ba14bce8 100644 --- a/OpenSim/Region/Environment/ModuleLoader.cs +++ b/OpenSim/Region/Environment/ModuleLoader.cs @@ -135,6 +135,7 @@ namespace OpenSim.Region.Environment m_loadedSharedModules.Add(xmlRpcMod.Name, xmlRpcMod); } //TextureDownloadModule textureModule = new TextureDownloadModule(); + //LoadedSharedModules.Add(textureModule.Name, textureModule); } diff --git a/OpenSim/Region/Environment/Modules/AppearanceTableMapper.cs b/OpenSim/Region/Environment/Modules/AppearanceTableMapper.cs new file mode 100644 index 0000000000..ec8214519c --- /dev/null +++ b/OpenSim/Region/Environment/Modules/AppearanceTableMapper.cs @@ -0,0 +1,216 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Framework; +using TribalMedia.Framework.Data; + +namespace OpenSim.Region.Environment.Modules +{ + public class AppearanceRowMapper : BaseRowMapper + { + + public AppearanceRowMapper(BaseSchema schema, AvatarAppearance obj) + : base(schema, obj) + { + } + } + + public class AppearanceTableMapper : BaseTableMapper + { + public AppearanceTableMapper(BaseDatabaseConnector database, string tableName) + : base(database, tableName) + { + BaseSchema rowMapperSchema = new BaseSchema(this); + m_schema = rowMapperSchema; + + m_keyFieldMapper = rowMapperSchema.AddMapping("UUID", + delegate(AppearanceRowMapper mapper) { return mapper.Object.ScenePresenceID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.ScenePresenceID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("Serial", + delegate(AppearanceRowMapper mapper) { return (uint)mapper.Object.WearablesSerial; }, + delegate(AppearanceRowMapper mapper, uint value) { mapper.Object.WearablesSerial = (int)value; }); + + rowMapperSchema.AddMapping("WearableItem0", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[0].ItemID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) + { + if (mapper.Object.Wearables == null) + { + mapper.Object.Wearables = new OpenSim.Framework.AvatarWearable[13]; + for (int i = 0; i < 13; i++) + { + mapper.Object.Wearables[i] = new AvatarWearable(); + } + } + mapper.Object.Wearables[0].ItemID = new libsecondlife.LLUUID(value.ToString()); + }); + + rowMapperSchema.AddMapping("WearableAsset0", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[0].AssetID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) + { mapper.Object.Wearables[0].AssetID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableItem1", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[1].ItemID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[1].ItemID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableAsset1", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[1].AssetID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) + { mapper.Object.Wearables[1].AssetID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableItem2", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[2].ItemID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[2].ItemID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableAsset2", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[2].AssetID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) + { mapper.Object.Wearables[2].AssetID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableItem3", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[3].ItemID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[3].ItemID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableAsset3", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[3].AssetID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) + { mapper.Object.Wearables[3].AssetID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableItem4", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[4].ItemID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[4].ItemID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableAsset4", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[4].AssetID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) + { mapper.Object.Wearables[4].AssetID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableItem5", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[5].ItemID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[5].ItemID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableAsset5", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[5].AssetID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) + { mapper.Object.Wearables[5].AssetID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableItem6", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[6].ItemID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[6].ItemID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableAsset6", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[6].AssetID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) + { mapper.Object.Wearables[6].AssetID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableItem7", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[7].ItemID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[7].ItemID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableAsset7", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[7].AssetID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) + { mapper.Object.Wearables[7].AssetID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableItem8", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[8].ItemID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[8].ItemID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableAsset8", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[8].AssetID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) + { mapper.Object.Wearables[8].AssetID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableItem9", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[9].ItemID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[9].ItemID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableAsset9", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[9].AssetID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) + { mapper.Object.Wearables[9].AssetID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableItem10", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[10].ItemID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[10].ItemID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableAsset10", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[10].AssetID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) + { mapper.Object.Wearables[10].AssetID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableItem11", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[11].ItemID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[11].ItemID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableAsset11", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[11].AssetID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) + { mapper.Object.Wearables[11].AssetID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableItem12", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[12].ItemID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[12].ItemID = new libsecondlife.LLUUID(value.ToString()); }); + + rowMapperSchema.AddMapping("WearableAsset12", + delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[12].AssetID.UUID; }, + delegate(AppearanceRowMapper mapper, Guid value) + { mapper.Object.Wearables[12].AssetID = new libsecondlife.LLUUID(value.ToString()); }); + + } + + public bool Add(Guid userID, AvatarAppearance appearance) + { + AppearanceRowMapper mapper = CreateRowMapper(appearance); + return Add(mapper); + } + + public bool Update(Guid userID, AvatarAppearance appearance) + { + AppearanceRowMapper mapper = CreateRowMapper(appearance); + return Update(appearance.ScenePresenceID.UUID, mapper); + } + + protected AppearanceRowMapper CreateRowMapper(AvatarAppearance appearance) + { + return new AppearanceRowMapper(m_schema, appearance); + } + + protected AppearanceRowMapper CreateRowMapper() + { + return CreateRowMapper(new AvatarAppearance()); + } + + protected AppearanceRowMapper FromReader(BaseDataReader reader, AvatarAppearance appearance) + { + AppearanceRowMapper mapper = CreateRowMapper(appearance); + mapper.FillObject(reader); + return mapper; + } + + public override AppearanceRowMapper FromReader(BaseDataReader reader) + { + AppearanceRowMapper mapper = CreateRowMapper(); + mapper.FillObject(reader); + return mapper; + } + + public bool TryGetValue(Guid presenceID, out AvatarAppearance val) + { + AppearanceRowMapper mapper; + if (TryGetValue(presenceID, out mapper)) + { + val = mapper.Object; + return true; + } + else + { + val = null; + return false; + } + } + } +} diff --git a/OpenSim/Region/Environment/Modules/AvatarFactoryModule.cs b/OpenSim/Region/Environment/Modules/AvatarFactoryModule.cs index 4dd1cb1183..19ebdb8d0b 100644 --- a/OpenSim/Region/Environment/Modules/AvatarFactoryModule.cs +++ b/OpenSim/Region/Environment/Modules/AvatarFactoryModule.cs @@ -35,6 +35,8 @@ using OpenSim.Framework.Communications.Cache; using OpenSim.Framework.Console; using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Scenes; +using OpenSim.Framework.Data; +using TribalMedia.Framework.Data; namespace OpenSim.Region.Environment.Modules { @@ -43,6 +45,12 @@ namespace OpenSim.Region.Environment.Modules private Scene m_scene = null; private readonly Dictionary m_avatarsAppearance = new Dictionary(); + private bool m_enablePersist = false; + private string m_connectionString; + private bool m_configured = false; + private BaseDatabaseConnector m_databaseMapper; + private AppearanceTableMapper m_appearanceMapper; + public bool TryGetAvatarAppearance(LLUUID avatarId, out AvatarAppearance appearance) { if (m_avatarsAppearance.ContainsKey(avatarId)) @@ -50,22 +58,31 @@ namespace OpenSim.Region.Environment.Modules appearance = m_avatarsAppearance[avatarId]; return true; } - else + + if (m_enablePersist) { - AvatarWearable[] wearables; - byte[] visualParams; - GetDefaultAvatarAppearance(out wearables, out visualParams); - appearance = new AvatarAppearance(avatarId, wearables, visualParams); - try + if (m_appearanceMapper.TryGetValue(avatarId.UUID, out appearance)) { + appearance.VisualParams = GetDefaultVisualParams(); + appearance.TextureEntry = AvatarAppearance.GetDefaultTextureEntry(); m_avatarsAppearance[avatarId] = appearance; + return true; } - catch (NullReferenceException) - { - MainLog.Instance.Error("AVATAR", "Unable to load appearance for uninitialized avatar"); - } - return true; } + + + //not found a appearance for user, so create a new one + AvatarWearable[] wearables; + byte[] visualParams; + GetDefaultAvatarAppearance(out wearables, out visualParams); + appearance = new AvatarAppearance(avatarId, wearables, visualParams); + + m_avatarsAppearance[avatarId] = appearance; + if (m_enablePersist) + { + m_appearanceMapper.Add(avatarId.UUID, appearance); + } + return true; } public void Initialise(Scene scene, IConfigSource source) @@ -77,6 +94,24 @@ namespace OpenSim.Region.Environment.Modules { m_scene = scene; } + + if (!m_configured) + { + m_configured = true; + try + { + m_enablePersist = source.Configs["Appearance"].GetBoolean("persist", false); + m_connectionString = source.Configs["Appearance"].GetString("connection_string", ""); + } + catch (Exception) + { + } + if (m_enablePersist) + { + m_databaseMapper = new MySQLDatabaseMapper(m_connectionString); + m_appearanceMapper = new AppearanceTableMapper(m_databaseMapper, "AvatarAppearance"); + } + } } public void PostInitialise() @@ -109,7 +144,7 @@ namespace OpenSim.Region.Environment.Modules public void AvatarIsWearing(Object sender, AvatarWearingArgs e) { - IClientAPI clientView = (IClientAPI) sender; + IClientAPI clientView = (IClientAPI)sender; CachedUserInfo profile = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(clientView.AgentId); if (profile != null) { @@ -134,6 +169,11 @@ namespace OpenSim.Region.Environment.Modules AvatarAppearance avatAppearance = m_avatarsAppearance[clientView.AgentId]; avatAppearance.Wearables[wear.Type].AssetID = assetId; avatAppearance.Wearables[wear.Type].ItemID = wear.ItemID; + + if (m_enablePersist) + { + m_appearanceMapper.Update(clientView.AgentId.UUID, avatAppearance); + } } } } diff --git a/OpenSim/Region/Environment/PermissionManager.cs b/OpenSim/Region/Environment/PermissionManager.cs index 9640ed748a..6c49586763 100644 --- a/OpenSim/Region/Environment/PermissionManager.cs +++ b/OpenSim/Region/Environment/PermissionManager.cs @@ -170,31 +170,9 @@ namespace OpenSim.Region.Environment // the administrator object permissions to take effect. LLUUID objectOwner = task.OwnerID; - //return task.RootPart.ObjectFlags;task.RootPart.ObjectFlags | - uint objectOwnerMask = task.RootPart.ObjectFlags; + objectOwnerMask = ApplyObjectModifyMasks(task.RootPart.OwnerMask, objectOwnerMask); - if((task.RootPart.OwnerMask & (uint)PermissionMask.Copy) != 0) - { - objectOwnerMask |= (uint)LLObject.ObjectFlags.ObjectCopy; - } - - if ((task.RootPart.OwnerMask & (uint) PermissionMask.Move) != 0) - { - objectOwnerMask |= (uint)LLObject.ObjectFlags.ObjectMove; - } - - if ((task.RootPart.OwnerMask & (uint) PermissionMask.Modify) != 0) - { - objectOwnerMask |= (uint)LLObject.ObjectFlags.ObjectModify; - } - - if ((task.RootPart.OwnerMask & (uint) PermissionMask.Transfer) != 0) - { - objectOwnerMask |= (uint)LLObject.ObjectFlags.ObjectTransfer; - } - - uint objectGroupMask = task.RootPart.ObjectFlags | task.RootPart.GroupMask; uint objectEveryoneMask = task.RootPart.ObjectFlags | task.RootPart.EveryoneMask; if (m_bypassPermissions) @@ -240,6 +218,31 @@ namespace OpenSim.Region.Environment return objectEveryoneMask; } + + private uint ApplyObjectModifyMasks(uint parentMask, uint objectOwnerMask) + { + if ((parentMask & (uint)PermissionMask.Copy) != 0) + { + objectOwnerMask |= (uint)LLObject.ObjectFlags.ObjectCopy; + } + + if ((parentMask & (uint)PermissionMask.Move) != 0) + { + objectOwnerMask |= (uint)LLObject.ObjectFlags.ObjectMove; + } + + if ((parentMask & (uint)PermissionMask.Modify) != 0) + { + objectOwnerMask |= (uint)LLObject.ObjectFlags.ObjectModify; + } + + if ((parentMask & (uint)PermissionMask.Transfer) != 0) + { + objectOwnerMask |= (uint)LLObject.ObjectFlags.ObjectTransfer; + } + return objectOwnerMask; + } + protected virtual bool GenericObjectPermission(LLUUID currentUser, LLUUID objId) { // Default: deny diff --git a/OpenSim/Region/Environment/Scenes/AvatarAppearance.cs b/OpenSim/Region/Environment/Scenes/AvatarAppearance.cs index 1583124b8c..b54f777404 100644 --- a/OpenSim/Region/Environment/Scenes/AvatarAppearance.cs +++ b/OpenSim/Region/Environment/Scenes/AvatarAppearance.cs @@ -35,8 +35,20 @@ namespace OpenSim.Region.Environment.Scenes public class AvatarAppearance { protected LLUUID m_scenePresenceID; + + public LLUUID ScenePresenceID + { + get { return m_scenePresenceID; } + set { m_scenePresenceID = value; } + } protected int m_wearablesSerial = 1; + public int WearablesSerial + { + get { return m_wearablesSerial; } + set { m_wearablesSerial = value; } + } + protected byte[] m_visualParams; public byte[] VisualParams diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index 043b094246..159eaf1f8c 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -72,6 +72,7 @@ namespace OpenSim.Region.Environment.Scenes public partial class SceneObjectPart : IScriptHost { + [XmlIgnore] public PhysicsActor PhysActor = null; public LLUUID LastOwnerID; @@ -764,11 +765,13 @@ namespace OpenSim.Region.Environment.Scenes public void TrimPermissions() { + BaseMask &= (uint)PermissionMask.All; OwnerMask &= (uint)PermissionMask.All; GroupMask &= (uint)PermissionMask.All; EveryoneMask &= (uint)PermissionMask.All; NextOwnerMask &= (uint)PermissionMask.All; + } /// diff --git a/ThirdParty/TribalMedia/TribalMedia.Framework.Data/BaseDatabaseConnector.cs b/ThirdParty/TribalMedia/TribalMedia.Framework.Data/BaseDatabaseConnector.cs index e5d4d62066..45ca650c53 100644 --- a/ThirdParty/TribalMedia/TribalMedia.Framework.Data/BaseDatabaseConnector.cs +++ b/ThirdParty/TribalMedia/TribalMedia.Framework.Data/BaseDatabaseConnector.cs @@ -138,4 +138,5 @@ namespace TribalMedia.Framework.Data public abstract BaseDataReader CreateReader(IDataReader reader); } + } \ No newline at end of file diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 3bcbdd254d..366978d929 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -241,3 +241,7 @@ CompileWithDebugInformation=true CleanUpOldScriptsOnStartup=true +[Appearance] +persist = false +connection_string = "Data Source=localhost;Database=avatar_appearance;User ID=root;Password=xxxx;pooling=false;" + diff --git a/prebuild.xml b/prebuild.xml index 6e64ce4bf6..567715be7f 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -141,6 +141,7 @@ + @@ -651,6 +652,7 @@ + diff --git a/share/sql/mysql-AvatarAppearance.sql b/share/sql/mysql-AvatarAppearance.sql new file mode 100644 index 0000000000..d9d3de08ad --- /dev/null +++ b/share/sql/mysql-AvatarAppearance.sql @@ -0,0 +1,42 @@ +-- +-- Create schema avatar_appearance +-- + +CREATE DATABASE IF NOT EXISTS avatar_appearance; +USE avatar_appearance; + +DROP TABLE IF EXISTS `avatarappearance`; +CREATE TABLE `avatarappearance` ( + `UUID` char(36) NOT NULL, + `Serial` int(10) unsigned NOT NULL, + `WearableItem0` char(36) NOT NULL, + `WearableAsset0` char(36) NOT NULL, + `WearableItem1` char(36) NOT NULL, + `WearableAsset1` char(36) NOT NULL, + `WearableItem2` char(36) NOT NULL, + `WearableAsset2` char(36) NOT NULL, + `WearableItem3` char(36) NOT NULL, + `WearableAsset3` char(36) NOT NULL, + `WearableItem4` char(36) NOT NULL, + `WearableAsset4` char(36) NOT NULL, + `WearableItem5` char(36) NOT NULL, + `WearableAsset5` char(36) NOT NULL, + `WearableItem6` char(36) NOT NULL, + `WearableAsset6` char(36) NOT NULL, + `WearableItem7` char(36) NOT NULL, + `WearableAsset7` char(36) NOT NULL, + `WearableItem8` char(36) NOT NULL, + `WearableAsset8` char(36) NOT NULL, + `WearableItem9` char(36) NOT NULL, + `WearableAsset9` char(36) NOT NULL, + `WearableItem10` char(36) NOT NULL, + `WearableAsset10` char(36) NOT NULL, + `WearableItem11` char(36) NOT NULL, + `WearableAsset11` char(36) NOT NULL, + `WearableItem12` char(36) NOT NULL, + `WearableAsset12` char(36) NOT NULL, + + + PRIMARY KEY (`UUID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +