diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 3c7727f738..3149eaa60b 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -1562,11 +1562,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController assets = doc.GetElementsByTagName("RequiredAsset"); foreach (XmlNode asset in assets) { - AssetBase rass = new AssetBase(); - rass.FullID = UUID.Random(); - rass.Name = GetStringAttribute(asset,"name",""); + AssetBase rass = new AssetBase(UUID.Random(), GetStringAttribute(asset,"name",""), SByte.Parse(GetStringAttribute(asset,"type",""))); rass.Description = GetStringAttribute(asset,"desc",""); - rass.Type = SByte.Parse(GetStringAttribute(asset,"type","")); rass.Local = Boolean.Parse(GetStringAttribute(asset,"local","")); rass.Temporary = Boolean.Parse(GetStringAttribute(asset,"temporary","")); rass.Data = Convert.FromBase64String(asset.InnerText); diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/RestAssetServices.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/RestAssetServices.cs index f862af1fb7..66572d5f5a 100644 --- a/OpenSim/ApplicationPlugins/Rest/Inventory/RestAssetServices.cs +++ b/OpenSim/ApplicationPlugins/Rest/Inventory/RestAssetServices.cs @@ -261,11 +261,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory modified = (asset != null); created = !modified; - asset = new AssetBase(); - asset.FullID = uuid; - asset.Name = xml.GetAttribute("name"); + asset = new AssetBase(uuid, xml.GetAttribute("name"), SByte.Parse(xml.GetAttribute("type"))); asset.Description = xml.GetAttribute("desc"); - asset.Type = SByte.Parse(xml.GetAttribute("type")); asset.Local = Int32.Parse(xml.GetAttribute("local")) != 0; asset.Temporary = Int32.Parse(xml.GetAttribute("temporary")) != 0; asset.Data = Convert.FromBase64String(xml.ReadElementContentAsString("Asset", "")); @@ -341,11 +338,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory modified = (asset != null); created = !modified; - asset = new AssetBase(); - asset.FullID = uuid; - asset.Name = xml.GetAttribute("name"); + asset = new AssetBase(uuid, xml.GetAttribute("name"), SByte.Parse(xml.GetAttribute("type"))); asset.Description = xml.GetAttribute("desc"); - asset.Type = SByte.Parse(xml.GetAttribute("type")); asset.Local = Int32.Parse(xml.GetAttribute("local")) != 0; asset.Temporary = Int32.Parse(xml.GetAttribute("temporary")) != 0; asset.Data = Convert.FromBase64String(xml.ReadElementContentAsString("Asset", "")); diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/RestInventoryServices.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/RestInventoryServices.cs index 4e03e67c3e..01bfe00686 100644 --- a/OpenSim/ApplicationPlugins/Rest/Inventory/RestInventoryServices.cs +++ b/OpenSim/ApplicationPlugins/Rest/Inventory/RestInventoryServices.cs @@ -1869,10 +1869,9 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory // Create AssetBase entity to hold the inlined asset - asset = new AssetBase(uuid, name); + asset = new AssetBase(uuid, name, type); asset.Description = desc; - asset.Type = type; // type == 0 == texture asset.Local = local; asset.Temporary = temp; diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index 204603d3b0..0cae3dd513 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs @@ -676,6 +676,7 @@ namespace OpenSim.Client.MXP.ClientStack public event FriendActionDelegate OnApproveFriendRequest; public event FriendActionDelegate OnDenyFriendRequest; public event FriendshipTermination OnTerminateFriendship; + public event GrantUserFriendRights OnGrantUserRights; public event MoneyTransferRequest OnMoneyTransferRequest; public event EconomyDataRequest OnEconomyDataRequest; public event MoneyBalanceRequest OnMoneyBalanceRequest; @@ -1052,7 +1053,7 @@ namespace OpenSim.Client.MXP.ClientStack { } - public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List items, List folders, bool fetchFolders, bool fetchItems) + public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List items, List folders, int version, bool fetchFolders, bool fetchItems) { // Need to translate to MXP somehow } diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index 4a54c679fd..fb87c1516a 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs @@ -327,6 +327,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack public event FriendActionDelegate OnApproveFriendRequest = delegate { }; public event FriendActionDelegate OnDenyFriendRequest = delegate { }; public event FriendshipTermination OnTerminateFriendship = delegate { }; + public event GrantUserFriendRights OnGrantUserRights = delegate { }; public event MoneyTransferRequest OnMoneyTransferRequest = delegate { }; public event EconomyDataRequest OnEconomyDataRequest = delegate { }; public event MoneyBalanceRequest OnMoneyBalanceRequest = delegate { }; @@ -406,6 +407,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack public event PlacesQuery OnPlacesQuery = delegate { }; + public void SetDebugPacketLevel(int newDebug) { throw new System.NotImplementedException(); @@ -606,7 +608,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack throw new System.NotImplementedException(); } - public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List items, List folders, bool fetchFolders, bool fetchItems) + public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List items, List folders, int version, bool fetchFolders, bool fetchItems) { throw new System.NotImplementedException(); } diff --git a/OpenSim/Data/MSSQL/MSSQLAssetData.cs b/OpenSim/Data/MSSQL/MSSQLAssetData.cs index 25f7cf019e..1ce4abfd16 100644 --- a/OpenSim/Data/MSSQL/MSSQLAssetData.cs +++ b/OpenSim/Data/MSSQL/MSSQLAssetData.cs @@ -132,12 +132,13 @@ namespace OpenSim.Data.MSSQL { if (reader.Read()) { - AssetBase asset = new AssetBase(); + AssetBase asset = new AssetBase( + new UUID((Guid)reader["id"]), + (string)reader["name"], + Convert.ToSByte(reader["assetType"]) + ); // Region Main - asset.FullID = new UUID((Guid)reader["id"]); - asset.Name = (string)reader["name"]; asset.Description = (string)reader["description"]; - asset.Type = Convert.ToSByte(reader["assetType"]); asset.Local = Convert.ToBoolean(reader["local"]); asset.Temporary = Convert.ToBoolean(reader["temporary"]); asset.Data = (byte[])reader["data"]; diff --git a/OpenSim/Data/MySQL/MySQLAssetData.cs b/OpenSim/Data/MySQL/MySQLAssetData.cs index 1fe6d2953d..6a4ccd7057 100644 --- a/OpenSim/Data/MySQL/MySQLAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLAssetData.cs @@ -151,10 +151,9 @@ namespace OpenSim.Data.MySQL { if (dbReader.Read()) { - asset = new AssetBase(); + asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["assetType"]); asset.Data = (byte[]) dbReader["data"]; asset.Description = (string) dbReader["description"]; - asset.FullID = assetID; string local = dbReader["local"].ToString(); if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase)) @@ -162,8 +161,6 @@ namespace OpenSim.Data.MySQL else asset.Local = false; - asset.Name = (string) dbReader["name"]; - asset.Type = (sbyte) dbReader["assetType"]; asset.Temporary = Convert.ToBoolean(dbReader["temporary"]); } dbReader.Close(); diff --git a/OpenSim/Data/SQLite/SQLiteAssetData.cs b/OpenSim/Data/SQLite/SQLiteAssetData.cs index 49275cbbae..23642b3974 100644 --- a/OpenSim/Data/SQLite/SQLiteAssetData.cs +++ b/OpenSim/Data/SQLite/SQLiteAssetData.cs @@ -162,22 +162,22 @@ namespace OpenSim.Data.SQLite } } - /// - /// Some... logging functionnality - /// - /// - private static void LogAssetLoad(AssetBase asset) - { - string temporary = asset.Temporary ? "Temporary" : "Stored"; - string local = asset.Local ? "Local" : "Remote"; - - int assetLength = (asset.Data != null) ? asset.Data.Length : 0; - - m_log.Debug("[ASSET DB]: " + - string.Format("Loaded {5} {4} Asset: [{0}][{3}] \"{1}\":{2} ({6} bytes)", - asset.FullID, asset.Name, asset.Description, asset.Type, - temporary, local, assetLength)); - } +// /// +// /// Some... logging functionnality +// /// +// /// +// private static void LogAssetLoad(AssetBase asset) +// { +// string temporary = asset.Temporary ? "Temporary" : "Stored"; +// string local = asset.Local ? "Local" : "Remote"; +// +// int assetLength = (asset.Data != null) ? asset.Data.Length : 0; +// +// m_log.Debug("[ASSET DB]: " + +// string.Format("Loaded {5} {4} Asset: [{0}][{3}] \"{1}\":{2} ({6} bytes)", +// asset.FullID, asset.Name, asset.Description, asset.Type, +// temporary, local, assetLength)); +// } /// /// Check if an asset exist in database @@ -231,12 +231,13 @@ namespace OpenSim.Data.SQLite // TODO: this doesn't work yet because something more // interesting has to be done to actually get these values // back out. Not enough time to figure it out yet. - AssetBase asset = new AssetBase(); + AssetBase asset = new AssetBase( + new UUID((String)row["UUID"]), + (String)row["Name"], + Convert.ToSByte(row["Type"]) + ); - asset.FullID = new UUID((String) row["UUID"]); - asset.Name = (String) row["Name"]; asset.Description = (String) row["Description"]; - asset.Type = Convert.ToSByte(row["Type"]); asset.Local = Convert.ToBoolean(row["Local"]); asset.Temporary = Convert.ToBoolean(row["Temporary"]); asset.Data = (byte[]) row["Data"]; diff --git a/OpenSim/Data/Tests/BasicAssetTest.cs b/OpenSim/Data/Tests/BasicAssetTest.cs index 1969d76a44..25aed61866 100644 --- a/OpenSim/Data/Tests/BasicAssetTest.cs +++ b/OpenSim/Data/Tests/BasicAssetTest.cs @@ -66,9 +66,9 @@ namespace OpenSim.Data.Tests [Test] public void T010_StoreSimpleAsset() { - AssetBase a1 = new AssetBase(uuid1, "asset one"); - AssetBase a2 = new AssetBase(uuid2, "asset two"); - AssetBase a3 = new AssetBase(uuid3, "asset three"); + AssetBase a1 = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture); + AssetBase a2 = new AssetBase(uuid2, "asset two", (sbyte)AssetType.Texture); + AssetBase a3 = new AssetBase(uuid3, "asset three", (sbyte)AssetType.Texture); a1.Data = asset1; a2.Data = asset1; a3.Data = asset1; diff --git a/OpenSim/Data/Tests/BasicRegionTest.cs b/OpenSim/Data/Tests/BasicRegionTest.cs index 60a8874adc..f76962cd37 100644 --- a/OpenSim/Data/Tests/BasicRegionTest.cs +++ b/OpenSim/Data/Tests/BasicRegionTest.cs @@ -252,7 +252,7 @@ namespace OpenSim.Data.Tests regionInfo.RegionLocX = 0; regionInfo.RegionLocY = 0; - Scene scene = new Scene(regionInfo); +// Scene scene = new Scene(regionInfo); SceneObjectPart sop = new SceneObjectPart(); sop.RegionHandle = regionh; diff --git a/OpenSim/Data/Tests/PropertyCompareConstraint.cs b/OpenSim/Data/Tests/PropertyCompareConstraint.cs index 06ca53ec90..5b1f935604 100644 --- a/OpenSim/Data/Tests/PropertyCompareConstraint.cs +++ b/OpenSim/Data/Tests/PropertyCompareConstraint.cs @@ -297,8 +297,8 @@ namespace OpenSim.Data.Tests public void AssetShouldMatch() { UUID uuid1 = UUID.Random(); - AssetBase actual = new AssetBase(uuid1, "asset one"); - AssetBase expected = new AssetBase(uuid1, "asset one"); + AssetBase actual = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture); + AssetBase expected = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture); var constraint = Constraints.PropertyCompareConstraint(expected); @@ -309,8 +309,8 @@ namespace OpenSim.Data.Tests public void AssetShouldNotMatch() { UUID uuid1 = UUID.Random(); - AssetBase actual = new AssetBase(uuid1, "asset one"); - AssetBase expected = new AssetBase(UUID.Random(), "asset one"); + AssetBase actual = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture); + AssetBase expected = new AssetBase(UUID.Random(), "asset one", (sbyte)AssetType.Texture); var constraint = Constraints.PropertyCompareConstraint(expected); @@ -321,8 +321,8 @@ namespace OpenSim.Data.Tests public void AssetShouldNotMatch2() { UUID uuid1 = UUID.Random(); - AssetBase actual = new AssetBase(uuid1, "asset one"); - AssetBase expected = new AssetBase(uuid1, "asset two"); + AssetBase actual = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture); + AssetBase expected = new AssetBase(uuid1, "asset two", (sbyte)AssetType.Texture); var constraint = Constraints.PropertyCompareConstraint(expected); diff --git a/OpenSim/Data/Tests/PropertyScrambler.cs b/OpenSim/Data/Tests/PropertyScrambler.cs index 72aaff1d0a..c968364919 100644 --- a/OpenSim/Data/Tests/PropertyScrambler.cs +++ b/OpenSim/Data/Tests/PropertyScrambler.cs @@ -165,7 +165,7 @@ namespace OpenSim.Data.Tests [Test] public void TestScramble() { - AssetBase actual = new AssetBase(UUID.Random(), "asset one"); + AssetBase actual = new AssetBase(UUID.Random(), "asset one", (sbyte)AssetType.Texture); new PropertyScrambler().Scramble(actual); } @@ -173,8 +173,7 @@ namespace OpenSim.Data.Tests public void DontScramble() { UUID uuid = UUID.Random(); - AssetBase asset = new AssetBase(); - asset.FullID = uuid; + AssetBase asset = new AssetBase(uuid, "asset", (sbyte)AssetType.Texture); new PropertyScrambler() .DontScramble(x => x.Metadata) .DontScramble(x => x.FullID) diff --git a/OpenSim/Framework/AssetBase.cs b/OpenSim/Framework/AssetBase.cs index 9679ff2512..212f41de39 100644 --- a/OpenSim/Framework/AssetBase.cs +++ b/OpenSim/Framework/AssetBase.cs @@ -27,6 +27,8 @@ using System; using System.Xml.Serialization; +using System.Reflection; +using log4net; using OpenMetaverse; namespace OpenSim.Framework @@ -37,6 +39,8 @@ namespace OpenSim.Framework [Serializable] public class AssetBase { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + /// /// Data of the Asset /// @@ -47,16 +51,44 @@ namespace OpenSim.Framework /// private AssetMetadata m_metadata; + // This is needed for .NET serialization!!! + // Do NOT "Optimize" away! public AssetBase() { m_metadata = new AssetMetadata(); + m_metadata.FullID = UUID.Zero; + m_metadata.ID = UUID.Zero.ToString(); + m_metadata.Type = (sbyte)AssetType.Unknown; } - public AssetBase(UUID assetId, string name) + public AssetBase(UUID assetID, string name, sbyte assetType) { + if (assetType == (sbyte)AssetType.Unknown) + { + System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(true); + m_log.ErrorFormat("[ASSETBASE]: Creating asset '{0}' ({1}) with an unknown asset type\n{2}", + name, assetID, trace.ToString()); + } + m_metadata = new AssetMetadata(); - m_metadata.FullID = assetId; + m_metadata.FullID = assetID; m_metadata.Name = name; + m_metadata.Type = assetType; + } + + public AssetBase(string assetID, string name, sbyte assetType) + { + if (assetType == (sbyte)AssetType.Unknown) + { + System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(true); + m_log.ErrorFormat("[ASSETBASE]: Creating asset '{0}' ({1}) with an unknown asset type\n{2}", + name, assetID, trace.ToString()); + } + + m_metadata = new AssetMetadata(); + m_metadata.ID = assetID; + m_metadata.Name = name; + m_metadata.Type = assetType; } public bool ContainsReferences @@ -193,11 +225,11 @@ namespace OpenSim.Framework private string m_name = String.Empty; private string m_description = String.Empty; private DateTime m_creation_date; - private sbyte m_type; + private sbyte m_type = (sbyte)AssetType.Unknown; private string m_content_type; private byte[] m_sha1; - private bool m_local = false; - private bool m_temporary = false; + private bool m_local; + private bool m_temporary; //private Dictionary m_methods = new Dictionary(); //private OSDMap m_extra_data; @@ -211,7 +243,13 @@ namespace OpenSim.Framework { //get { return m_fullid.ToString(); } //set { m_fullid = new UUID(value); } - get { return m_id; } + get + { + if (String.IsNullOrEmpty(m_id)) + m_id = m_fullid.ToString(); + + return m_id; + } set { UUID uuid = UUID.Zero; diff --git a/OpenSim/Framework/AssetLandmark.cs b/OpenSim/Framework/AssetLandmark.cs index fd7a2cd184..058b442d58 100644 --- a/OpenSim/Framework/AssetLandmark.cs +++ b/OpenSim/Framework/AssetLandmark.cs @@ -38,11 +38,9 @@ namespace OpenSim.Framework public int Version; public AssetLandmark(AssetBase a) + : base(a.FullID, a.Name, a.Type) { Data = a.Data; - FullID = a.FullID; - Type = a.Type; - Name = a.Name; Description = a.Description; InternData(); } diff --git a/OpenSim/Framework/AssetLoader/Filesystem/AssetLoaderFileSystem.cs b/OpenSim/Framework/AssetLoader/Filesystem/AssetLoaderFileSystem.cs index a394b1afd1..6ab1b58ad6 100644 --- a/OpenSim/Framework/AssetLoader/Filesystem/AssetLoaderFileSystem.cs +++ b/OpenSim/Framework/AssetLoader/Filesystem/AssetLoaderFileSystem.cs @@ -43,18 +43,15 @@ namespace OpenSim.Framework.AssetLoader.Filesystem { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - protected static AssetBase CreateAsset(string assetIdStr, string name, string path, bool isImage) + protected static AssetBase CreateAsset(string assetIdStr, string name, string path, sbyte type) { - AssetBase asset = new AssetBase( - new UUID(assetIdStr), - name - ); + AssetBase asset = new AssetBase(new UUID(assetIdStr), name, type); if (!String.IsNullOrEmpty(path)) { //m_log.InfoFormat("[ASSETS]: Loading: [{0}][{1}]", name, path); - LoadAsset(asset, isImage, path); + LoadAsset(asset, path); } else { @@ -64,8 +61,14 @@ namespace OpenSim.Framework.AssetLoader.Filesystem return asset; } - protected static void LoadAsset(AssetBase info, bool image, string path) + protected static void LoadAsset(AssetBase info, string path) { +// bool image = +// (info.Type == (sbyte)AssetType.Texture || +// info.Type == (sbyte)AssetType.TextureTGA || +// info.Type == (sbyte)AssetType.ImageJPEG || +// info.Type == (sbyte)AssetType.ImageTGA); + FileInfo fInfo = new FileInfo(path); long numBytes = fInfo.Length; if (fInfo.Exists) @@ -138,10 +141,10 @@ namespace OpenSim.Framework.AssetLoader.Filesystem { string assetIdStr = source.Configs[i].GetString("assetID", UUID.Random().ToString()); string name = source.Configs[i].GetString("name", String.Empty); - sbyte type = (sbyte) source.Configs[i].GetInt("assetType", 0); + sbyte type = (sbyte)source.Configs[i].GetInt("assetType", 0); string assetPath = Path.Combine(dir, source.Configs[i].GetString("fileName", String.Empty)); - AssetBase newAsset = CreateAsset(assetIdStr, name, assetPath, false); + AssetBase newAsset = CreateAsset(assetIdStr, name, assetPath, type); newAsset.Type = type; assets.Add(newAsset); diff --git a/OpenSim/Framework/Capabilities/Caps.cs b/OpenSim/Framework/Capabilities/Caps.cs index 1dfb2d48c3..1f1ac78d93 100644 --- a/OpenSim/Framework/Capabilities/Caps.cs +++ b/OpenSim/Framework/Capabilities/Caps.cs @@ -89,7 +89,7 @@ namespace OpenSim.Framework.Capabilities //private static readonly string m_requestTexture = "0003/"; private static readonly string m_notecardUpdatePath = "0004/"; private static readonly string m_notecardTaskUpdatePath = "0005/"; - private static readonly string m_fetchInventoryPath = "0006/"; +// private static readonly string m_fetchInventoryPath = "0006/"; // The following entries are in a module, however, they are also here so that we don't re-assign // the path to another cap by mistake. @@ -208,7 +208,7 @@ namespace OpenSim.Framework.Capabilities // As of RC 1.22.9 of the Linden client this is // supported - m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest); + //m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest); // justincc: I've disabled the CAPS service for now to fix problems with selecting textures, and // subsequent inventory breakage, in the edit object pane (such as mantis 1085). This requires @@ -888,10 +888,7 @@ namespace OpenSim.Framework.Capabilities } AssetBase asset; - asset = new AssetBase(); - asset.FullID = assetID; - asset.Type = assType; - asset.Name = assetName; + asset = new AssetBase(assetID, assetName, assType); asset.Data = data; if (AddNewAsset != null) AddNewAsset(asset); diff --git a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs index aa71536c6c..6648c36e14 100644 --- a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs +++ b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs @@ -679,7 +679,7 @@ namespace OpenSim.Framework.Communications.Cache /// /// /// true if the request was queued or successfully processed, false otherwise - public bool SendInventoryDecendents(IClientAPI client, UUID folderID, bool fetchFolders, bool fetchItems) + public bool SendInventoryDecendents(IClientAPI client, UUID folderID, int version, bool fetchFolders, bool fetchItems) { if (m_hasReceivedInventory) { @@ -693,7 +693,7 @@ namespace OpenSim.Framework.Communications.Cache client.SendInventoryFolderDetails( client.AgentId, folderID, folder.RequestListOfItems(), - folder.RequestListOfFolders(), fetchFolders, fetchItems); + folder.RequestListOfFolders(), version, fetchFolders, fetchItems); return true; } diff --git a/OpenSim/Framework/Communications/Osp/OspResolver.cs b/OpenSim/Framework/Communications/Osp/OspResolver.cs index 32f0efce27..401389648a 100644 --- a/OpenSim/Framework/Communications/Osp/OspResolver.cs +++ b/OpenSim/Framework/Communications/Osp/OspResolver.cs @@ -93,7 +93,7 @@ namespace OpenSim.Framework.Communications.Osp if (!ospa.StartsWith(OSPA_PREFIX)) return UUID.Zero; - m_log.DebugFormat("[OSP RESOLVER]: Resolving {0}", ospa); +// m_log.DebugFormat("[OSP RESOLVER]: Resolving {0}", ospa); string ospaMeat = ospa.Substring(OSPA_PREFIX.Length); string[] ospaTuples = ospaMeat.Split(OSPA_TUPLE_SEPARATOR_ARRAY); diff --git a/OpenSim/Framework/Communications/Tests/Cache/AssetCacheTests.cs b/OpenSim/Framework/Communications/Tests/Cache/AssetCacheTests.cs deleted file mode 100644 index caaebd7b0d..0000000000 --- a/OpenSim/Framework/Communications/Tests/Cache/AssetCacheTests.cs +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Threading; -using NUnit.Framework; -using NUnit.Framework.SyntaxHelpers; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Framework.Communications.Cache; -using OpenSim.Services.Interfaces; -using OpenSim.Tests.Common.Mock; - -namespace OpenSim.Framework.Communications.Tests -{ - /// - /// Asset cache tests - /// - [TestFixture] - public class AssetCacheTests - { - private class FakeUserService : IUserService - { - public void AddTemporaryUserProfile(UserProfileData userProfile) - { - throw new NotImplementedException(); - } - - public UserProfileData GetUserProfile(string firstName, string lastName) - { - throw new NotImplementedException(); - } - - public UserProfileData GetUserProfile(UUID userId) - { - throw new NotImplementedException(); - } - - public UserProfileData GetUserProfile(Uri uri) - { - UserProfileData userProfile = new UserProfileData(); - -// userProfile.ID = new UUID(Util.GetHashGuid(uri.ToString(), AssetCache.AssetInfo.Secret)); - - return userProfile; - } - - public Uri GetUserUri(UserProfileData userProfile) - { - throw new NotImplementedException(); - } - - public UserAgentData GetAgentByUUID(UUID userId) - { - throw new NotImplementedException(); - } - - public void ClearUserAgent(UUID avatarID) - { - throw new NotImplementedException(); - } - - public List GenerateAgentPickerRequestResponse(UUID QueryID, string Query) - { - throw new NotImplementedException(); - } - - public UserProfileData SetupMasterUser(string firstName, string lastName) - { - throw new NotImplementedException(); - } - - public UserProfileData SetupMasterUser(string firstName, string lastName, string password) - { - throw new NotImplementedException(); - } - - public UserProfileData SetupMasterUser(UUID userId) - { - throw new NotImplementedException(); - } - - public bool UpdateUserProfile(UserProfileData data) - { - throw new NotImplementedException(); - } - - public void AddNewUserFriend(UUID friendlistowner, UUID friend, uint perms) - { - throw new NotImplementedException(); - } - - public void RemoveUserFriend(UUID friendlistowner, UUID friend) - { - throw new NotImplementedException(); - } - - public void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms) - { - throw new NotImplementedException(); - } - - public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, Vector3 position, Vector3 lookat) - { - throw new NotImplementedException(); - } - - public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, float posx, float posy, float posz) - { - throw new NotImplementedException(); - } - - public List GetUserFriendList(UUID friendlistowner) - { - throw new NotImplementedException(); - } - - public bool VerifySession(UUID userID, UUID sessionID) - { - return true; - } - - public void SetInventoryService(IInventoryService inv) - { - throw new NotImplementedException(); - } - - public virtual bool AuthenticateUserByPassword(UUID userID, string password) - { - throw new NotImplementedException(); - } - } - } -} diff --git a/OpenSim/Framework/Communications/Tests/LoginServiceTests.cs b/OpenSim/Framework/Communications/Tests/LoginServiceTests.cs index e891d9c11d..60f0ba8ef6 100644 --- a/OpenSim/Framework/Communications/Tests/LoginServiceTests.cs +++ b/OpenSim/Framework/Communications/Tests/LoginServiceTests.cs @@ -75,7 +75,7 @@ namespace OpenSim.Framework.Communications.Tests m_regionConnector.AddRegion(new RegionInfo(42, 43, m_capsEndPoint, m_regionExternalName)); - //IInventoryService m_inventoryService = new TestInventoryService(); + //IInventoryService m_inventoryService = new MockInventoryService(); m_localUserServices = (LocalUserServices) m_commsManager.UserService; m_localUserServices.AddUser(m_firstName,m_lastName,"boingboing","abc@ftw.com",42,43); @@ -95,7 +95,8 @@ namespace OpenSim.Framework.Communications.Tests TestHelper.InMethod(); // We want to use our own LoginService for this test, one that // doesn't require authentication. - new LLStandaloneLoginService((UserManagerBase)m_commsManager.UserService, "Hello folks", new TestInventoryService(), + new LLStandaloneLoginService( + (UserManagerBase)m_commsManager.UserService, "Hello folks", new MockInventoryService(), m_commsManager.NetworkServersInfo, false, new LibraryRootFolder(String.Empty), m_regionConnector); Hashtable loginParams = new Hashtable(); @@ -457,148 +458,4 @@ namespace OpenSim.Framework.Communications.Tests #endregion } } - - class TestInventoryService : IInventoryService - { - public TestInventoryService() - { - } - - /// - /// - /// - /// - /// - public bool CreateUserInventory(UUID userId) - { - return false; - } - - /// - /// - /// - /// - /// - public List GetInventorySkeleton(UUID userId) - { - List folders = new List(); - InventoryFolderBase folder = new InventoryFolderBase(); - folder.ID = UUID.Random(); - folder.Owner = userId; - folders.Add(folder); - return folders; - } - - /// - /// Returns a list of all the active gestures in a user's inventory. - /// - /// - /// The of the user - /// - /// - /// A flat list of the gesture items. - /// - public List GetActiveGestures(UUID userId) - { - return null; - } - - public InventoryCollection GetUserInventory(UUID userID) - { - return null; - } - - public void GetUserInventory(UUID userID, OpenSim.Services.Interfaces.InventoryReceiptCallback callback) - { - } - - public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) - { - return null; - } - - public InventoryCollection GetFolderContent(UUID userID, UUID folderID) - { - return null; - } - - public List GetFolderItems(UUID userID, UUID folderID) - { - return null; - } - - public bool AddFolder(InventoryFolderBase folder) - { - return false; - } - - public bool UpdateFolder(InventoryFolderBase folder) - { - return false; - } - - public bool MoveFolder(InventoryFolderBase folder) - { - return false; - } - - public bool DeleteFolders(UUID ownerID, List ids) - { - return false; - } - - public bool PurgeFolder(InventoryFolderBase folder) - { - return false; - } - - public bool AddItem(InventoryItemBase item) - { - return false; - } - - public bool UpdateItem(InventoryItemBase item) - { - return false; - } - - public bool MoveItems(UUID owner, List items) - { - return false; - } - - public bool DeleteItems(UUID owner, List items) - { - return false; - } - - public InventoryItemBase GetItem(InventoryItemBase item) - { - return null; - } - - public InventoryFolderBase GetFolder(InventoryFolderBase folder) - { - return null; - } - - public bool HasInventoryForUser(UUID userID) - { - return false; - } - - public InventoryFolderBase GetRootFolder(UUID userID) - { - InventoryFolderBase root = new InventoryFolderBase(); - root.ID = UUID.Random(); - root.Owner = userID; - root.ParentID = UUID.Zero; - return root; - } - - public int GetAssetPermissions(UUID userID, UUID assetID) - { - return 1; - } - } -} +} \ No newline at end of file diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index d304345b83..04ba9c69e9 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -446,6 +446,7 @@ namespace OpenSim.Framework public delegate void AvatarNotesUpdate(IClientAPI client, UUID targetID, string notes); public delegate void MuteListRequest(IClientAPI client, uint muteCRC); public delegate void AvatarInterestUpdate(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages); + public delegate void GrantUserFriendRights(IClientAPI client, UUID requester, UUID target, int rights); public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client); public delegate void AgentFOV(IClientAPI client, float verticalAngle); @@ -591,7 +592,6 @@ namespace OpenSim.Framework public readonly Vector3 Velocity; public readonly Vector3 Acceleration; public readonly Vector3 AngularVelocity; - public readonly byte State; public readonly UUID AssetID; public readonly UUID OwnerID; public readonly int AttachPoint; @@ -599,7 +599,7 @@ namespace OpenSim.Framework public readonly double Priority; public SendPrimitiveTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, - Quaternion rotation, Vector3 velocity, Vector3 acceleration, Vector3 rotationalvelocity, byte state, + Quaternion rotation, Vector3 velocity, Vector3 acceleration, Vector3 rotationalvelocity, UUID assetID, UUID ownerID, int attachPoint, byte[] textureEntry, double priority) { RegionHandle = regionHandle; @@ -610,7 +610,6 @@ namespace OpenSim.Framework Velocity = velocity; Acceleration = acceleration; AngularVelocity = rotationalvelocity; - State = state; AssetID = assetID; OwnerID = ownerID; AttachPoint = attachPoint; @@ -1023,6 +1022,7 @@ namespace OpenSim.Framework event PickInfoUpdate OnPickInfoUpdate; event AvatarNotesUpdate OnAvatarNotesUpdate; event AvatarInterestUpdate OnAvatarInterestUpdate; + event GrantUserFriendRights OnGrantUserRights; event MuteListRequest OnMuteListRequest; @@ -1124,7 +1124,7 @@ namespace OpenSim.Framework void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler); void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List items, - List folders, bool fetchFolders, + List folders, int version, bool fetchFolders, bool fetchItems); void FlushPrimUpdates(); diff --git a/OpenSim/Framework/Parallel.cs b/OpenSim/Framework/Parallel.cs index 515852f323..a0394f2c25 100644 --- a/OpenSim/Framework/Parallel.cs +++ b/OpenSim/Framework/Parallel.cs @@ -69,7 +69,7 @@ namespace OpenSim.Framework Util.FireAndForget( delegate(object o) { - int threadIndex = (int)o; +// int threadIndex = (int)o; while (exception == null) { @@ -126,7 +126,7 @@ namespace OpenSim.Framework Util.FireAndForget( delegate(object o) { - int threadIndex = (int)o; +// int threadIndex = (int)o; while (exception == null) { @@ -182,7 +182,7 @@ namespace OpenSim.Framework Util.FireAndForget( delegate(object o) { - int threadIndex = (int)o; +// int threadIndex = (int)o; while (exception == null) { diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs index 5e4d1752a9..97231ff9c2 100644 --- a/OpenSim/Framework/PrimitiveBaseShape.cs +++ b/OpenSim/Framework/PrimitiveBaseShape.cs @@ -1066,5 +1066,106 @@ namespace OpenSim.Framework return data; } + + + /// + /// Creates a OpenMetaverse.Primitive and populates it with converted PrimitiveBaseShape values + /// + /// + public Primitive ToOmvPrimitive() + { + // position and rotation defaults here since they are not available in PrimitiveBaseShape + return ToOmvPrimitive(new Vector3(0.0f, 0.0f, 0.0f), + new Quaternion(0.0f, 0.0f, 0.0f, 1.0f)); + } + + + /// + /// Creates a OpenMetaverse.Primitive and populates it with converted PrimitiveBaseShape values + /// + /// + /// + /// + public Primitive ToOmvPrimitive(Vector3 position, Quaternion rotation) + { + OpenMetaverse.Primitive prim = new OpenMetaverse.Primitive(); + + prim.Scale = this.Scale; + prim.Position = position; + prim.Rotation = rotation; + + if (this.SculptEntry) + { + prim.Sculpt = new Primitive.SculptData(); + prim.Sculpt.Type = (OpenMetaverse.SculptType)this.SculptType; + prim.Sculpt.SculptTexture = this.SculptTexture; + + return prim; + } + + prim.PrimData.PathShearX = this.PathShearX < 128 ? (float)this.PathShearX * 0.01f : (float)(this.PathShearX - 256) * 0.01f; + prim.PrimData.PathShearY = this.PathShearY < 128 ? (float)this.PathShearY * 0.01f : (float)(this.PathShearY - 256) * 0.01f; + prim.PrimData.PathBegin = (float)this.PathBegin * 2.0e-5f; + prim.PrimData.PathEnd = 1.0f - (float)this.PathEnd * 2.0e-5f; + + prim.PrimData.PathScaleX = (200 - this.PathScaleX) * 0.01f; + prim.PrimData.PathScaleY = (200 - this.PathScaleY) * 0.01f; + + prim.PrimData.PathTaperX = this.PathTaperX * 0.01f; + prim.PrimData.PathTaperY = this.PathTaperY * 0.01f; + + prim.PrimData.PathTwistBegin = this.PathTwistBegin * 0.01f; + prim.PrimData.PathTwist = this.PathTwist * 0.01f; + + prim.PrimData.ProfileBegin = (float)this.ProfileBegin * 2.0e-5f; + prim.PrimData.ProfileEnd = 1.0f - (float)this.ProfileEnd * 2.0e-5f; + prim.PrimData.ProfileHollow = (float)this.ProfileHollow * 2.0e-5f; + + prim.PrimData.profileCurve = this.ProfileCurve; + prim.PrimData.ProfileHole = (HoleType)this.HollowShape; + + prim.PrimData.PathCurve = (PathCurve)this.PathCurve; + prim.PrimData.PathRadiusOffset = 0.01f * this.PathRadiusOffset; + prim.PrimData.PathRevolutions = 1.0f + 0.015f * this.PathRevolutions; + prim.PrimData.PathSkew = 0.01f * this.PathSkew; + + prim.PrimData.PCode = OpenMetaverse.PCode.Prim; + prim.PrimData.State = 0; + + if (this.FlexiEntry) + { + prim.Flexible = new Primitive.FlexibleData(); + prim.Flexible.Drag = this.FlexiDrag; + prim.Flexible.Force = new Vector3(this.FlexiForceX, this.FlexiForceY, this.FlexiForceZ); + prim.Flexible.Gravity = this.FlexiGravity; + prim.Flexible.Softness = this.FlexiSoftness; + prim.Flexible.Tension = this.FlexiTension; + prim.Flexible.Wind = this.FlexiWind; + } + + if (this.LightEntry) + { + prim.Light = new Primitive.LightData(); + prim.Light.Color = new Color4(this.LightColorR, this.LightColorG, this.LightColorB, this.LightColorA); + prim.Light.Cutoff = this.LightCutoff; + prim.Light.Falloff = this.LightFalloff; + prim.Light.Intensity = this.LightIntensity; + prim.Light.Radius = this.LightRadius; + } + + prim.Textures = new Primitive.TextureEntry(this.TextureEntry, 0, this.TextureEntry.Length); + + prim.Properties = new Primitive.ObjectProperties(); + prim.Properties.Name = "Primitive"; + prim.Properties.Description = ""; + prim.Properties.CreatorID = UUID.Zero; + prim.Properties.GroupID = UUID.Zero; + prim.Properties.OwnerID = UUID.Zero; + prim.Properties.Permissions = new Permissions(); + prim.Properties.SalePrice = 10; + prim.Properties.SaleType = new SaleType(); + + return prim; + } } } diff --git a/OpenSim/Framework/Tests/AssetBaseTest.cs b/OpenSim/Framework/Tests/AssetBaseTest.cs index 3dc6b4ee4f..18a3e011d5 100644 --- a/OpenSim/Framework/Tests/AssetBaseTest.cs +++ b/OpenSim/Framework/Tests/AssetBaseTest.cs @@ -67,8 +67,7 @@ namespace OpenSim.Framework.Tests private void CheckContainsReferences(AssetType assetType, bool expected) { - AssetBase asset = new AssetBase(); - asset.Type = (sbyte)assetType; + AssetBase asset = new AssetBase(UUID.Zero, String.Empty, (sbyte)assetType); bool actual = asset.ContainsReferences; Assert.AreEqual(expected, actual, "Expected "+assetType+".ContainsReferences to be "+expected+" but was "+actual+"."); } diff --git a/OpenSim/Framework/ThreadTracker.cs b/OpenSim/Framework/ThreadTracker.cs index b68d9b3278..069e98b378 100644 --- a/OpenSim/Framework/ThreadTracker.cs +++ b/OpenSim/Framework/ThreadTracker.cs @@ -35,7 +35,7 @@ namespace OpenSim.Framework { public static class ThreadTracker { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public static ProcessThreadCollection GetThreads() { diff --git a/OpenSim/Grid/MessagingServer.Modules/MessageRegionModule.cs b/OpenSim/Grid/MessagingServer.Modules/MessageRegionModule.cs index dedf8768b1..b9d3f22300 100644 --- a/OpenSim/Grid/MessagingServer.Modules/MessageRegionModule.cs +++ b/OpenSim/Grid/MessagingServer.Modules/MessageRegionModule.cs @@ -48,7 +48,7 @@ namespace OpenSim.Grid.MessagingServer.Modules { public class MessageRegionModule : IMessageRegionLookup { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private MessageServerConfig m_cfg; diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index db0c3b8692..7eb829ece5 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -220,6 +220,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event FriendActionDelegate OnApproveFriendRequest; public event FriendActionDelegate OnDenyFriendRequest; public event FriendshipTermination OnTerminateFriendship; + public event GrantUserFriendRights OnGrantUserRights; public event MoneyTransferRequest OnMoneyTransferRequest; public event EconomyDataRequest OnEconomyDataRequest; public event MoneyBalanceRequest OnMoneyBalanceRequest; @@ -1251,7 +1252,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Do we need to send folder information? /// Do we need to send item information? public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List items, - List folders, + List folders, int version, bool fetchFolders, bool fetchItems) { // An inventory descendents packet consists of a single agent section and an inventory details @@ -1264,174 +1265,107 @@ namespace OpenSim.Region.ClientStack.LindenUDP // // for one example of this kind of thing. In fact, the Linden servers appear to only send about // 6 to 7 items at a time, so let's stick with 6 - int MAX_ITEMS_PER_PACKET = 6; - - //Ckrinke This variable is not used, so comment out to remove the warning from the compiler (3-21-08) - //Ckrinke uint FULL_MASK_PERMISSIONS = 2147483647; + int MAX_ITEMS_PER_PACKET = 5; + int MAX_FOLDERS_PER_PACKET = 6; + int totalItems = fetchItems ? items.Count : 0; + int totalFolders = fetchFolders ? folders.Count : 0; int itemsSent = 0; - if (fetchItems) - { - InventoryDescendentsPacket descend = CreateInventoryDescendentsPacket(ownerID, folderID); + int foldersSent = 0; + int foldersToSend = 0; + int itemsToSend = 0; - if (items.Count < MAX_ITEMS_PER_PACKET) + InventoryDescendentsPacket currentPacket = null; + + // Handle empty folders + // + if (totalItems == 0 && totalFolders == 0) + currentPacket = CreateInventoryDescendentsPacket(ownerID, folderID, version, items.Count + folders.Count, 0, 0); + + // To preserve SL compatibility, we will NOT combine folders and items in one packet + // + while(itemsSent < totalItems || foldersSent < totalFolders) + { + if (currentPacket == null) // Start a new packet { - descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items.Count]; + foldersToSend = totalFolders - foldersSent; + if (foldersToSend > MAX_FOLDERS_PER_PACKET) + foldersToSend = MAX_FOLDERS_PER_PACKET; + + if (foldersToSend == 0) + { + itemsToSend = totalItems - itemsSent; + if (itemsToSend > MAX_ITEMS_PER_PACKET) + itemsToSend = MAX_ITEMS_PER_PACKET; + } + + currentPacket = CreateInventoryDescendentsPacket(ownerID, folderID, version, items.Count + folders.Count, foldersToSend, itemsToSend); } + + if (foldersToSend-- > 0) + currentPacket.FolderData[foldersSent % MAX_FOLDERS_PER_PACKET] = CreateFolderDataBlock(folders[foldersSent++]); + else if(itemsToSend-- > 0) + currentPacket.ItemData[itemsSent % MAX_ITEMS_PER_PACKET] = CreateItemDataBlock(items[itemsSent++]); else { - descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[MAX_ITEMS_PER_PACKET]; + OutPacket(currentPacket, ThrottleOutPacketType.Asset, false); + currentPacket = null; } - // Descendents must contain the *total* number of descendents (plus folders, whether we - // fetch them or not), not the number of entries we send in this packet. For consistency, - // I'll use it for folder-requests, too, although I wasn't able to get one with - // FetchFolders = true. - // TODO this should be checked with FetchFolders = true - descend.AgentData.Descendents = items.Count + folders.Count; - - int count = 0; - int i = 0; - foreach (InventoryItemBase item in items) - { - descend.ItemData[i] = new InventoryDescendentsPacket.ItemDataBlock(); - descend.ItemData[i].ItemID = item.ID; - descend.ItemData[i].AssetID = item.AssetID; - descend.ItemData[i].CreatorID = item.CreatorIdAsUuid; - descend.ItemData[i].BaseMask = item.BasePermissions; - descend.ItemData[i].Description = Util.StringToBytes256(item.Description); - descend.ItemData[i].EveryoneMask = item.EveryOnePermissions; - descend.ItemData[i].OwnerMask = item.CurrentPermissions; - descend.ItemData[i].FolderID = item.Folder; - descend.ItemData[i].InvType = (sbyte)item.InvType; - descend.ItemData[i].Name = Util.StringToBytes256(item.Name); - descend.ItemData[i].NextOwnerMask = item.NextPermissions; - descend.ItemData[i].OwnerID = item.Owner; - descend.ItemData[i].Type = (sbyte)item.AssetType; - - descend.ItemData[i].GroupID = item.GroupID; - descend.ItemData[i].GroupOwned = item.GroupOwned; - descend.ItemData[i].GroupMask = item.GroupPermissions; - descend.ItemData[i].CreationDate = item.CreationDate; - descend.ItemData[i].SalePrice = item.SalePrice; - descend.ItemData[i].SaleType = item.SaleType; - descend.ItemData[i].Flags = item.Flags; - - descend.ItemData[i].CRC = - Helpers.InventoryCRC(descend.ItemData[i].CreationDate, descend.ItemData[i].SaleType, - descend.ItemData[i].InvType, descend.ItemData[i].Type, - descend.ItemData[i].AssetID, descend.ItemData[i].GroupID, - descend.ItemData[i].SalePrice, - descend.ItemData[i].OwnerID, descend.ItemData[i].CreatorID, - descend.ItemData[i].ItemID, descend.ItemData[i].FolderID, - descend.ItemData[i].EveryoneMask, - descend.ItemData[i].Flags, descend.ItemData[i].OwnerMask, - descend.ItemData[i].GroupMask, item.CurrentPermissions); - - i++; - count++; - itemsSent++; - if (i == MAX_ITEMS_PER_PACKET) - { - descend.Header.Zerocoded = true; - AddNullFolderBlockToDecendentsPacket(ref descend); - OutPacket(descend, ThrottleOutPacketType.Asset); - - if ((items.Count - count) > 0) - { - descend = CreateInventoryDescendentsPacket(ownerID, folderID); - if ((items.Count - count) < MAX_ITEMS_PER_PACKET) - { - descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items.Count - count]; - } - else - { - descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[MAX_ITEMS_PER_PACKET]; - } - descend.AgentData.Descendents = items.Count + folders.Count; - i = 0; - } - } - } - - if (0 < i && i < MAX_ITEMS_PER_PACKET) - { - AddNullFolderBlockToDecendentsPacket(ref descend); - OutPacket(descend, ThrottleOutPacketType.Asset); - } } - //send subfolders - if (fetchFolders) - { - InventoryDescendentsPacket descend = CreateInventoryDescendentsPacket(ownerID, folderID); + if (currentPacket != null) + OutPacket(currentPacket, ThrottleOutPacketType.Asset, false); + } - if (folders.Count < MAX_ITEMS_PER_PACKET) - { - descend.FolderData = new InventoryDescendentsPacket.FolderDataBlock[folders.Count]; - } - else - { - descend.FolderData = new InventoryDescendentsPacket.FolderDataBlock[MAX_ITEMS_PER_PACKET]; - } + private InventoryDescendentsPacket.FolderDataBlock CreateFolderDataBlock(InventoryFolderBase folder) + { + InventoryDescendentsPacket.FolderDataBlock newBlock = new InventoryDescendentsPacket.FolderDataBlock(); + newBlock.FolderID = folder.ID; + newBlock.Name = Util.StringToBytes256(folder.Name); + newBlock.ParentID = folder.ParentID; + newBlock.Type = (sbyte)folder.Type; - // Not sure if this scenario ever actually occurs, but nonetheless we include the items - // count even if we're not sending item data for the same reasons as above. - descend.AgentData.Descendents = items.Count + folders.Count; + return newBlock; + } - int i = 0; - int count = 0; - foreach (InventoryFolderBase folder in folders) - { - descend.FolderData[i] = new InventoryDescendentsPacket.FolderDataBlock(); - descend.FolderData[i].FolderID = folder.ID; - descend.FolderData[i].Name = Util.StringToBytes256(folder.Name); - descend.FolderData[i].ParentID = folder.ParentID; - descend.FolderData[i].Type = (sbyte)folder.Type; + private InventoryDescendentsPacket.ItemDataBlock CreateItemDataBlock(InventoryItemBase item) + { + InventoryDescendentsPacket.ItemDataBlock newBlock = new InventoryDescendentsPacket.ItemDataBlock(); + newBlock.ItemID = item.ID; + newBlock.AssetID = item.AssetID; + newBlock.CreatorID = item.CreatorIdAsUuid; + newBlock.BaseMask = item.BasePermissions; + newBlock.Description = Util.StringToBytes256(item.Description); + newBlock.EveryoneMask = item.EveryOnePermissions; + newBlock.OwnerMask = item.CurrentPermissions; + newBlock.FolderID = item.Folder; + newBlock.InvType = (sbyte)item.InvType; + newBlock.Name = Util.StringToBytes256(item.Name); + newBlock.NextOwnerMask = item.NextPermissions; + newBlock.OwnerID = item.Owner; + newBlock.Type = (sbyte)item.AssetType; - i++; - count++; - itemsSent++; - if (i == MAX_ITEMS_PER_PACKET) - { - AddNullItemBlockToDescendentsPacket(ref descend); - OutPacket(descend, ThrottleOutPacketType.Asset); + newBlock.GroupID = item.GroupID; + newBlock.GroupOwned = item.GroupOwned; + newBlock.GroupMask = item.GroupPermissions; + newBlock.CreationDate = item.CreationDate; + newBlock.SalePrice = item.SalePrice; + newBlock.SaleType = item.SaleType; + newBlock.Flags = item.Flags; - if ((folders.Count - count) > 0) - { - descend = CreateInventoryDescendentsPacket(ownerID, folderID); - if ((folders.Count - count) < MAX_ITEMS_PER_PACKET) - { - descend.FolderData = - new InventoryDescendentsPacket.FolderDataBlock[folders.Count - count]; - } - else - { - descend.FolderData = - new InventoryDescendentsPacket.FolderDataBlock[MAX_ITEMS_PER_PACKET]; - } - descend.AgentData.Descendents = items.Count + folders.Count; - i = 0; - } - } - } + newBlock.CRC = + Helpers.InventoryCRC(newBlock.CreationDate, newBlock.SaleType, + newBlock.InvType, newBlock.Type, + newBlock.AssetID, newBlock.GroupID, + newBlock.SalePrice, + newBlock.OwnerID, newBlock.CreatorID, + newBlock.ItemID, newBlock.FolderID, + newBlock.EveryoneMask, + newBlock.Flags, newBlock.OwnerMask, + newBlock.GroupMask, newBlock.NextOwnerMask); - if (0 < i && i < MAX_ITEMS_PER_PACKET) - { - AddNullItemBlockToDescendentsPacket(ref descend); - OutPacket(descend, ThrottleOutPacketType.Asset); - } - } - - if (itemsSent == 0) - { - // no items found. - InventoryDescendentsPacket descend = CreateInventoryDescendentsPacket(ownerID, folderID); - descend.AgentData.Descendents = 0; - AddNullItemBlockToDescendentsPacket(ref descend); - AddNullFolderBlockToDecendentsPacket(ref descend); - OutPacket(descend, ThrottleOutPacketType.Asset); - } + return newBlock; } private void AddNullFolderBlockToDecendentsPacket(ref InventoryDescendentsPacket packet) @@ -1473,14 +1407,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP // No need to add CRC } - private InventoryDescendentsPacket CreateInventoryDescendentsPacket(UUID ownerID, UUID folderID) + private InventoryDescendentsPacket CreateInventoryDescendentsPacket(UUID ownerID, UUID folderID, int version, int descendents, int folders, int items) { InventoryDescendentsPacket descend = (InventoryDescendentsPacket)PacketPool.Instance.GetPacket(PacketType.InventoryDescendents); descend.Header.Zerocoded = true; descend.AgentData.AgentID = AgentId; descend.AgentData.OwnerID = ownerID; descend.AgentData.FolderID = folderID; - descend.AgentData.Version = 1; + descend.AgentData.Version = version; + descend.AgentData.Descendents = descendents; + + if (folders > 0) + descend.FolderData = new InventoryDescendentsPacket.FolderDataBlock[folders]; + else + AddNullFolderBlockToDecendentsPacket(ref descend); + + if (items > 0) + descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items]; + else + AddNullItemBlockToDescendentsPacket(ref descend); return descend; } @@ -3251,12 +3196,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (!IsActive) return; // We don't need to update inactive clients. CoarseLocationUpdatePacket loc = (CoarseLocationUpdatePacket)PacketPool.Instance.GetPacket(PacketType.CoarseLocationUpdate); - // TODO: don't create new blocks if recycling an old packet - int total = CoarseLocations.Count; - CoarseLocationUpdatePacket.IndexBlock ib = - new CoarseLocationUpdatePacket.IndexBlock(); + loc.Header.Reliable = false; + + // Each packet can only hold around 62 avatar positions and the client clears the mini-map each time + // a CoarseLocationUpdate packet is received. Oh well. + int total = Math.Min(CoarseLocations.Count, 60); + + CoarseLocationUpdatePacket.IndexBlock ib = new CoarseLocationUpdatePacket.IndexBlock(); + loc.Location = new CoarseLocationUpdatePacket.LocationBlock[total]; loc.AgentData = new CoarseLocationUpdatePacket.AgentDataBlock[total]; + int selfindex = -1; for (int i = 0; i < total; i++) { @@ -3266,18 +3216,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP lb.X = (byte)CoarseLocations[i].X; lb.Y = (byte)CoarseLocations[i].Y; - lb.Z = CoarseLocations[i].Z > 1024 ? (byte)0 : (byte)(CoarseLocations[i].Z * 0.25); + lb.Z = CoarseLocations[i].Z > 1024 ? (byte)0 : (byte)(CoarseLocations[i].Z * 0.25f); loc.Location[i] = lb; loc.AgentData[i] = new CoarseLocationUpdatePacket.AgentDataBlock(); loc.AgentData[i].AgentID = users[i]; if (users[i] == AgentId) selfindex = i; } + ib.You = (short)selfindex; ib.Prey = -1; loc.Index = ib; - loc.Header.Reliable = false; - loc.Header.Zerocoded = true; OutPacket(loc, ThrottleOutPacketType.Task); } @@ -4088,11 +4037,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendPrimitiveTerseData data) { - return CreateImprovedTerseBlock(false, data.LocalID, data.State, Vector4.Zero, data.Position, data.Velocity, + return CreateImprovedTerseBlock(false, data.LocalID, data.AttachPoint, Vector4.Zero, data.Position, data.Velocity, data.Acceleration, data.Rotation, data.AngularVelocity, data.TextureEntry); } - protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(bool avatar, uint localID, byte state, + protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(bool avatar, uint localID, int attachPoint, Vector4 collisionPlane, Vector3 position, Vector3 velocity, Vector3 acceleration, Quaternion rotation, Vector3 angularVelocity, byte[] textureEntry) { @@ -4104,7 +4053,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP pos += 4; // Avatar/CollisionPlane - data[pos++] = state; + data[pos++] = (byte)((attachPoint % 16) * 16 + (attachPoint / 16)); ; if (avatar) { data[pos++] = 1; @@ -4960,9 +4909,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Throttling category for the packet protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType) { + #region BinaryStats + LLUDPServer.LogPacketHeader(false, m_circuitCode, 0, packet.Type, (ushort)packet.Length); + #endregion BinaryStats + m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, true); } + /// + /// This is the starting point for sending a simulator packet out to the client + /// + /// Packet to send + /// Throttling category for the packet + /// True to automatically split oversized + /// packets (the default), or false to disable splitting if the calling code + /// handles splitting manually + protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting) + { + m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting); + } + public bool AddMoney(int debit) { if (m_moneyBalance + debit >= 0) @@ -9762,7 +9728,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP Utils.BytesToString(avatarInterestUpdate.PropertiesData.SkillsText), Utils.BytesToString(avatarInterestUpdate.PropertiesData.LanguagesText)); break; - + + case PacketType.GrantUserRights: + GrantUserRightsPacket GrantUserRights = + (GrantUserRightsPacket)Pack; + #region Packet Session and User Check + if (m_checkPackets) + { + if (GrantUserRights.AgentData.SessionID != SessionId || + GrantUserRights.AgentData.AgentID != AgentId) + break; + } + #endregion + GrantUserFriendRights GrantUserRightsHandler = OnGrantUserRights; + if (GrantUserRightsHandler != null) + GrantUserRightsHandler(this, + GrantUserRights.AgentData.AgentID, + GrantUserRights.Rights[0].AgentRelated, + GrantUserRights.Rights[0].RelatedRights); + break; + case PacketType.PlacesQuery: PlacesQueryPacket placesQueryPacket = (PlacesQueryPacket)Pack; diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs index 697bbe6325..adf171e465 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs @@ -197,11 +197,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP private void Initialise(UUID fileID, string fileName) { - m_asset = new AssetBase(); - m_asset.FullID = fileID; - m_asset.Type = type; + m_asset = new AssetBase(fileID, fileName, type); m_asset.Data = new byte[0]; - m_asset.Name = fileName; m_asset.Description = "empty"; m_asset.Local = true; m_asset.Temporary = true; diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 93946ae50b..c773c05905 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Net; using System.Net.Sockets; using System.Reflection; @@ -204,6 +205,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP TextureSendLimit = 20; } + #region BinaryStats + config = configSource.Configs["Statistics.Binary"]; + m_shouldCollectStats = false; + if (config != null) + { + if (config.Contains("enabled") && config.GetBoolean("enabled")) + { + if (config.Contains("collect_packet_headers")) + m_shouldCollectStats = config.GetBoolean("collect_packet_headers"); + if (config.Contains("packet_headers_period_seconds")) + { + binStatsMaxFilesize = TimeSpan.FromSeconds(config.GetInt("region_stats_period_seconds")); + } + if (config.Contains("stats_dir")) + { + binStatsDir = config.GetString("stats_dir"); + } + } + else + { + m_shouldCollectStats = false; + } + } + #endregion BinaryStats + m_throttle = new TokenBucket(null, sceneThrottleBps, sceneThrottleBps); m_throttleRates = new ThrottleRates(configSource); } @@ -359,9 +385,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { - m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" + - type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length + ". Dropping packet"); - return; + bufferSize = dataLength; + buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize); + + // m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" + + // type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length + ". Dropping packet"); + Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); } } @@ -676,6 +705,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion Incoming Packet Accounting + #region BinaryStats + LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length); + #endregion BinaryStats + #region Ping Check Handling if (packet.Type == PacketType.StartPingCheck) @@ -697,6 +730,87 @@ namespace OpenSim.Region.ClientStack.LindenUDP packetInbox.Enqueue(new IncomingPacket(udpClient, packet)); } + #region BinaryStats + + public class PacketLogger + { + public DateTime StartTime; + public string Path = null; + public System.IO.BinaryWriter Log = null; + } + + public static PacketLogger PacketLog; + + protected static bool m_shouldCollectStats = false; + // Number of seconds to log for + static TimeSpan binStatsMaxFilesize = TimeSpan.FromSeconds(300); + static object binStatsLogLock = new object(); + static string binStatsDir = ""; + + public static void LogPacketHeader(bool incoming, uint circuit, byte flags, PacketType packetType, ushort size) + { + if (!m_shouldCollectStats) return; + + // Binary logging format is TTTTTTTTCCCCFPPPSS, T=Time, C=Circuit, F=Flags, P=PacketType, S=size + + // Put the incoming bit into the least significant bit of the flags byte + if (incoming) + flags |= 0x01; + else + flags &= 0xFE; + + // Put the flags byte into the most significant bits of the type integer + uint type = (uint)packetType; + type |= (uint)flags << 24; + + // m_log.Debug("1 LogPacketHeader(): Outside lock"); + lock (binStatsLogLock) + { + DateTime now = DateTime.Now; + + // m_log.Debug("2 LogPacketHeader(): Inside lock. now is " + now.Ticks); + try + { + if (PacketLog == null || (now > PacketLog.StartTime + binStatsMaxFilesize)) + { + if (PacketLog != null && PacketLog.Log != null) + { + PacketLog.Log.Close(); + } + + // First log file or time has expired, start writing to a new log file + PacketLog = new PacketLogger(); + PacketLog.StartTime = now; + PacketLog.Path = (binStatsDir.Length > 0 ? binStatsDir + System.IO.Path.DirectorySeparatorChar.ToString() : "") + + String.Format("packets-{0}.log", now.ToString("yyyyMMddHHmmss")); + PacketLog.Log = new BinaryWriter(File.Open(PacketLog.Path, FileMode.Append, FileAccess.Write)); + } + + // Serialize the data + byte[] output = new byte[18]; + Buffer.BlockCopy(BitConverter.GetBytes(now.Ticks), 0, output, 0, 8); + Buffer.BlockCopy(BitConverter.GetBytes(circuit), 0, output, 8, 4); + Buffer.BlockCopy(BitConverter.GetBytes(type), 0, output, 12, 4); + Buffer.BlockCopy(BitConverter.GetBytes(size), 0, output, 16, 2); + + // Write the serialized data to disk + if (PacketLog != null && PacketLog.Log != null) + PacketLog.Log.Write(output); + } + catch (Exception ex) + { + m_log.Error("Packet statistics gathering failed: " + ex.Message, ex); + if (PacketLog.Log != null) + { + PacketLog.Log.Close(); + } + PacketLog = null; + } + } + } + + #endregion BinaryStats + private void HandleUseCircuitCode(object o) { object[] array = (object[])o; diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs index 552cc4a773..d2779ba302 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs @@ -270,8 +270,8 @@ namespace OpenMetaverse { try { - UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState; - int bytesSent = m_udpSocket.EndSendTo(result); +// UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState; + m_udpSocket.EndSendTo(result); } catch (SocketException) { } catch (ObjectDisposedException) { } diff --git a/OpenSim/Region/Communications/Hypergrid/HGUserServices.cs b/OpenSim/Region/Communications/Hypergrid/HGUserServices.cs index 49a2261577..09d8285a6f 100644 --- a/OpenSim/Region/Communications/Hypergrid/HGUserServices.cs +++ b/OpenSim/Region/Communications/Hypergrid/HGUserServices.cs @@ -204,6 +204,14 @@ namespace OpenSim.Region.Communications.Hypergrid return base.UpdateUserProfile(userProfile); } + public override bool AuthenticateUserByPassword(UUID userID, string password) + { + if (m_localUserServices != null) + return m_localUserServices.AuthenticateUserByPassword(userID, password); + else + return base.AuthenticateUserByPassword(userID, password); + } + #region IUserServices Friend Methods // NOTE: We're still not dealing with foreign user friends diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs index e192b8163e..f698ea13c7 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs @@ -112,11 +112,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction bool storeLocal, bool tempFile) { ourClient = remoteClient; - m_asset = new AssetBase(); - m_asset.FullID = assetID; - m_asset.Type = type; + m_asset = new AssetBase(assetID, "blank", type); m_asset.Data = data; - m_asset.Name = "blank"; m_asset.Description = "empty"; m_asset.Local = storeLocal; m_asset.Temporary = tempFile; diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs index 7456e8c04f..7ac8bed012 100644 --- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs +++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs @@ -144,8 +144,8 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender /// JPEG2000 data private void DoJ2KDecode(UUID assetID, byte[] j2kData) { - int DecodeTime = 0; - DecodeTime = Environment.TickCount; +// int DecodeTime = 0; +// DecodeTime = Environment.TickCount; OpenJPEG.J2KLayerInfo[] layers; if (!TryLoadCacheForAsset(assetID, out layers)) @@ -238,12 +238,11 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender if (m_cache != null) { - AssetBase layerDecodeAsset = new AssetBase(); - layerDecodeAsset.ID = "j2kCache_" + AssetId.ToString(); + string assetID = "j2kCache_" + AssetId.ToString(); + + AssetBase layerDecodeAsset = new AssetBase(assetID, assetID, (sbyte)AssetType.Notecard); layerDecodeAsset.Local = true; - layerDecodeAsset.Name = layerDecodeAsset.ID; layerDecodeAsset.Temporary = true; - layerDecodeAsset.Type = (sbyte)AssetType.Notecard; #region Serialize Layer Data diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index c6af8067a4..adcf6bd4f0 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -831,7 +831,7 @@ namespace Flotsam.RegionModules.AssetCache public string Store(AssetBase asset) { - if ((asset.FullID == null) || (asset.FullID == UUID.Zero)) + if (asset.FullID == UUID.Zero) { asset.FullID = UUID.Random(); } diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index fc7d63aa06..bb4e0322cb 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -395,6 +395,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // if it leaves, we want to know, too client.OnLogout += OnLogout; + client.OnGrantUserRights += GrantUserFriendRights; + } private void ClientClosed(UUID AgentId, Scene scene) @@ -1108,7 +1110,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // tell everyone that we are offline SendPresenceState(remoteClient, fl, false); } - } + private void GrantUserFriendRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) + { + ((Scene)remoteClient.Scene).CommsManager.UpdateUserFriendPerms(requester, target, (uint)rights); + } + public List GetUserFriends(UUID agentID) + { + List fl; + lock (m_friendLists) + { + fl = (List)m_friendLists.Get(agentID.ToString(), + m_initialScene.GetFriendList); + } + + return fl; + } + } #endregion } diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index f761bf0c53..aafcfa2eab 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs @@ -99,36 +99,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver int failedAssetRestores = 0; int successfulItemRestores = 0; List nodesLoaded = new List(); - - /* - if (!m_userInfo.HasReceivedInventory) - { - // If the region server has access to the user admin service (by which users are created), - // then we'll assume that it's okay to fiddle with the user's inventory even if they are not on the - // server. - // - // FIXME: FetchInventory should probably be assumed to by async anyway, since even standalones might - // use a remote inventory service, though this is vanishingly rare at the moment. - if (null == m_scene.CommsManager.UserAdminService) - { - m_log.ErrorFormat( - "[INVENTORY ARCHIVER]: Have not yet received inventory info for user {0} {1}", - m_userInfo.UserProfile.Name, m_userInfo.UserProfile.ID); - - return nodesLoaded; - } - else - { - m_userInfo.FetchInventory(); - for (int i = 0 ; i < 50 ; i++) - { - if (m_userInfo.HasReceivedInventory == true) - break; - Thread.Sleep(200); - } - } - } - */ //InventoryFolderImpl rootDestinationFolder = m_userInfo.RootFolder.FindFolderByPath(m_invPath); InventoryFolderBase rootDestinationFolder @@ -159,9 +129,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver successfulAssetRestores++; else failedAssetRestores++; + + if ((successfulAssetRestores) % 50 == 0) + m_log.DebugFormat( + "[INVENTORY ARCHIVER]: Loaded {0} assets...", + successfulAssetRestores); } else if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH)) - { + { InventoryFolderBase foundFolder = ReplicateArchivePathToUserInventory( filePath, TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType, @@ -169,38 +144,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType) { - InventoryItemBase item = UserInventoryItemSerializer.Deserialize(data); - - // Don't use the item ID that's in the file - item.ID = UUID.Random(); + InventoryItemBase item = LoadItem(data, foundFolder); - UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.CommsManager); - if (UUID.Zero != ospResolvedId) - item.CreatorIdAsUuid = ospResolvedId; - else - item.CreatorIdAsUuid = m_userInfo.UserProfile.ID; - - item.Owner = m_userInfo.UserProfile.ID; - - // Reset folder ID to the one in which we want to load it - item.Folder = foundFolder.ID; - - //m_userInfo.AddItem(item); - m_scene.InventoryService.AddItem(item); - successfulItemRestores++; - - // If we're loading an item directly into the given destination folder then we need to record - // it separately from any loaded root folders - if (rootDestinationFolder == foundFolder) - nodesLoaded.Add(item); + if (item != null) + { + successfulItemRestores++; + + // If we're loading an item directly into the given destination folder then we need to record + // it separately from any loaded root folders + if (rootDestinationFolder == foundFolder) + nodesLoaded.Add(item); + } } } } archive.Close(); - m_log.DebugFormat("[INVENTORY ARCHIVER]: Restored {0} assets", successfulAssetRestores); - m_log.InfoFormat("[INVENTORY ARCHIVER]: Restored {0} items", successfulItemRestores); + m_log.DebugFormat( + "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures", + successfulAssetRestores, failedAssetRestores); + m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores); return nodesLoaded; } @@ -234,8 +198,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver string originalArchivePath = archivePath; - m_log.DebugFormat( - "[INVENTORY ARCHIVER]: Loading to folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID); +// m_log.DebugFormat( +// "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID); InventoryFolderBase destFolder = null; @@ -246,8 +210,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { if (foldersCreated.ContainsKey(archivePath)) { - m_log.DebugFormat( - "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath); +// m_log.DebugFormat( +// "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath); destFolder = foldersCreated[archivePath]; } else @@ -289,6 +253,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR); string newFolderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex); + + newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName); UUID newFolderId = UUID.Random(); // Asset type has to be Unknown here rather than Folder, otherwise the created folder can't be @@ -360,6 +326,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver */ } + /// + /// Load an item from the archive + /// + /// The archive path for the item + /// The raw item data + /// The root destination folder for loaded items + /// All the inventory nodes (items and folders) loaded so far + protected InventoryItemBase LoadItem(byte[] data, InventoryFolderBase loadFolder) + { + InventoryItemBase item = UserInventoryItemSerializer.Deserialize(data); + + // Don't use the item ID that's in the file + item.ID = UUID.Random(); + + UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.CommsManager); + if (UUID.Zero != ospResolvedId) + item.CreatorIdAsUuid = ospResolvedId; + else + item.CreatorIdAsUuid = m_userInfo.UserProfile.ID; + + item.Owner = m_userInfo.UserProfile.ID; + + // Reset folder ID to the one in which we want to load it + item.Folder = loadFolder.ID; + + //m_userInfo.AddItem(item); + m_scene.InventoryService.AddItem(item); + + return item; + } + /// /// Load an asset /// @@ -389,11 +386,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; + if (assetType == (sbyte)AssetType.Unknown) + m_log.WarnFormat("[INVENTORY ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, uuid); + //m_log.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); - AssetBase asset = new AssetBase(new UUID(uuid), "RandomName"); - - asset.Type = assetType; + AssetBase asset = new AssetBase(new UUID(uuid), "RandomName", assetType); asset.Data = data; m_scene.AssetService.Store(asset); diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs index a822d104cc..247cee41c8 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs @@ -27,6 +27,9 @@ using System; using System.Collections.Generic; +using System.Reflection; +using System.Text; +using log4net; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Services.Interfaces; @@ -38,7 +41,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// public static class InventoryArchiveUtils { - public static readonly string PATH_DELIMITER = "/"; +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + // Character used for escaping the path delimter ("\/") and itself ("\\") in human escaped strings + public static readonly char ESCAPE_CHARACTER = '\\'; + + // The character used to separate inventory path components (different folders and items) + public static readonly char PATH_DELIMITER = '/'; /// /// Find a folder given a PATH_DELIMITER delimited path starting from a user's root folder @@ -103,10 +112,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver path = path.Trim(); - if (path == PATH_DELIMITER) + if (path == PATH_DELIMITER.ToString()) return startFolder; - string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); + string[] components = SplitEscapedPath(path); + components[0] = UnescapePath(components[0]); + + //string[] components = path.Split(new string[] { PATH_DELIMITER.ToString() }, 2, StringSplitOptions.None); + InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); foreach (InventoryFolderBase folder in contents.Folders) @@ -181,10 +194,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver public static InventoryItemBase FindItemByPath( IInventoryService inventoryService, InventoryFolderBase startFolder, string path) { - string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); + string[] components = SplitEscapedPath(path); + components[0] = UnescapePath(components[0]); + + //string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); if (components.Length == 1) { +// m_log.DebugFormat("FOUND SINGLE COMPONENT [{0}]", components[0]); + List items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID); foreach (InventoryItemBase item in items) { @@ -194,6 +212,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver } else { +// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]); + InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); foreach (InventoryFolderBase folder in contents.Folders) @@ -206,5 +226,97 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // We didn't find an item or intermediate folder with the given name return null; } + + /// + /// Split a human escaped path into two components if it contains an unescaped path delimiter, or one component + /// if no delimiter is present + /// + /// + /// + /// The split path. We leave the components in their originally unescaped state (though we remove the delimiter + /// which originally split them if applicable). + /// + public static string[] SplitEscapedPath(string path) + { +// m_log.DebugFormat("SPLITTING PATH {0}", path); + + bool singleEscapeChar = false; + + for (int i = 0; i < path.Length; i++) + { + if (path[i] == ESCAPE_CHARACTER && !singleEscapeChar) + { + singleEscapeChar = true; + } + else + { + if (PATH_DELIMITER == path[i] && !singleEscapeChar) + return new string[2] { path.Remove(i), path.Substring(i + 1) }; + else + singleEscapeChar = false; + } + } + + // We didn't find a delimiter + return new string[1] { path }; + } + + /// + /// Unescapes a human escaped path. This means that "\\" goes to "\", and "\/" goes to "/" + /// + /// + /// + public static string UnescapePath(string path) + { +// m_log.DebugFormat("ESCAPING PATH {0}", path); + + StringBuilder sb = new StringBuilder(); + + bool singleEscapeChar = false; + for (int i = 0; i < path.Length; i++) + { + if (path[i] == ESCAPE_CHARACTER && !singleEscapeChar) + singleEscapeChar = true; + else + singleEscapeChar = false; + + if (singleEscapeChar) + { + if (PATH_DELIMITER == path[i]) + sb.Append(PATH_DELIMITER); + } + else + { + sb.Append(path[i]); + } + } + +// m_log.DebugFormat("ESCAPED PATH TO {0}", sb); + + return sb.ToString(); + } + + /// + /// Escape an archive path. + /// + /// This has to be done differently from human paths because we can't leave in any "/" characters (due to + /// problems if the archive is built from or extracted to a filesystem + /// + /// + public static string EscapeArchivePath(string path) + { + // Only encode ampersands (for escaping anything) and / (since this is used as general dir separator). + return path.Replace("&", "&").Replace("/", "/"); + } + + /// + /// Unescape an archive path. + /// + /// + /// + public static string UnescapeArchivePath(string path) + { + return path.Replace("/", "/").Replace("&", "&"); + } } } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index 499c552a4a..bbb49f6108 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs @@ -217,37 +217,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver InventoryItemBase inventoryItem = null; InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.UserProfile.ID); - // XXX: Very temporarily, drop and refetch inventory to make sure we have any newly created items in cache - // This will disappear very soon once we stop using the old cached inventory. - /* - m_userInfo.DropInventory(); - m_userInfo.FetchInventory(); - */ - - /* - if (!m_userInfo.HasReceivedInventory) - { - // If the region server has access to the user admin service (by which users are created), - // then we'll assume that it's okay to fiddle with the user's inventory even if they are not on the - // server. - // - // FIXME: FetchInventory should probably be assumed to by async anyway, since even standalones might - // use a remote inventory service, though this is vanishingly rare at the moment. - if (null == m_scene.CommsManager.UserAdminService) - { - m_log.ErrorFormat( - "[INVENTORY ARCHIVER]: Have not yet received inventory info for user {0} {1}", - m_userInfo.UserProfile.Name, m_userInfo.UserProfile.ID); - - return; - } - else - { - m_userInfo.FetchInventory(); - } - } - */ - bool foundStar = false; // Eliminate double slashes and any leading / on the path. @@ -294,34 +263,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver m_archiveWriter = new TarArchiveWriter(m_saveStream); - if (null == inventoryFolder) - { - if (null == inventoryItem) - { - // We couldn't find the path indicated - m_saveStream.Close(); - m_module.TriggerInventoryArchiveSaved( - m_id, false, m_userInfo, m_invPath, m_saveStream, - new Exception(string.Format("Could not find inventory entry at path {0}", m_invPath))); - return; - } - else - { - m_log.DebugFormat( - "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}", - inventoryItem.Name, inventoryItem.ID, m_invPath); - - SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH); - } - } - else + if (inventoryFolder != null) { m_log.DebugFormat( "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}", inventoryFolder.Name, inventoryFolder.ID, m_invPath); //recurse through all dirs getting dirs and files - SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !foundStar); + SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !foundStar); + } + else if (inventoryItem != null) + { + m_log.DebugFormat( + "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}", + inventoryItem.Name, inventoryItem.ID, m_invPath); + + SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH); + } + else + { + // We couldn't find the path indicated + m_saveStream.Close(); + string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath); + m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", errorMessage); + m_module.TriggerInventoryArchiveSaved( + m_id, false, m_userInfo, m_invPath, m_saveStream, + new Exception(errorMessage)); + return; } // Don't put all this profile information into the archive right now. @@ -396,7 +364,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { return string.Format( "{0}{1}{2}/", - name, + InventoryArchiveUtils.EscapeArchivePath(name), ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, id); } @@ -411,7 +379,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { return string.Format( "{0}{1}{2}.xml", - name, + InventoryArchiveUtils.EscapeArchivePath(name), ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, id); } diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index b0fdcd6f33..f8a010c42b 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -29,7 +29,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Reflection; -using System.Text; using System.Threading; using NUnit.Framework; using NUnit.Framework.SyntaxHelpers; @@ -122,9 +121,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests } UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); - AssetBase asset1 = new AssetBase(); - asset1.FullID = asset1Id; - asset1.Data = Encoding.ASCII.GetBytes(SceneObjectSerializer.ToXml2Format(object1)); + AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); scene.AssetService.Store(asset1); // Create item @@ -136,7 +133,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests InventoryFolderBase objsFolder = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects"); item1.Folder = objsFolder.ID; - scene.AddInventoryItem(userId, item1); + scene.AddInventoryItem(userId, item1); MemoryStream archiveWriteStream = new MemoryStream(); archiverModule.OnInventoryArchiveSaved += SaveCompleted; @@ -218,14 +215,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests string userItemCreatorLastName = "Lucan"; UUID userItemCreatorUuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); - string itemName = "b.lsl"; - string archiveItemName = InventoryArchiveWriteRequest.CreateArchiveItemName(itemName, UUID.Random()); + string item1Name = "b.lsl"; + string archiveItemName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1Name, UUID.Random()); MemoryStream archiveWriteStream = new MemoryStream(); TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); InventoryItemBase item1 = new InventoryItemBase(); - item1.Name = itemName; + item1.Name = item1Name; item1.AssetID = UUID.Random(); item1.GroupID = UUID.Random(); item1.CreatorId = OspResolver.MakeOspa(userItemCreatorFirstName, userItemCreatorLastName); @@ -259,7 +256,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests = scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName); InventoryItemBase foundItem1 - = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, itemName); + = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, item1Name); Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); Assert.That( @@ -277,7 +274,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests archiverModule.DearchiveInventory(userFirstName, userLastName, "xA", "meowfood", archiveReadStream); InventoryItemBase foundItem2 - = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, "xA/" + itemName); + = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, "xA/" + item1Name); Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2"); // Now try loading to a more deeply nested folder @@ -286,10 +283,99 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests archiverModule.DearchiveInventory(userFirstName, userLastName, "xB/xC", "meowfood", archiveReadStream); InventoryItemBase foundItem3 - = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, "xB/xC/" + itemName); + = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, "xB/xC/" + item1Name); Assert.That(foundItem3, Is.Not.Null, "Didn't find loaded item 3"); } + [Test] + public void TestIarV0_1WithEscapedChars() + { + TestHelper.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + string itemName = "You & you are a mean/man/"; + string humanEscapedItemName = @"You & you are a mean\/man\/"; + string userPassword = "meowfood"; + + InventoryArchiverModule archiverModule = new InventoryArchiverModule(true); + + Scene scene = SceneSetupHelpers.SetupScene("Inventory"); + SceneSetupHelpers.SetupSceneModules(scene, archiverModule); + CommunicationsManager cm = scene.CommsManager; + + // Create user + string userFirstName = "Jock"; + string userLastName = "Stirrup"; + UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); + + lock (this) + { + UserProfileTestUtils.CreateUserWithInventory( + cm, userFirstName, userLastName, userPassword, userId, InventoryReceived); + Monitor.Wait(this, 60000); + } + + // Create asset + SceneObjectGroup object1; + SceneObjectPart part1; + { + string partName = "part name"; + UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); + PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere(); + Vector3 groupPosition = new Vector3(10, 20, 30); + Quaternion rotationOffset = new Quaternion(20, 30, 40, 50); + Vector3 offsetPosition = new Vector3(5, 10, 15); + + part1 + = new SceneObjectPart( + ownerId, shape, groupPosition, rotationOffset, offsetPosition); + part1.Name = partName; + + object1 = new SceneObjectGroup(part1); + scene.AddNewSceneObject(object1, false); + } + + UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); + AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); + scene.AssetService.Store(asset1); + + // Create item + UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080"); + InventoryItemBase item1 = new InventoryItemBase(); + item1.Name = itemName; + item1.AssetID = asset1.FullID; + item1.ID = item1Id; + InventoryFolderBase objsFolder + = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects"); + item1.Folder = objsFolder.ID; + scene.AddInventoryItem(userId, item1); + + MemoryStream archiveWriteStream = new MemoryStream(); + archiverModule.OnInventoryArchiveSaved += SaveCompleted; + + mre.Reset(); + archiverModule.ArchiveInventory( + Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream); + mre.WaitOne(60000, false); + + // LOAD ITEM + MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); + + archiverModule.DearchiveInventory(userFirstName, userLastName, "Scripts", userPassword, archiveReadStream); + + InventoryItemBase foundItem1 + = InventoryArchiveUtils.FindItemByPath( + scene.InventoryService, userId, "Scripts/Objects/" + humanEscapedItemName); + + Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); +// Assert.That( +// foundItem1.CreatorId, Is.EqualTo(userUuid), +// "Loaded item non-uuid creator doesn't match that of the loading user"); + Assert.That( + foundItem1.Name, Is.EqualTo(itemName), + "Loaded item name doesn't match saved name"); + } + /// /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where /// embedded creators do not exist in the system @@ -302,7 +388,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests { TestHelper.InMethod(); - log4net.Config.XmlConfigurator.Configure(); + //log4net.Config.XmlConfigurator.Configure(); string userFirstName = "Charlie"; string userLastName = "Chan"; @@ -370,7 +456,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests { TestHelper.InMethod(); - log4net.Config.XmlConfigurator.Configure(); + //log4net.Config.XmlConfigurator.Configure(); string userFirstName = "Dennis"; string userLastName = "Menace"; diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs index 769af8df6d..11aca99dcc 100644 --- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs @@ -1,7 +1,10 @@ -using System.Collections.Generic; +using System.Collections; +using System.Collections.Generic; using System.Reflection; using log4net; using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; using OpenSim.Region.CoreModules.Framework.Monitoring.Alerts; using OpenSim.Region.CoreModules.Framework.Monitoring.Monitors; using OpenSim.Region.Framework.Interfaces; @@ -43,6 +46,56 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring "monitor report", "Returns a variety of statistics about the current region and/or simulator", DebugMonitors); + + MainServer.Instance.AddHTTPHandler("/monitorstats/" + m_scene.RegionInfo.RegionID + "/", StatsPage); + } + + public Hashtable StatsPage(Hashtable request) + { + // If request was for a specific monitor + // eg url/?monitor=Monitor.Name + if (request.ContainsKey("monitor")) + { + string monID = (string) request["monitor"]; + + foreach (IMonitor monitor in m_monitors) + { + if (monitor.ToString() == monID) + { + Hashtable ereply3 = new Hashtable(); + + ereply3["int_response_code"] = 404; // 200 OK + ereply3["str_response_string"] = monitor.GetValue().ToString(); + ereply3["content_type"] = "text/plain"; + + return ereply3; + } + } + + // No monitor with that name + Hashtable ereply2 = new Hashtable(); + + ereply2["int_response_code"] = 404; // 200 OK + ereply2["str_response_string"] = "No such monitor"; + ereply2["content_type"] = "text/plain"; + + return ereply2; + } + + string xml = ""; + foreach (IMonitor monitor in m_monitors) + { + xml += "<" + monitor.ToString() + ">" + monitor.GetValue() + ""; + } + xml += ""; + + Hashtable ereply = new Hashtable(); + + ereply["int_response_code"] = 200; // 200 OK + ereply["str_response_string"] = xml; + ereply["content_type"] = "text/xml"; + + return ereply; } public void PostInitialise() diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml index 8f8271845d..975707258e 100644 --- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml +++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml @@ -13,7 +13,6 @@ - diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 9a6c49aae0..43761fce62 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -311,11 +311,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture } // Create a new asset for user - AssetBase asset = new AssetBase(); - asset.FullID = UUID.Random(); + AssetBase asset = new AssetBase(UUID.Random(), "DynamicImage" + Util.RandomClass.Next(1, 10000), (sbyte)AssetType.Texture); asset.Data = assetData; - asset.Name = "DynamicImage" + Util.RandomClass.Next(1, 10000); - asset.Type = 0; asset.Description = String.Format("URL image : {0}", Url); asset.Local = false; asset.Temporary = ((Disp & DISP_TEMP) != 0); diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs index 97899a7af4..27b64bffc0 100644 --- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs @@ -689,7 +689,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC } if (respParms.Contains("IntValue")) { - Idata = Convert.ToInt32((string) respParms["IntValue"]); + Idata = Convert.ToInt32(respParms["IntValue"]); } if (respParms.Contains("faultString")) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs index 92db15bc38..b12d778f87 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs @@ -118,7 +118,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Grid m_log.Info("[HypergridService]: Starting..."); - Object[] args = new Object[] { m_Config, MainServer.Instance }; +// Object[] args = new Object[] { m_Config, MainServer.Instance }; m_HypergridHandler = new HypergridServiceInConnector(m_Config, MainServer.Instance, scene.RequestModuleInterface()); //ServerUtils.LoadPlugin("OpenSim.Server.Handlers.dll:HypergridServiceInConnector", args); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs index 40ac647d08..f2d8579c83 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs @@ -336,7 +336,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public List GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax) { int snapXmin = (int)(xmin / Constants.RegionSize) * (int)Constants.RegionSize; - int snapXmax = (int)(xmax / Constants.RegionSize) * (int)Constants.RegionSize; +// int snapXmax = (int)(xmax / Constants.RegionSize) * (int)Constants.RegionSize; int snapYmin = (int)(ymin / Constants.RegionSize) * (int)Constants.RegionSize; int snapYmax = (int)(ymax / Constants.RegionSize) * (int)Constants.RegionSize; @@ -604,13 +604,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid { CachedUserInfo uinfo = m_aScene.CommsManager.UserProfileCacheService.GetUserDetails(agentData.AgentID); + if (uinfo == null) + return false; + if ((IsLocalUser(uinfo) && (GetHyperlinkRegion(regInfo.RegionHandle) != null)) || (!IsLocalUser(uinfo) && !IsGoingHome(uinfo, regInfo))) { m_log.Info("[HGrid]: Local user is going to foreign region or foreign user is going elsewhere"); // Set the position of the region on the remote grid - ulong realHandle = FindRegionHandle(regInfo.RegionHandle); +// ulong realHandle = FindRegionHandle(regInfo.RegionHandle); uint x = 0, y = 0; Utils.LongToUInts(regInfo.RegionHandle, out x, out y); GridRegion clonedRegion = new GridRegion(regInfo); @@ -737,6 +740,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid // Is the user going back to the home region or the home grid? protected bool IsGoingHome(CachedUserInfo uinfo, GridRegion rinfo) { + if (uinfo == null) + return false; + if (uinfo.UserProfile == null) return false; diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index c261943a3c..70a225e7c1 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -332,10 +332,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver { sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; + if (assetType == (sbyte)AssetType.Unknown) + m_log.WarnFormat("[ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, uuid); + //m_log.DebugFormat("[ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); - AssetBase asset = new AssetBase(new UUID(uuid), String.Empty); - asset.Type = assetType; + AssetBase asset = new AssetBase(new UUID(uuid), String.Empty, assetType); asset.Data = data; // We're relying on the asset service to do the sensible thing and not store the asset if it already diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs index 5208e7abbf..2d2c570447 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs @@ -158,9 +158,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver m_log.DebugFormat("[ARCHIVER]: Importing asset {0}", filename); - AssetBase asset = new AssetBase(new UUID(filename), metadata.Name); + AssetBase asset = new AssetBase(new UUID(filename), metadata.Name, metadata.AssetType); asset.Description = metadata.Description; - asset.Type = metadata.AssetType; asset.Data = data; m_cache.Store(asset); diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs b/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs index ddac51596a..2ff635b1ff 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs @@ -52,16 +52,11 @@ namespace OpenSim.Region.CoreModules.World.Estate public EstateTerrainXferHandler(IClientAPI pRemoteClient, string pClientFilename) { - - m_asset = new AssetBase(); - m_asset.FullID = UUID.Zero; - m_asset.Type = type; + m_asset = new AssetBase(UUID.Zero, pClientFilename, type); m_asset.Data = new byte[0]; - m_asset.Name = pClientFilename; m_asset.Description = "empty"; m_asset.Local = true; m_asset.Temporary = true; - } public ulong XferID diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 93a949a249..968f46a50f 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -1059,9 +1059,11 @@ namespace OpenSim.Region.CoreModules.World.Land if (m_scene.Permissions.IsGod(remote_client.AgentId)) { land.LandData.OwnerID = ownerID; + land.LandData.GroupID = UUID.Zero; + land.LandData.IsGroupOwned = false; m_scene.ForEachClient(SendParcelOverlay); - land.SendLandUpdateToClient(remote_client); + land.SendLandUpdateToClient(true, remote_client); } } } @@ -1082,8 +1084,10 @@ namespace OpenSim.Region.CoreModules.World.Land land.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; else land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; + land.LandData.GroupID = UUID.Zero; + land.LandData.IsGroupOwned = false; m_scene.ForEachClient(SendParcelOverlay); - land.SendLandUpdateToClient(remote_client); + land.SendLandUpdateToClient(true, remote_client); } } } @@ -1105,9 +1109,10 @@ namespace OpenSim.Region.CoreModules.World.Land else land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; land.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); + land.LandData.GroupID = UUID.Zero; land.LandData.IsGroupOwned = false; m_scene.ForEachClient(SendParcelOverlay); - land.SendLandUpdateToClient(remote_client); + land.SendLandUpdateToClient(true, remote_client); } } } diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index bfe85f1e04..0bd225ebe4 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -49,6 +49,8 @@ namespace OpenSim.Region.CoreModules.World.Land #pragma warning restore 0429 private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; + private int m_lastSeqId = 0; + protected LandData m_landData = new LandData(); protected Scene m_scene; protected List primsOverMe = new List(); @@ -81,6 +83,10 @@ namespace OpenSim.Region.CoreModules.World.Land { m_scene = scene; LandData.OwnerID = owner_id; + if (is_group_owned) + LandData.GroupID = owner_id; + else + LandData.GroupID = UUID.Zero; LandData.IsGroupOwned = is_group_owned; } @@ -172,7 +178,19 @@ namespace OpenSim.Region.CoreModules.World.Land // regionFlags |= (uint)RegionFlags.AllowLandmark; // if (landData.OwnerID == remote_client.AgentId) // regionFlags |= (uint)RegionFlags.AllowSetHome; - remote_client.SendLandProperties(sequence_id, + + int seq_id; + if (snap_selection && (sequence_id == 0)) + { + seq_id = m_lastSeqId; + } + else + { + seq_id = sequence_id; + m_lastSeqId = seq_id; + } + + remote_client.SendLandProperties(seq_id, snap_selection, request_result, LandData, (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, GetParcelMaxPrimCount(this), @@ -184,6 +202,7 @@ namespace OpenSim.Region.CoreModules.World.Land if (m_scene.Permissions.CanEditParcel(remote_client.AgentId,this)) { //Needs later group support + bool snap_selection = false; LandData newData = LandData.Copy(); if (args.AuthBuyerID != newData.AuthBuyerID || args.SalePrice != newData.SalePrice) @@ -192,6 +211,7 @@ namespace OpenSim.Region.CoreModules.World.Land { newData.AuthBuyerID = args.AuthBuyerID; newData.SalePrice = args.SalePrice; + snap_selection = true; } } newData.Category = args.Category; @@ -212,7 +232,7 @@ namespace OpenSim.Region.CoreModules.World.Land m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); - SendLandUpdateToAvatarsOverMe(); + SendLandUpdateToAvatarsOverMe(snap_selection); } } @@ -230,7 +250,7 @@ namespace OpenSim.Region.CoreModules.World.Land newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects); m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); - SendLandUpdateToAvatarsOverMe(); + SendLandUpdateToAvatarsOverMe(true); } public void DeedToGroup(UUID groupID) @@ -242,7 +262,7 @@ namespace OpenSim.Region.CoreModules.World.Land m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); - SendLandUpdateToAvatarsOverMe(); + SendLandUpdateToAvatarsOverMe(true); } public bool IsEitherBannedOrRestricted(UUID avatar) @@ -297,7 +317,17 @@ namespace OpenSim.Region.CoreModules.World.Land SendLandProperties(0, false, 0, remote_client); } + public void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client) + { + SendLandProperties(0, snap_selection, 0, remote_client); + } + public void SendLandUpdateToAvatarsOverMe() + { + SendLandUpdateToAvatarsOverMe(false); + } + + public void SendLandUpdateToAvatarsOverMe(bool snap_selection) { List avatars = m_scene.GetAvatars(); ILandObject over = null; @@ -325,7 +355,7 @@ namespace OpenSim.Region.CoreModules.World.Land else avatars[i].Invulnerable = true; - SendLandUpdateToClient(avatars[i].ControllingClient); + SendLandUpdateToClient(snap_selection, avatars[i].ControllingClient); } } } diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index fe9de1b3c5..c79062469b 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -144,6 +144,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions private Dictionary GrantVB = new Dictionary(); private Dictionary GrantJS = new Dictionary(); private Dictionary GrantYP = new Dictionary(); + private IFriendsModule m_friendsModule = null; + #endregion #region IRegionModule Members @@ -363,6 +365,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions public void PostInitialise() { + m_friendsModule = m_scene.RequestModuleInterface(); + + if (m_friendsModule == null) + m_log.Error("[PERMISSIONS]: Friends module not found, friend permissions will not work"); + else + m_log.Info("[PERMISSIONS]: Friends module found, friend permissions enabled"); } public void Close() @@ -476,6 +484,24 @@ namespace OpenSim.Region.CoreModules.World.Permissions return false; } + protected bool IsFriendWithPerms(UUID user,UUID objectOwner) + { + + if (user == UUID.Zero) + return false; + + if (m_friendsModule == null) + return false; + + List profile = m_friendsModule.GetUserFriends(user); + + foreach (FriendListItem item in profile) + { + if(item.Friend == objectOwner && (item.FriendPerms & (uint)FriendRights.CanModifyObjects) != 0) + return true; + } + return false; + } protected bool IsEstateManager(UUID user) { @@ -565,6 +591,9 @@ namespace OpenSim.Region.CoreModules.World.Permissions // Object owners should be able to edit their own content if (user == objectOwner) return objectOwnerMask; + + if (IsFriendWithPerms(user, objectOwner)) + return objectOwnerMask; // Estate users should be able to edit anything in the sim if (IsEstateManager(user) && m_RegionOwnerIsGod && !IsAdministrator(objectOwner)) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index f4b54aa0a7..44a651f627 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -1077,14 +1077,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap m_scene.RegionInfo.RegionSettings.TerrainImageID = TerrainImageUUID; - AssetBase asset = new AssetBase(); - asset.FullID = m_scene.RegionInfo.RegionSettings.TerrainImageID; + AssetBase asset = new AssetBase( + m_scene.RegionInfo.RegionSettings.TerrainImageID, + "terrainImage_" + m_scene.RegionInfo.RegionID.ToString() + "_" + lastMapRefresh.ToString(), + (sbyte)AssetType.Texture); asset.Data = data; - asset.Name - = "terrainImage_" + m_scene.RegionInfo.RegionID.ToString() + "_" + lastMapRefresh.ToString(); asset.Description = m_scene.RegionInfo.RegionName; - - asset.Type = 0; asset.Temporary = temporary; m_scene.AssetService.Store(asset); } diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 5a5fcfe8c5..9754da3c78 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -179,6 +179,7 @@ namespace OpenSim.Region.Examples.SimpleModule public event FriendActionDelegate OnApproveFriendRequest; public event FriendActionDelegate OnDenyFriendRequest; public event FriendshipTermination OnTerminateFriendship; + public event GrantUserFriendRights OnGrantUserRights; public event EconomyDataRequest OnEconomyDataRequest; public event MoneyBalanceRequest OnMoneyBalanceRequest; @@ -538,6 +539,7 @@ namespace OpenSim.Region.Examples.SimpleModule public virtual void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List items, List folders, + int version, bool fetchFolders, bool fetchItems) { diff --git a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs index 7a8aba23e4..8386030a1f 100644 --- a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs @@ -27,6 +27,7 @@ using OpenMetaverse; using OpenSim.Framework; +using System.Collections.Generic; namespace OpenSim.Region.Framework.Interfaces { @@ -45,5 +46,6 @@ namespace OpenSim.Region.Framework.Interfaces /// /// void OfferFriendship(UUID fromUserId, IClientAPI toUserClient, string offerMessage); + List GetUserFriends(UUID agentID); } } diff --git a/OpenSim/Region/Framework/Interfaces/ILandObject.cs b/OpenSim/Region/Framework/Interfaces/ILandObject.cs index c2b1292864..084184ffb4 100644 --- a/OpenSim/Region/Framework/Interfaces/ILandObject.cs +++ b/OpenSim/Region/Framework/Interfaces/ILandObject.cs @@ -54,6 +54,7 @@ namespace OpenSim.Region.Framework.Interfaces bool IsBannedFromLand(UUID avatar); bool IsRestrictedFromLand(UUID avatar); void SendLandUpdateToClient(IClientAPI remote_client); + void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client); List CreateAccessListArrayByFlag(AccessList flag); void SendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID, IClientAPI remote_client); void UpdateAccessList(uint flags, List entries, IClientAPI remote_client); diff --git a/OpenSim/Grid/GridServer/Program.cs b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs similarity index 60% rename from OpenSim/Grid/GridServer/Program.cs rename to OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs index 741a01b94a..5cdf1911b2 100644 --- a/OpenSim/Grid/GridServer/Program.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs @@ -25,41 +25,20 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using log4net.Config; -using Nini.Config; +using System; +using OpenMetaverse; -namespace OpenSim.Grid.GridServer +namespace OpenSim.Region.Framework.Interfaces { - public class Program + public delegate void ScriptCommand(UUID script, string id, string module, string command, string k); + + public interface IScriptModuleComms { - public static void Main(string[] args) - { - ArgvConfigSource argvSource = new ArgvConfigSource(args); - argvSource.AddSwitch("Startup", "console", "c"); - argvSource.AddSwitch("Startup", "xmlfile", "x"); + event ScriptCommand OnScriptCommand; - XmlConfigurator.Configure(); + void DispatchReply(UUID script, int code, string text, string k); - GridServerBase app = new GridServerBase(); - - IConfig startupConfig = argvSource.Configs["Startup"]; - if (startupConfig != null) - { - app.m_consoleType = startupConfig.GetString("console", "local"); - app.m_configFile = startupConfig.GetString("xmlfile", "GridServer_Config.xml"); - } - - app.m_configSource = argvSource; - -// if (args.Length > 0 && args[0] == "-setuponly") -// { -// app.Config(); -// } -// else -// { - app.Startup(); - app.Work(); -// } - } + // For use ONLY by the script API + void RaiseEvent(UUID script, string id, string module, string command, string k); } } diff --git a/OpenSim/Region/Framework/Scenes/EntityBase.cs b/OpenSim/Region/Framework/Scenes/EntityBase.cs index c2ec6a5c6e..1c76c546e5 100644 --- a/OpenSim/Region/Framework/Scenes/EntityBase.cs +++ b/OpenSim/Region/Framework/Scenes/EntityBase.cs @@ -94,14 +94,6 @@ namespace OpenSim.Region.Framework.Scenes set { m_velocity = value; } } - protected Quaternion m_rotation = new Quaternion(0f, 0f, 1f, 0f); - - public virtual Quaternion Rotation - { - get { return m_rotation; } - set { m_rotation = value; } - } - protected uint m_localId; public virtual uint LocalId @@ -115,13 +107,7 @@ namespace OpenSim.Region.Framework.Scenes /// public EntityBase() { - m_uuid = UUID.Zero; - - m_pos = Vector3.Zero; - m_velocity = Vector3.Zero; - Rotation = Quaternion.Identity; m_name = "(basic entity)"; - m_rotationalvelocity = Vector3.Zero; } /// diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs index 244ac3bc0f..ec50598f3b 100644 --- a/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs +++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs @@ -77,13 +77,13 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid #region Internal functions - private string UserAssetURL(UUID userID) - { - CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID); - if (uinfo != null) - return (uinfo.UserProfile.UserAssetURI == "") ? null : uinfo.UserProfile.UserAssetURI; - return null; - } +// private string UserAssetURL(UUID userID) +// { +// CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID); +// if (uinfo != null) +// return (uinfo.UserProfile.UserAssetURI == "") ? null : uinfo.UserProfile.UserAssetURI; +// return null; +// } // private string UserInventoryURL(UUID userID) // { @@ -118,7 +118,7 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid // HGAssetService dispatches it to the remote grid. // It's not pretty, but the best that can be done while // not having a global naming infrastructure - AssetBase asset1 = new AssetBase(); + AssetBase asset1 = new AssetBase(asset.FullID, asset.Name, asset.Type); Copy(asset, asset1); try { diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 4d76b4ef6a..66fb918bd7 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -93,7 +93,6 @@ namespace OpenSim.Region.Framework.Scenes public void AddInventoryItem(UUID AgentID, InventoryItemBase item) { - if (InventoryService.AddItem(item)) { int userlevel = 0; @@ -627,11 +626,8 @@ namespace OpenSim.Region.Framework.Scenes /// private AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data) { - AssetBase asset = new AssetBase(); - asset.Name = name; + AssetBase asset = new AssetBase(UUID.Random(), name, assetType); asset.Description = description; - asset.Type = assetType; - asset.FullID = UUID.Random(); asset.Data = (data == null) ? new byte[1] : data; return asset; @@ -807,20 +803,6 @@ namespace OpenSim.Region.Framework.Scenes InventoryService.DeleteFolders(remoteClient.AgentId, folderIDs); } - private SceneObjectGroup GetGroupByPrim(uint localID) - { - List EntityList = GetEntities(); - - foreach (EntityBase ent in EntityList) - { - if (ent is SceneObjectGroup) - { - if (((SceneObjectGroup) ent).HasChildPrim(localID)) - return (SceneObjectGroup) ent; - } - } - return null; - } /// /// Send the details of a prim's inventory to the client. @@ -1175,7 +1157,13 @@ namespace OpenSim.Region.Framework.Scenes { m_log.DebugFormat("[AGENT INVENTORY]: Send Inventory Folder {0} Update to {1} {2}", folder.Name, client.FirstName, client.LastName); InventoryCollection contents = InventoryService.GetFolderContent(client.AgentId, folder.ID); - client.SendInventoryFolderDetails(client.AgentId, folder.ID, contents.Items, contents.Folders, fetchFolders, fetchItems); + InventoryFolderBase containingFolder = new InventoryFolderBase(); + containingFolder.ID = folder.ID; + containingFolder.Owner = client.AgentId; + containingFolder = InventoryService.GetFolder(containingFolder); + int version = containingFolder.Version; + + client.SendInventoryFolderDetails(client.AgentId, folder.ID, contents.Items, contents.Folders, version, fetchFolders, fetchItems); } /// diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 1a91f0c9b0..47fbeb45db 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -462,7 +462,7 @@ namespace OpenSim.Region.Framework.Scenes { remoteClient.SendInventoryFolderDetails( fold.Owner, folderID, fold.RequestListOfItems(), - fold.RequestListOfFolders(), fetchFolders, fetchItems); + fold.RequestListOfFolders(), fold.Version, fetchFolders, fetchItems); return; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index a6ee40a0ab..aeca7df2d6 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -36,6 +36,7 @@ using System.Timers; using System.Xml; using Nini.Config; using OpenMetaverse; +using OpenMetaverse.Packets; using OpenMetaverse.Imaging; using OpenSim.Framework; using OpenSim.Services.Interfaces; @@ -87,8 +88,18 @@ namespace OpenSim.Region.Framework.Scenes protected List m_regionRestartNotifyList = new List(); protected List m_neighbours = new List(); - public volatile bool BordersLocked = false; - + private volatile int m_bordersLocked = 0; + public bool BordersLocked + { + get { return m_bordersLocked == 1; } + set + { + if (value == true) + m_bordersLocked = 1; + else + m_bordersLocked = 0; + } + } public List NorthBorders = new List(); public List EastBorders = new List(); public List SouthBorders = new List(); @@ -397,6 +408,73 @@ namespace OpenSim.Region.Framework.Scenes #endregion + #region BinaryStats + + public class StatLogger + { + public DateTime StartTime; + public string Path; + public System.IO.BinaryWriter Log; + } + static StatLogger m_statLog = null; + static TimeSpan m_statLogPeriod = TimeSpan.FromSeconds(300); + static string m_statsDir = String.Empty; + static Object m_statLockObject = new Object(); + private void LogSimStats(SimStats stats) + { + SimStatsPacket pack = new SimStatsPacket(); + pack.Region = new SimStatsPacket.RegionBlock(); + pack.Region.RegionX = stats.RegionX; + pack.Region.RegionY = stats.RegionY; + pack.Region.RegionFlags = stats.RegionFlags; + pack.Region.ObjectCapacity = stats.ObjectCapacity; + //pack.Region = //stats.RegionBlock; + pack.Stat = stats.StatsBlock; + pack.Header.Reliable = false; + + // note that we are inside the reporter lock when called + DateTime now = DateTime.Now; + + // hide some time information into the packet + pack.Header.Sequence = (uint)now.Ticks; + + lock (m_statLockObject) // m_statLog is shared so make sure there is only executer here + { + try + { + if (m_statLog == null || now > m_statLog.StartTime + m_statLogPeriod) + { + // First log file or time has expired, start writing to a new log file + if (m_statLog != null && m_statLog.Log != null) + { + m_statLog.Log.Close(); + } + m_statLog = new StatLogger(); + m_statLog.StartTime = now; + m_statLog.Path = (m_statsDir.Length > 0 ? m_statsDir + System.IO.Path.DirectorySeparatorChar.ToString() : "") + + String.Format("stats-{0}.log", now.ToString("yyyyMMddHHmmss")); + m_statLog.Log = new BinaryWriter(File.Open(m_statLog.Path, FileMode.Append, FileAccess.Write)); + } + + // Write the serialized data to disk + if (m_statLog != null && m_statLog.Log != null) + m_statLog.Log.Write(pack.ToBytes()); + } + catch (Exception ex) + { + m_log.Error("statistics gathering failed: " + ex.Message, ex); + if (m_statLog != null && m_statLog.Log != null) + { + m_statLog.Log.Close(); + } + m_statLog = null; + } + } + return; + } + + #endregion + #region Constructors public Scene(RegionInfo regInfo, AgentCircuitManager authen, @@ -582,6 +660,38 @@ namespace OpenSim.Region.Framework.Scenes } m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); + + #region BinaryStats + + try + { + IConfig statConfig = m_config.Configs["Statistics.Binary"]; + if (statConfig.Contains("enabled") && statConfig.GetBoolean("enabled")) + { + if (statConfig.Contains("collect_region_stats")) + { + if (statConfig.GetBoolean("collect_region_stats")) + { + // if enabled, add us to the event. If not enabled, I won't get called + StatsReporter.OnSendStatsResult += LogSimStats; + } + } + if (statConfig.Contains("region_stats_period_seconds")) + { + m_statLogPeriod = TimeSpan.FromSeconds(statConfig.GetInt("region_stats_period_seconds")); + } + if (statConfig.Contains("stats_dir")) + { + m_statsDir = statConfig.GetString("stats_dir"); + } + } + } + catch + { + // if it doesn't work, we don't collect anything + } + + #endregion BinaryStats } catch { @@ -1043,7 +1153,7 @@ namespace OpenSim.Region.Framework.Scenes TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate; physicsFPS = 0f; - maintc = maintc = otherMS = Environment.TickCount; + maintc = otherMS = Environment.TickCount; int tmpFrameMS = maintc; // Increment the frame counter @@ -4273,6 +4383,16 @@ namespace OpenSim.Region.Framework.Scenes return m_sceneGraph.GetSceneObjectPart(fullID); } + /// + /// Get a scene object group that contains the prim with the given local id + /// + /// + /// null if no scene object group containing that prim is found + public SceneObjectGroup GetGroupByPrim(uint localID) + { + return m_sceneGraph.GetGroupByPrim(localID); + } + public bool TryGetAvatar(UUID avatarId, out ScenePresence avatar) { return m_sceneGraph.TryGetAvatar(avatarId, out avatar); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 0b752c967a..bcc9b37aee 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -204,6 +204,14 @@ namespace OpenSim.Region.Framework.Scenes get { return m_parts.Count; } } + protected Quaternion m_rotation = Quaternion.Identity; + + public virtual Quaternion Rotation + { + get { return m_rotation; } + set { m_rotation = value; } + } + public Quaternion GroupRotation { get { return m_rootPart.RotationOffset; } @@ -1959,12 +1967,12 @@ namespace OpenSim.Region.Framework.Scenes /// Note: this may not be cused by opensim (it probably should) but it's used by /// external modules. /// - public void SendGroupRootUpdate() + public void SendGroupRootTerseUpdate() { if (IsDeleted) return; - RootPart.SendFullUpdateToAllClients(); + RootPart.SendTerseUpdateToAllClients(); } public void QueueForUpdateCheck() @@ -2946,12 +2954,13 @@ namespace OpenSim.Region.Framework.Scenes /// public void UpdateGroupRotationR(Quaternion rot) { - m_rootPart.UpdateRotation(rot); - if (m_rootPart.PhysActor != null) + + PhysicsActor actor = m_rootPart.PhysActor; + if (actor != null) { - m_rootPart.PhysActor.Orientation = m_rootPart.RotationOffset; - m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); + actor.Orientation = m_rootPart.RotationOffset; + m_scene.PhysicsScene.AddPhysicsActorTaint(actor); } HasGroupChanged = true; @@ -2966,11 +2975,14 @@ namespace OpenSim.Region.Framework.Scenes public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) { m_rootPart.UpdateRotation(rot); - if (m_rootPart.PhysActor != null) + + PhysicsActor actor = m_rootPart.PhysActor; + if (actor != null) { - m_rootPart.PhysActor.Orientation = m_rootPart.RotationOffset; - m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); + actor.Orientation = m_rootPart.RotationOffset; + m_scene.PhysicsScene.AddPhysicsActorTaint(actor); } + AbsolutePosition = pos; HasGroupChanged = true; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 2bc7f66ef9..73d0984e6b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -243,7 +243,7 @@ namespace OpenSim.Region.Framework.Scenes protected SceneObjectGroup m_parentGroup; protected byte[] m_particleSystem = Utils.EmptyBytes; protected ulong m_regionHandle; - protected Quaternion m_rotationOffset; + protected Quaternion m_rotationOffset = Quaternion.Identity; protected PrimitiveBaseShape m_shape; protected UUID m_uuid; protected Vector3 m_velocity; @@ -3758,14 +3758,12 @@ namespace OpenSim.Region.Framework.Scenes Vector3 lPos = OffsetPosition; - byte state = Shape.State; if (IsAttachment) { if (ParentGroup.RootPart != this) return; lPos = ParentGroup.RootPart.AttachedPos; - state = (byte)AttachmentPoint; } else { @@ -3778,7 +3776,7 @@ namespace OpenSim.Region.Framework.Scenes remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle, m_parentGroup.GetTimeDilation(), LocalId, lPos, RotationOffset, Velocity, Acceleration, - AngularVelocity, state, FromItemID, + AngularVelocity, FromItemID, OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient))); } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 6c0d9f2a9b..08c144af5e 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -76,7 +76,7 @@ namespace OpenSim.Region.Framework.Scenes private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; - private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); +// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); /// @@ -181,7 +181,7 @@ namespace OpenSim.Region.Framework.Scenes private byte m_state; //Reuse the Vector3 instead of creating a new one on the UpdateMovement method - private Vector3 movementvector; +// private Vector3 movementvector; private bool m_autopilotMoving; private Vector3 m_autoPilotTarget; @@ -481,6 +481,12 @@ namespace OpenSim.Region.Framework.Scenes } } + public Quaternion Rotation + { + get { return m_bodyRot; } + set { m_bodyRot = value; } + } + /// /// If this is true, agent doesn't have a representation in this scene. /// this is an agent 'looking into' this scene from a nearby scene(region) @@ -1912,14 +1918,10 @@ namespace OpenSim.Region.Framework.Scenes } - AssetBase Animasset = new AssetBase(); + AssetBase Animasset = new AssetBase(UUID.Random(), "Random Animation", (sbyte)AssetType.Animation); Animasset.Data = anim.ToBytes(); Animasset.Temporary = true; Animasset.Local = true; - Animasset.FullID = UUID.Random(); - Animasset.ID = Animasset.FullID.ToString(); - Animasset.Name = "Random Animation"; - Animasset.Type = (sbyte)AssetType.Animation; Animasset.Description = "dance"; //BinBVHAnimation bbvhanim = new BinBVHAnimation(Animasset.Data); @@ -2068,7 +2070,7 @@ namespace OpenSim.Region.Framework.Scenes if (heldDown) { move.Z -= 1; } // Is the avatar trying to move? - bool moving = (move != Vector3.Zero); +// bool moving = (move != Vector3.Zero); bool jumping = m_animTickJump != 0; #endregion Inputs @@ -2256,7 +2258,7 @@ namespace OpenSim.Region.Framework.Scenes m_perfMonMS = Environment.TickCount; - m_rotation = rotation; + Rotation = rotation; Vector3 direc = vec * rotation; direc.Normalize(); @@ -2320,7 +2322,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_isChildAgent == false) { - PhysicsActor actor = m_physicsActor; +// PhysicsActor actor = m_physicsActor; // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to // grab the latest PhysicsActor velocity, whereas m_velocity is often @@ -3256,7 +3258,7 @@ namespace OpenSim.Region.Framework.Scenes Vector3 force = m_forceToApply.Value; m_updateflag = true; - movementvector = force; +// movementvector = force; Velocity = force; m_forceToApply = null; @@ -3905,7 +3907,7 @@ namespace OpenSim.Region.Framework.Scenes } else { - group = Scene.SceneGraph.GetGroupByPrim(data.localID); + group = Scene.GetGroupByPrim(data.localID); if (group != null) return GetSOGUpdatePriority(group); } diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs new file mode 100644 index 0000000000..b68a0444c8 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs @@ -0,0 +1,88 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System.Collections.Generic; +using System.Text; +using NUnit.Framework; +using NUnit.Framework.SyntaxHelpers; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Setup; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.Framework.Scenes.Tests +{ + [TestFixture] + public class UuidGathererTests + { + protected IAssetService m_assetService; + protected UuidGatherer m_uuidGatherer; + + [SetUp] + public void Init() + { + m_assetService = new MockAssetService(); + m_uuidGatherer = new UuidGatherer(m_assetService); + } + + [Test] + public void TestCorruptAsset() + { + TestHelper.InMethod(); + + UUID corruptAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); + AssetBase corruptAsset = AssetHelpers.CreateAsset(corruptAssetUuid, "CORRUPT ASSET"); + m_assetService.Store(corruptAsset); + + IDictionary foundAssetUuids = new Dictionary(); + m_uuidGatherer.GatherAssetUuids(corruptAssetUuid, AssetType.Object, foundAssetUuids); + + // We count the uuid as gathered even if the asset itself is corrupt. + Assert.That(foundAssetUuids.Count, Is.EqualTo(1)); + } + + /// + /// Test requests made for non-existent assets while we're gathering + /// + [Test] + public void TestMissingAsset() + { + TestHelper.InMethod(); + + UUID missingAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); + IDictionary foundAssetUuids = new Dictionary(); + + m_uuidGatherer.GatherAssetUuids(missingAssetUuid, AssetType.Object, foundAssetUuids); + + // We count the uuid as gathered even if the asset itself is missing. + Assert.That(foundAssetUuids.Count, Is.EqualTo(1)); + } + } +} diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs index 525a93a7fe..930af813c2 100644 --- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs +++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs @@ -273,7 +273,9 @@ namespace OpenSim.Region.Framework.Scenes { string xml = Utils.BytesToString(objectAsset.Data); SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); - GatherAssetUuids(sog, assetUuids); + + if (null != sog) + GatherAssetUuids(sog, assetUuids); } } } diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs index 4c2a4b9785..cfe1278786 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs @@ -40,7 +40,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private IRCServer m_server; - private Scene m_scene; +// private Scene m_scene; #region Implementation of IRegionModule @@ -50,7 +50,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView source.Configs["IRCd"].GetBoolean("Enabled",false)) { int portNo = source.Configs["IRCd"].GetInt("Port",6666); - m_scene = scene; +// m_scene = scene; m_server = new IRCServer(IPAddress.Parse("0.0.0.0"), portNo, scene); m_server.OnNewIRCClient += m_server_OnNewIRCClient; } diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 4b0d01a2ec..6c3e7eb64c 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -758,6 +758,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public event FriendActionDelegate OnApproveFriendRequest; public event FriendActionDelegate OnDenyFriendRequest; public event FriendshipTermination OnTerminateFriendship; + public event GrantUserFriendRights OnGrantUserRights; public event MoneyTransferRequest OnMoneyTransferRequest; public event EconomyDataRequest OnEconomyDataRequest; public event MoneyBalanceRequest OnMoneyBalanceRequest; @@ -1055,7 +1056,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server } - public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List items, List folders, bool fetchFolders, bool fetchItems) + public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List items, List folders, int version, bool fetchFolders, bool fetchItems) { } diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Graphics.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Graphics.cs index 963cab5bb8..8ea7ad39e4 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Graphics.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Graphics.cs @@ -49,11 +49,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule public UUID SaveBitmap(Bitmap data, bool lossless, bool temporary) { - AssetBase asset = new AssetBase(); - asset.FullID = UUID.Random(); + AssetBase asset = new AssetBase(UUID.Random(), "MRMDynamicImage", (sbyte)AssetType.Texture); asset.Data = OpenJPEG.EncodeFromImage(data, lossless); - asset.Name = "MRMDynamicImage"; - asset.Type = 0; asset.Description = "MRM Image"; asset.Local = false; asset.Temporary = temporary; diff --git a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs new file mode 100644 index 0000000000..44c9ada221 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs @@ -0,0 +1,105 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using Nini.Config; +using log4net; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using Mono.Addins; +using OpenMetaverse; + +namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")] + class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private IScriptModule m_scriptModule = null; + + public event ScriptCommand OnScriptCommand; + + public void Initialise(IConfigSource config) + { + } + + public void AddRegion(Scene scene) + { + scene.RegisterModuleInterface(this); + } + + public void RemoveRegion(Scene scene) + { + } + + public void RegionLoaded(Scene scene) + { + m_scriptModule = scene.RequestModuleInterface(); + + if (m_scriptModule != null) + m_log.Info("[MODULE COMMANDS]: Script engine found, module active"); + } + + public string Name + { + get { return "ScriptModuleCommsModule"; } + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void Close() + { + } + + public void RaiseEvent(UUID script, string id, string module, string command, string k) + { + ScriptCommand c = OnScriptCommand; + + if (c == null) + return; + + c(script, id, module, command, k); + } + + public void DispatchReply(UUID script, int code, string text, string k) + { + if (m_scriptModule == null) + return; + + Object[] args = new Object[] {-1, code, text, k}; + + m_scriptModule.PostScriptEvent(script, "link_message", args); + } + } +} diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index f7cadaabd2..cf36d080e1 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -283,6 +283,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC public event FriendActionDelegate OnApproveFriendRequest; public event FriendActionDelegate OnDenyFriendRequest; public event FriendshipTermination OnTerminateFriendship; + public event GrantUserFriendRights OnGrantUserRights; public event EconomyDataRequest OnEconomyDataRequest; public event MoneyBalanceRequest OnMoneyBalanceRequest; @@ -627,6 +628,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC public virtual void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List items, List folders, + int version, bool fetchFolders, bool fetchItems) { diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs index cbe73bbbe0..1e94ee2d82 100644 --- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs +++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs @@ -347,6 +347,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin { indexBase = mesh.getIndexListAsInt(); vertexBase = new Vector3[iVertexCount]; + for (int i = 0; i < iVertexCount; i++) { OpenMetaverse.Vector3 v = mesh.getVertexList()[i]; @@ -355,6 +356,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin else vertexBase[i] = Vector3.Zero; } + for (int ix = 0; ix < iIndexCount; ix += 3) { int ia = indexBase[ix + 0]; diff --git a/OpenSim/Region/Physics/Meshing/PrimMesher.cs b/OpenSim/Region/Physics/Meshing/PrimMesher.cs index 47ce615224..2a213c3d88 100644 --- a/OpenSim/Region/Physics/Meshing/PrimMesher.cs +++ b/OpenSim/Region/Physics/Meshing/PrimMesher.cs @@ -67,11 +67,6 @@ namespace PrimMesher Normalize(); } - public Quat Identity() - { - return new Quat(0.0f, 0.0f, 0.0f, 1.0f); - } - public float Length() { return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W); @@ -660,7 +655,7 @@ namespace PrimMesher this.faceNumbers = new List(); Coord center = new Coord(0.0f, 0.0f, 0.0f); - bool hasCenter = false; + //bool hasCenter = false; List hollowCoords = new List(); List hollowNormals = new List(); @@ -727,7 +722,7 @@ namespace PrimMesher else if (!simpleFace) { this.coords.Add(center); - hasCenter = true; + //hasCenter = true; if (this.calcVertexNormals) this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f)); this.us.Add(0.0f); @@ -1353,7 +1348,7 @@ namespace PrimMesher float stepSize = twoPi / this.stepsPerRevolution; int step = (int)(startAngle / stepSize); - int firstStep = step; +// int firstStep = step; float angle = startAngle; bool done = false; @@ -1541,7 +1536,7 @@ namespace PrimMesher } /// - /// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism. + /// Extrudes a profile along a path. /// public void Extrude(PathType pathType) { @@ -1557,7 +1552,6 @@ namespace PrimMesher if (this.calcVertexNormals) this.normals = new List(); - //int step = 0; int steps = 1; float length = this.pathCutEnd - this.pathCutBegin; @@ -1579,20 +1573,6 @@ namespace PrimMesher if (twistTotalAbs > 0.01f) steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number - //float start = -0.5f; - //float stepSize = length / (float)steps; - //float percentOfPathMultiplier = stepSize; - //float xProfileScale = 1.0f; - //float yProfileScale = 1.0f; - //float xOffset = 0.0f; - //float yOffset = 0.0f; - //float zOffset = start; - //float xOffsetStepIncrement = this.topShearX / steps; - //float yOffsetStepIncrement = this.topShearY / steps; - - //float percentOfPath = this.pathCutBegin; - //zOffset += percentOfPath; - float hollow = this.hollow; // sanity checks @@ -1662,7 +1642,6 @@ namespace PrimMesher cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts; } - if (initialProfileRot != 0.0f) { profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); @@ -1693,24 +1672,6 @@ namespace PrimMesher path.stepsPerRevolution = stepsPerRevolution; path.Create(pathType, steps); - /* - public int twistBegin = 0; - public int twistEnd = 0; - public float topShearX = 0.0f; - public float topShearY = 0.0f; - public float pathCutBegin = 0.0f; - public float pathCutEnd = 1.0f; - public float dimpleBegin = 0.0f; - public float dimpleEnd = 1.0f; - public float skew = 0.0f; - public float holeSizeX = 1.0f; // called pathScaleX in pbs - public float holeSizeY = 0.25f; - public float taperX = 0.0f; - public float taperY = 0.0f; - public float radius = 0.0f; - public float revolutions = 1.0f; - public int stepsPerRevolution = 24; - */ bool needEndFaces = false; if (pathType == PathType.Circular) @@ -1777,7 +1738,7 @@ namespace PrimMesher // append this layer int coordsLen = this.coords.Count; - int lastCoordsLen = coordsLen; +// int lastCoordsLen = coordsLen; newLayer.AddValue2FaceVertexIndices(coordsLen); this.coords.AddRange(newLayer.coords); @@ -1796,7 +1757,6 @@ namespace PrimMesher int numVerts = newLayer.coords.Count; Face newFace = new Face(); - //if (step > 0) if (nodeIndex > 0) { int startVert = coordsLen + 1; @@ -1812,7 +1772,6 @@ namespace PrimMesher iNext = startVert; int whichVert = i - startVert; - //int whichVert2 = i - lastCoordsLen; newFace.v1 = i; newFace.v2 = i - numVerts; @@ -1982,809 +1941,27 @@ namespace PrimMesher /// + /// DEPRICATED - use Extrude(PathType.Linear) instead /// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism. /// + /// public void ExtrudeLinear() { - this.coords = new List(); - this.faces = new List(); - - if (this.viewerMode) - { - this.viewerFaces = new List(); - this.calcVertexNormals = true; - } - - if (this.calcVertexNormals) - this.normals = new List(); - - int step = 0; - int steps = 1; - - float length = this.pathCutEnd - this.pathCutBegin; - normalsProcessed = false; - - if (this.viewerMode && this.sides == 3) - { - // prisms don't taper well so add some vertical resolution - // other prims may benefit from this but just do prisms for now - if (Math.Abs(this.taperX) > 0.01 || Math.Abs(this.taperY) > 0.01) - steps = (int)(steps * 4.5 * length); - } - - - float twistBegin = this.twistBegin / 360.0f * twoPi; - float twistEnd = this.twistEnd / 360.0f * twoPi; - float twistTotal = twistEnd - twistBegin; - float twistTotalAbs = Math.Abs(twistTotal); - if (twistTotalAbs > 0.01f) - steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number - - float start = -0.5f; - float stepSize = length / (float)steps; - float percentOfPathMultiplier = stepSize; - float xProfileScale = 1.0f; - float yProfileScale = 1.0f; - float xOffset = 0.0f; - float yOffset = 0.0f; - float zOffset = start; - float xOffsetStepIncrement = this.topShearX / steps; - float yOffsetStepIncrement = this.topShearY / steps; - - float percentOfPath = this.pathCutBegin; - zOffset += percentOfPath; - - float hollow = this.hollow; - - // sanity checks - float initialProfileRot = 0.0f; - if (this.sides == 3) - { - if (this.hollowSides == 4) - { - if (hollow > 0.7f) - hollow = 0.7f; - hollow *= 0.707f; - } - else hollow *= 0.5f; - } - else if (this.sides == 4) - { - initialProfileRot = 1.25f * (float)Math.PI; - if (this.hollowSides != 4) - hollow *= 0.707f; - } - else if (this.sides == 24 && this.hollowSides == 4) - hollow *= 1.414f; - - Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, true, calcVertexNormals); - this.errorMessage = profile.errorMessage; - - this.numPrimFaces = profile.numPrimFaces; - - int cut1Vert = -1; - int cut2Vert = -1; - if (hasProfileCut) - { - cut1Vert = hasHollow ? profile.coords.Count - 1 : 0; - cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts; - } - - if (initialProfileRot != 0.0f) - { - profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); - if (viewerMode) - profile.MakeFaceUVs(); - } - - Coord lastCutNormal1 = new Coord(); - Coord lastCutNormal2 = new Coord(); - float lastV = 1.0f; - - bool done = false; - while (!done) - { - Profile newLayer = profile.Copy(); - - if (this.taperX == 0.0f) - xProfileScale = 1.0f; - else if (this.taperX > 0.0f) - xProfileScale = 1.0f - percentOfPath * this.taperX; - else xProfileScale = 1.0f + (1.0f - percentOfPath) * this.taperX; - - if (this.taperY == 0.0f) - yProfileScale = 1.0f; - else if (this.taperY > 0.0f) - yProfileScale = 1.0f - percentOfPath * this.taperY; - else yProfileScale = 1.0f + (1.0f - percentOfPath) * this.taperY; - - if (xProfileScale != 1.0f || yProfileScale != 1.0f) - newLayer.Scale(xProfileScale, yProfileScale); - - float twist = twistBegin + twistTotal * percentOfPath; - if (twist != 0.0f) - newLayer.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), twist)); - - newLayer.AddPos(xOffset, yOffset, zOffset); - - if (step == 0) - { - newLayer.FlipNormals(); - - // add the top faces to the viewerFaces list here - if (this.viewerMode) - { - Coord faceNormal = newLayer.faceNormal; - ViewerFace newViewerFace = new ViewerFace(profile.bottomFaceNumber); - int numFaces = newLayer.faces.Count; - List faces = newLayer.faces; - - for (int i = 0; i < numFaces; i++) - { - Face face = faces[i]; - newViewerFace.v1 = newLayer.coords[face.v1]; - newViewerFace.v2 = newLayer.coords[face.v2]; - newViewerFace.v3 = newLayer.coords[face.v3]; - - newViewerFace.coordIndex1 = face.v1; - newViewerFace.coordIndex2 = face.v2; - newViewerFace.coordIndex3 = face.v3; - - newViewerFace.n1 = faceNormal; - newViewerFace.n2 = faceNormal; - newViewerFace.n3 = faceNormal; - - newViewerFace.uv1 = newLayer.faceUVs[face.v1]; - newViewerFace.uv2 = newLayer.faceUVs[face.v2]; - newViewerFace.uv3 = newLayer.faceUVs[face.v3]; - - this.viewerFaces.Add(newViewerFace); - } - } - } - - // append this layer - - int coordsLen = this.coords.Count; - int lastCoordsLen = coordsLen; - newLayer.AddValue2FaceVertexIndices(coordsLen); - - this.coords.AddRange(newLayer.coords); - - if (this.calcVertexNormals) - { - newLayer.AddValue2FaceNormalIndices(this.normals.Count); - this.normals.AddRange(newLayer.vertexNormals); - } - - if (percentOfPath < this.pathCutBegin + 0.01f || percentOfPath > this.pathCutEnd - 0.01f) - this.faces.AddRange(newLayer.faces); - - // fill faces between layers - - int numVerts = newLayer.coords.Count; - Face newFace = new Face(); - - if (step > 0) - { - int startVert = coordsLen + 1; - int endVert = this.coords.Count; - - if (sides < 5 || this.hasProfileCut || hollow > 0.0f) - startVert--; - - for (int i = startVert; i < endVert; i++) - { - int iNext = i + 1; - if (i == endVert - 1) - iNext = startVert; - - int whichVert = i - startVert; - //int whichVert2 = i - lastCoordsLen; - - newFace.v1 = i; - newFace.v2 = i - numVerts; - newFace.v3 = iNext - numVerts; - this.faces.Add(newFace); - - newFace.v2 = iNext - numVerts; - newFace.v3 = iNext; - this.faces.Add(newFace); - - if (this.viewerMode) - { - // add the side faces to the list of viewerFaces here - //int primFaceNum = 1; - //if (whichVert >= sides) - // primFaceNum = 2; - int primFaceNum = profile.faceNumbers[whichVert]; - - ViewerFace newViewerFace1 = new ViewerFace(primFaceNum); - ViewerFace newViewerFace2 = new ViewerFace(primFaceNum); - - float u1 = newLayer.us[whichVert]; - float u2 = 1.0f; - if (whichVert < newLayer.us.Count - 1) - u2 = newLayer.us[whichVert + 1]; - - if (whichVert == cut1Vert || whichVert == cut2Vert) - { - u1 = 0.0f; - u2 = 1.0f; - } - else if (sides < 5) - { // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled - // to reflect the entire texture width - u1 *= sides; - u2 *= sides; - u2 -= (int)u1; - u1 -= (int)u1; - if (u2 < 0.1f) - u2 = 1.0f; - - //newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1; - } - - newViewerFace1.uv1.U = u1; - newViewerFace1.uv2.U = u1; - newViewerFace1.uv3.U = u2; - - newViewerFace1.uv1.V = 1.0f - percentOfPath; - newViewerFace1.uv2.V = lastV; - newViewerFace1.uv3.V = lastV; - - newViewerFace2.uv1.U = u1; - newViewerFace2.uv2.U = u2; - newViewerFace2.uv3.U = u2; - - newViewerFace2.uv1.V = 1.0f - percentOfPath; - newViewerFace2.uv2.V = lastV; - newViewerFace2.uv3.V = 1.0f - percentOfPath; - - newViewerFace1.v1 = this.coords[i]; - newViewerFace1.v2 = this.coords[i - numVerts]; - newViewerFace1.v3 = this.coords[iNext - numVerts]; - - newViewerFace2.v1 = this.coords[i]; - newViewerFace2.v2 = this.coords[iNext - numVerts]; - newViewerFace2.v3 = this.coords[iNext]; - - newViewerFace1.coordIndex1 = i; - newViewerFace1.coordIndex2 = i - numVerts; - newViewerFace1.coordIndex3 = iNext - numVerts; - - newViewerFace2.coordIndex1 = i; - newViewerFace2.coordIndex2 = iNext - numVerts; - newViewerFace2.coordIndex3 = iNext; - - // profile cut faces - if (whichVert == cut1Vert) - { - newViewerFace1.n1 = newLayer.cutNormal1; - newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1; - - newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1; - newViewerFace2.n2 = lastCutNormal1; - } - else if (whichVert == cut2Vert) - { - newViewerFace1.n1 = newLayer.cutNormal2; - newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2; - - newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2; - newViewerFace2.n2 = lastCutNormal2; - } - - else // outer and hollow faces - { - if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)) - { - newViewerFace1.CalcSurfaceNormal(); - newViewerFace2.CalcSurfaceNormal(); - } - else - { - newViewerFace1.n1 = this.normals[i]; - newViewerFace1.n2 = this.normals[i - numVerts]; - newViewerFace1.n3 = this.normals[iNext - numVerts]; - - newViewerFace2.n1 = this.normals[i]; - newViewerFace2.n2 = this.normals[iNext - numVerts]; - newViewerFace2.n3 = this.normals[iNext]; - } - } - - //newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = newLayer.faceNumbers[whichVert]; - - this.viewerFaces.Add(newViewerFace1); - this.viewerFaces.Add(newViewerFace2); - - } - } - } - - lastCutNormal1 = newLayer.cutNormal1; - lastCutNormal2 = newLayer.cutNormal2; - lastV = 1.0f - percentOfPath; - - // calc the step for the next iteration of the loop - - if (step < steps) - { - step += 1; - percentOfPath += percentOfPathMultiplier; - xOffset += xOffsetStepIncrement; - yOffset += yOffsetStepIncrement; - zOffset += stepSize; - if (percentOfPath > this.pathCutEnd) - done = true; - } - else done = true; - - if (done && viewerMode) - { - // add the top faces to the viewerFaces list here - Coord faceNormal = newLayer.faceNormal; - ViewerFace newViewerFace = new ViewerFace(); - newViewerFace.primFaceNumber = 0; - int numFaces = newLayer.faces.Count; - List faces = newLayer.faces; - - for (int i = 0; i < numFaces; i++) - { - Face face = faces[i]; - newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen]; - newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen]; - newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen]; - - newViewerFace.coordIndex1 = face.v1 - coordsLen; - newViewerFace.coordIndex2 = face.v2 - coordsLen; - newViewerFace.coordIndex3 = face.v3 - coordsLen; - - newViewerFace.n1 = faceNormal; - newViewerFace.n2 = faceNormal; - newViewerFace.n3 = faceNormal; - - newViewerFace.uv1 = newLayer.faceUVs[face.v1 - coordsLen]; - newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen]; - newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen]; - - this.viewerFaces.Add(newViewerFace); - } - } - } + this.Extrude(PathType.Linear); } /// + /// DEPRICATED - use Extrude(PathType.Circular) instead /// Extrude a profile into a circular path prim mesh. Used for prim types torus, tube, and ring. /// + /// public void ExtrudeCircular() { - this.coords = new List(); - this.faces = new List(); - - if (this.viewerMode) - { - this.viewerFaces = new List(); - this.calcVertexNormals = true; - } - - if (this.calcVertexNormals) - this.normals = new List(); - - int step = 0; - int steps = 24; - - normalsProcessed = false; - - float twistBegin = this.twistBegin / 360.0f * twoPi; - float twistEnd = this.twistEnd / 360.0f * twoPi; - float twistTotal = twistEnd - twistBegin; - - // if the profile has a lot of twist, add more layers otherwise the layers may overlap - // and the resulting mesh may be quite inaccurate. This method is arbitrary and doesn't - // accurately match the viewer - float twistTotalAbs = Math.Abs(twistTotal); - if (twistTotalAbs > 0.01f) - { - if (twistTotalAbs > Math.PI * 1.5f) - steps *= 2; - if (twistTotalAbs > Math.PI * 3.0f) - steps *= 2; - } - - float yPathScale = this.holeSizeY * 0.5f; - float pathLength = this.pathCutEnd - this.pathCutBegin; - float totalSkew = this.skew * 2.0f * pathLength; - float skewStart = this.pathCutBegin * 2.0f * this.skew - this.skew; - float xOffsetTopShearXFactor = this.topShearX * (0.25f + 0.5f * (0.5f - this.holeSizeY)); - float yShearCompensation = 1.0f + Math.Abs(this.topShearY) * 0.25f; - - // It's not quite clear what pushY (Y top shear) does, but subtracting it from the start and end - // angles appears to approximate it's effects on path cut. Likewise, adding it to the angle used - // to calculate the sine for generating the path radius appears to approximate it's effects there - // too, but there are some subtle differences in the radius which are noticeable as the prim size - // increases and it may affect megaprims quite a bit. The effect of the Y top shear parameter on - // the meshes generated with this technique appear nearly identical in shape to the same prims when - // displayed by the viewer. - - float startAngle = (twoPi * this.pathCutBegin * this.revolutions) - this.topShearY * 0.9f; - float endAngle = (twoPi * this.pathCutEnd * this.revolutions) - this.topShearY * 0.9f; - float stepSize = twoPi / this.stepsPerRevolution; - - step = (int)(startAngle / stepSize); - int firstStep = step; - float angle = startAngle; - float hollow = this.hollow; - - // sanity checks - float initialProfileRot = 0.0f; - if (this.sides == 3) - { - initialProfileRot = (float)Math.PI; - if (this.hollowSides == 4) - { - if (hollow > 0.7f) - hollow = 0.7f; - hollow *= 0.707f; - } - else hollow *= 0.5f; - } - else if (this.sides == 4) - { - initialProfileRot = 0.25f * (float)Math.PI; - if (this.hollowSides != 4) - hollow *= 0.707f; - } - else if (this.sides > 4) - { - initialProfileRot = (float)Math.PI; - if (this.hollowSides == 4) - { - if (hollow > 0.7f) - hollow = 0.7f; - hollow /= 0.7f; - } - } - - bool needEndFaces = false; - if (this.pathCutBegin != 0.0f || this.pathCutEnd != 1.0f) - needEndFaces = true; - else if (this.taperX != 0.0f || this.taperY != 0.0f) - needEndFaces = true; - else if (this.skew != 0.0f) - needEndFaces = true; - else if (twistTotal != 0.0f) - needEndFaces = true; - else if (this.radius != 0.0f) - needEndFaces = true; - - Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, needEndFaces, calcVertexNormals); - this.errorMessage = profile.errorMessage; - - this.numPrimFaces = profile.numPrimFaces; - - int cut1Vert = -1; - int cut2Vert = -1; - if (hasProfileCut) - { - cut1Vert = hasHollow ? profile.coords.Count - 1 : 0; - cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts; - } - - if (initialProfileRot != 0.0f) - { - profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); - if (viewerMode) - profile.MakeFaceUVs(); - } - - Coord lastCutNormal1 = new Coord(); - Coord lastCutNormal2 = new Coord(); - float lastV = 1.0f; - - bool done = false; - while (!done) // loop through the length of the path and add the layers - { - bool isEndLayer = false; - if (angle <= startAngle + .01f || angle >= endAngle - .01f) - isEndLayer = true; - - Profile newLayer = profile.Copy(); - - float xProfileScale = (1.0f - Math.Abs(this.skew)) * this.holeSizeX; - float yProfileScale = this.holeSizeY; - - float percentOfPath = angle / (twoPi * this.revolutions); - float percentOfAngles = (angle - startAngle) / (endAngle - startAngle); - - if (this.taperX > 0.01f) - xProfileScale *= 1.0f - percentOfPath * this.taperX; - else if (this.taperX < -0.01f) - xProfileScale *= 1.0f + (1.0f - percentOfPath) * this.taperX; - - if (this.taperY > 0.01f) - yProfileScale *= 1.0f - percentOfPath * this.taperY; - else if (this.taperY < -0.01f) - yProfileScale *= 1.0f + (1.0f - percentOfPath) * this.taperY; - - if (xProfileScale != 1.0f || yProfileScale != 1.0f) - newLayer.Scale(xProfileScale, yProfileScale); - - float radiusScale = 1.0f; - if (this.radius > 0.001f) - radiusScale = 1.0f - this.radius * percentOfPath; - else if (this.radius < 0.001f) - radiusScale = 1.0f + this.radius * (1.0f - percentOfPath); - - float twist = twistBegin + twistTotal * percentOfPath; - - float xOffset = 0.5f * (skewStart + totalSkew * percentOfAngles); - xOffset += (float)Math.Sin(angle) * xOffsetTopShearXFactor; - - float yOffset = yShearCompensation * (float)Math.Cos(angle) * (0.5f - yPathScale) * radiusScale; - - float zOffset = (float)Math.Sin(angle + this.topShearY) * (0.5f - yPathScale) * radiusScale; - - // next apply twist rotation to the profile layer - if (twistTotal != 0.0f || twistBegin != 0.0f) - newLayer.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), twist)); - - // now orient the rotation of the profile layer relative to it's position on the path - // adding taperY to the angle used to generate the quat appears to approximate the viewer - newLayer.AddRot(new Quat(new Coord(1.0f, 0.0f, 0.0f), angle + this.topShearY)); - newLayer.AddPos(xOffset, yOffset, zOffset); - - if (isEndLayer && angle <= startAngle + .01f) - { - newLayer.FlipNormals(); - - // add the top faces to the viewerFaces list here - if (this.viewerMode && needEndFaces) - { - Coord faceNormal = newLayer.faceNormal; - ViewerFace newViewerFace = new ViewerFace(); - newViewerFace.primFaceNumber = 0; - foreach (Face face in newLayer.faces) - { - newViewerFace.v1 = newLayer.coords[face.v1]; - newViewerFace.v2 = newLayer.coords[face.v2]; - newViewerFace.v3 = newLayer.coords[face.v3]; - - newViewerFace.coordIndex1 = face.v1; - newViewerFace.coordIndex2 = face.v2; - newViewerFace.coordIndex3 = face.v3; - - newViewerFace.n1 = faceNormal; - newViewerFace.n2 = faceNormal; - newViewerFace.n3 = faceNormal; - - newViewerFace.uv1 = newLayer.faceUVs[face.v1]; - newViewerFace.uv2 = newLayer.faceUVs[face.v2]; - newViewerFace.uv3 = newLayer.faceUVs[face.v3]; - - this.viewerFaces.Add(newViewerFace); - } - } - } - - // append the layer and fill in the sides - - int coordsLen = this.coords.Count; - newLayer.AddValue2FaceVertexIndices(coordsLen); - - this.coords.AddRange(newLayer.coords); - - if (this.calcVertexNormals) - { - newLayer.AddValue2FaceNormalIndices(this.normals.Count); - this.normals.AddRange(newLayer.vertexNormals); - } - - if (isEndLayer) - this.faces.AddRange(newLayer.faces); - - // fill faces between layers - - int numVerts = newLayer.coords.Count; - Face newFace = new Face(); - if (step > firstStep) - { - int startVert = coordsLen + 1; - int endVert = this.coords.Count; - - if (sides < 5 || this.hasProfileCut || hollow > 0.0f) - startVert--; - - for (int i = startVert; i < endVert; i++) - { - int iNext = i + 1; - if (i == endVert - 1) - iNext = startVert; - - int whichVert = i - startVert; - - newFace.v1 = i; - newFace.v2 = i - numVerts; - newFace.v3 = iNext - numVerts; - this.faces.Add(newFace); - - newFace.v2 = iNext - numVerts; - newFace.v3 = iNext; - this.faces.Add(newFace); - - if (this.viewerMode) - { - int primFaceNumber = profile.faceNumbers[whichVert]; - if (!needEndFaces) - primFaceNumber -= 1; - - // add the side faces to the list of viewerFaces here - ViewerFace newViewerFace1 = new ViewerFace(primFaceNumber); - ViewerFace newViewerFace2 = new ViewerFace(primFaceNumber); - float u1 = newLayer.us[whichVert]; - float u2 = 1.0f; - if (whichVert < newLayer.us.Count - 1) - u2 = newLayer.us[whichVert + 1]; - - if (whichVert == cut1Vert || whichVert == cut2Vert) - { - u1 = 0.0f; - u2 = 1.0f; - } - else if (sides < 5) - { // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled - // to reflect the entire texture width - u1 *= sides; - u2 *= sides; - u2 -= (int)u1; - u1 -= (int)u1; - if (u2 < 0.1f) - u2 = 1.0f; - - //newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1; - } - - newViewerFace1.uv1.U = u1; - newViewerFace1.uv2.U = u1; - newViewerFace1.uv3.U = u2; - - newViewerFace1.uv1.V = 1.0f - percentOfPath; - newViewerFace1.uv2.V = lastV; - newViewerFace1.uv3.V = lastV; - - newViewerFace2.uv1.U = u1; - newViewerFace2.uv2.U = u2; - newViewerFace2.uv3.U = u2; - - newViewerFace2.uv1.V = 1.0f - percentOfPath; - newViewerFace2.uv2.V = lastV; - newViewerFace2.uv3.V = 1.0f - percentOfPath; - - newViewerFace1.v1 = this.coords[i]; - newViewerFace1.v2 = this.coords[i - numVerts]; - newViewerFace1.v3 = this.coords[iNext - numVerts]; - - newViewerFace2.v1 = this.coords[i]; - newViewerFace2.v2 = this.coords[iNext - numVerts]; - newViewerFace2.v3 = this.coords[iNext]; - - newViewerFace1.coordIndex1 = i; - newViewerFace1.coordIndex2 = i - numVerts; - newViewerFace1.coordIndex3 = iNext - numVerts; - - newViewerFace2.coordIndex1 = i; - newViewerFace2.coordIndex2 = iNext - numVerts; - newViewerFace2.coordIndex3 = iNext; - - // profile cut faces - if (whichVert == cut1Vert) - { - newViewerFace1.n1 = newLayer.cutNormal1; - newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1; - - newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1; - newViewerFace2.n2 = lastCutNormal1; - } - else if (whichVert == cut2Vert) - { - newViewerFace1.n1 = newLayer.cutNormal2; - newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2; - - newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2; - newViewerFace2.n2 = lastCutNormal2; - } - else // periphery faces - { - if (sides < 5 && whichVert < newLayer.numOuterVerts) - { - newViewerFace1.n1 = this.normals[i]; - newViewerFace1.n2 = this.normals[i - numVerts]; - newViewerFace1.n3 = this.normals[i - numVerts]; - - newViewerFace2.n1 = this.normals[i]; - newViewerFace2.n2 = this.normals[i - numVerts]; - newViewerFace2.n3 = this.normals[i]; - } - else if (hollowSides < 5 && whichVert >= newLayer.numOuterVerts) - { - newViewerFace1.n1 = this.normals[iNext]; - newViewerFace1.n2 = this.normals[iNext - numVerts]; - newViewerFace1.n3 = this.normals[iNext - numVerts]; - - newViewerFace2.n1 = this.normals[iNext]; - newViewerFace2.n2 = this.normals[iNext - numVerts]; - newViewerFace2.n3 = this.normals[iNext]; - } - else - { - newViewerFace1.n1 = this.normals[i]; - newViewerFace1.n2 = this.normals[i - numVerts]; - newViewerFace1.n3 = this.normals[iNext - numVerts]; - - newViewerFace2.n1 = this.normals[i]; - newViewerFace2.n2 = this.normals[iNext - numVerts]; - newViewerFace2.n3 = this.normals[iNext]; - } - } - - //newViewerFace1.primFaceNumber = newViewerFace2.primFaceNumber = newLayer.faceNumbers[whichVert]; - this.viewerFaces.Add(newViewerFace1); - this.viewerFaces.Add(newViewerFace2); - - } - } - } - - lastCutNormal1 = newLayer.cutNormal1; - lastCutNormal2 = newLayer.cutNormal2; - lastV = 1.0f - percentOfPath; - - // calculate terms for next iteration - // calculate the angle for the next iteration of the loop - - if (angle >= endAngle - 0.01) - done = true; - else - { - step += 1; - angle = stepSize * step; - if (angle > endAngle) - angle = endAngle; - } - - if (done && viewerMode && needEndFaces) - { - // add the bottom faces to the viewerFaces list here - Coord faceNormal = newLayer.faceNormal; - ViewerFace newViewerFace = new ViewerFace(); - //newViewerFace.primFaceNumber = newLayer.bottomFaceNumber + 1; - newViewerFace.primFaceNumber = newLayer.bottomFaceNumber; - foreach (Face face in newLayer.faces) - { - newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen]; - newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen]; - newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen]; - - newViewerFace.coordIndex1 = face.v1 - coordsLen; - newViewerFace.coordIndex2 = face.v2 - coordsLen; - newViewerFace.coordIndex3 = face.v3 - coordsLen; - - newViewerFace.n1 = faceNormal; - newViewerFace.n2 = faceNormal; - newViewerFace.n3 = faceNormal; - - newViewerFace.uv1 = newLayer.faceUVs[face.v1 - coordsLen]; - newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen]; - newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen]; - - this.viewerFaces.Add(newViewerFace); - } - } - } + this.Extrude(PathType.Circular); } + private Coord SurfaceNormal(Coord c1, Coord c2, Coord c3) { Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z); diff --git a/OpenSim/Region/Physics/Meshing/SculptMesh.cs b/OpenSim/Region/Physics/Meshing/SculptMesh.cs index f1dd586b28..4dc6e2e510 100644 --- a/OpenSim/Region/Physics/Meshing/SculptMesh.cs +++ b/OpenSim/Region/Physics/Meshing/SculptMesh.cs @@ -25,12 +25,18 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +// to build without references to System.Drawing, comment this out +#define SYSTEM_DRAWING + using System; using System.Collections.Generic; using System.Text; using System.IO; + +#if SYSTEM_DRAWING using System.Drawing; using System.Drawing.Imaging; +#endif namespace PrimMesher { @@ -46,6 +52,7 @@ namespace PrimMesher public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 }; +#if SYSTEM_DRAWING // private Bitmap ScaleImage(Bitmap srcImage, float scale) // { // int sourceWidth = srcImage.Width; @@ -83,6 +90,7 @@ namespace PrimMesher // return scaledImage; // } + public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode) { Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); @@ -97,6 +105,7 @@ namespace PrimMesher _SculptMesh(bitmap, (SculptType)sculptType, lod, viewerMode != 0, mirror != 0, invert != 0); bitmap.Dispose(); } +#endif /// /// ** Experimental ** May disappear from future versions ** not recommeneded for use in applications @@ -201,6 +210,7 @@ namespace PrimMesher calcVertexNormals(SculptType.plane, numXElements, numYElements); } +#if SYSTEM_DRAWING public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode) { _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, false, false); @@ -210,9 +220,16 @@ namespace PrimMesher { _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, mirror, invert); } +#endif + public SculptMesh(List> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert) + { + _SculptMesh(rows, sculptType, viewerMode, mirror, invert); + } + +#if SYSTEM_DRAWING /// - /// converts a bitmap to a list lists of coords, while scaling the image. + /// converts a bitmap to a list of lists of coords, while scaling the image. /// the scaling is done in floating point so as to allow for reduced vertex position /// quantization as the position will be averaged between pixel values. this routine will /// likely fail if the bitmap width and height are not powers of 2. @@ -267,6 +284,7 @@ namespace PrimMesher return rows; } + void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert) { coords = new List(); @@ -285,12 +303,27 @@ namespace PrimMesher int scale = (int)(1.0f / sourceScaleFactor); if (scale < 1) scale = 1; - List> rows = bitmap2Coords(sculptBitmap, scale, mirror); + _SculptMesh(bitmap2Coords(sculptBitmap, scale, mirror), sculptType, viewerMode, mirror, invert); + } +#endif + + + void _SculptMesh(List> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert) + { + coords = new List(); + faces = new List(); + normals = new List(); + uvs = new List(); + + sculptType = (SculptType)(((int)sculptType) & 0x07); + + if (mirror) + if (sculptType == SculptType.plane) + invert = !invert; viewerFaces = new List(); - int width = sculptBitmap.Width / scale; - // int height = sculptBitmap.Height / scale; + int width = rows[0].Count; int p1, p2, p3, p4; diff --git a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs index 4a802cd1bd..39cdc0ff62 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs @@ -67,8 +67,8 @@ namespace OpenSim.Region.Physics.OdePlugin // private OdeScene m_parentScene = null; private IntPtr m_body = IntPtr.Zero; - private IntPtr m_jointGroup = IntPtr.Zero; - private IntPtr m_aMotor = IntPtr.Zero; +// private IntPtr m_jointGroup = IntPtr.Zero; +// private IntPtr m_aMotor = IntPtr.Zero; // Vehicle properties @@ -117,7 +117,7 @@ namespace OpenSim.Region.Physics.OdePlugin //Hover and Buoyancy properties private float m_VhoverHeight = 0f; - private float m_VhoverEfficiency = 0f; +// private float m_VhoverEfficiency = 0f; private float m_VhoverTimescale = 0f; private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. @@ -170,11 +170,11 @@ namespace OpenSim.Region.Physics.OdePlugin if (pValue > 1f) pValue = 1f; m_VehicleBuoyancy = pValue; break; - case Vehicle.HOVER_EFFICIENCY: - if (pValue < 0f) pValue = 0f; - if (pValue > 1f) pValue = 1f; - m_VhoverEfficiency = pValue; - break; +// case Vehicle.HOVER_EFFICIENCY: +// if (pValue < 0f) pValue = 0f; +// if (pValue > 1f) pValue = 1f; +// m_VhoverEfficiency = pValue; +// break; case Vehicle.HOVER_HEIGHT: m_VhoverHeight = pValue; break; @@ -291,7 +291,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_angularMotorTimescale = 1000; m_angularMotorDecayTimescale = 120; m_VhoverHeight = 0; - m_VhoverEfficiency = 1; +// m_VhoverEfficiency = 1; m_VhoverTimescale = 10; m_VehicleBuoyancy = 0; // m_linearDeflectionEfficiency = 1; @@ -317,7 +317,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_angularMotorTimescale = 1; m_angularMotorDecayTimescale = 0.8f; m_VhoverHeight = 0; - m_VhoverEfficiency = 0; +// m_VhoverEfficiency = 0; m_VhoverTimescale = 1000; m_VehicleBuoyancy = 0; // // m_linearDeflectionEfficiency = 1; @@ -344,7 +344,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_angularMotorTimescale = 4; m_angularMotorDecayTimescale = 4; m_VhoverHeight = 0; - m_VhoverEfficiency = 0.5f; +// m_VhoverEfficiency = 0.5f; m_VhoverTimescale = 2; m_VehicleBuoyancy = 1; // m_linearDeflectionEfficiency = 0.5f; @@ -372,7 +372,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_angularMotorTimescale = 4; m_angularMotorDecayTimescale = 4; m_VhoverHeight = 0; - m_VhoverEfficiency = 0.5f; +// m_VhoverEfficiency = 0.5f; m_VhoverTimescale = 1000; m_VehicleBuoyancy = 0; // m_linearDeflectionEfficiency = 0.5f; @@ -399,7 +399,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_angularMotorTimescale = 6; m_angularMotorDecayTimescale = 10; m_VhoverHeight = 5; - m_VhoverEfficiency = 0.8f; +// m_VhoverEfficiency = 0.8f; m_VhoverTimescale = 10; m_VehicleBuoyancy = 1; // m_linearDeflectionEfficiency = 0; diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index f4b502a467..fa42023b35 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -2643,7 +2643,7 @@ Console.WriteLine(" JointCreateFixed"); //outofBounds = true; } - float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)); +// float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)); //Console.WriteLine("Adiff " + m_primName + " = " + Adiff); if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index a8e006bfa5..981cf430ce 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -439,7 +439,7 @@ namespace OpenSim.Region.Physics.OdePlugin avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f); avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f); avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f); - avCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", true); + avCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", false); contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80); @@ -3541,7 +3541,7 @@ namespace OpenSim.Region.Physics.OdePlugin public override void UnCombine(PhysicsScene pScene) { IntPtr localGround = IntPtr.Zero; - float[] localHeightfield; +// float[] localHeightfield; bool proceed = false; List geomDestroyList = new List(); @@ -3553,7 +3553,7 @@ namespace OpenSim.Region.Physics.OdePlugin { if (geom == localGround) { - localHeightfield = TerrainHeightFieldHeights[geom]; +// localHeightfield = TerrainHeightFieldHeights[geom]; proceed = true; } else @@ -3575,7 +3575,7 @@ namespace OpenSim.Region.Physics.OdePlugin // memory corruption if (TerrainHeightFieldHeights.ContainsKey(g)) { - float[] removingHeightField = TerrainHeightFieldHeights[g]; +// float[] removingHeightField = TerrainHeightFieldHeights[g]; TerrainHeightFieldHeights.Remove(g); if (RegionTerrain.ContainsKey(g)) diff --git a/OpenSim/Region/CoreModules/World/Land/RegionCombinerClientEventForwarder.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerClientEventForwarder.cs similarity index 98% rename from OpenSim/Region/CoreModules/World/Land/RegionCombinerClientEventForwarder.cs rename to OpenSim/Region/RegionCombinerModule/RegionCombinerClientEventForwarder.cs index 70d6de3fd6..721d396b48 100644 --- a/OpenSim/Region/CoreModules/World/Land/RegionCombinerClientEventForwarder.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerClientEventForwarder.cs @@ -30,7 +30,7 @@ using System.Collections.Generic; using OpenMetaverse; using OpenSim.Region.Framework.Scenes; -namespace OpenSim.Region.CoreModules.World.Land +namespace OpenSim.Region.RegionCombinerModule { public class RegionCombinerClientEventForwarder { diff --git a/OpenSim/Region/CoreModules/World/Land/RegionCombinerIndividualEventForwarder.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs similarity index 99% rename from OpenSim/Region/CoreModules/World/Land/RegionCombinerIndividualEventForwarder.cs rename to OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs index 2cbaf96356..9d41c9c225 100644 --- a/OpenSim/Region/CoreModules/World/Land/RegionCombinerIndividualEventForwarder.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs @@ -30,7 +30,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; -namespace OpenSim.Region.CoreModules.World.Land +namespace OpenSim.Region.RegionCombinerModule { public class RegionCombinerIndividualEventForwarder { diff --git a/OpenSim/Region/CoreModules/World/Land/RegionCombinerLargeLandChannel.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs similarity index 98% rename from OpenSim/Region/CoreModules/World/Land/RegionCombinerLargeLandChannel.cs rename to OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs index 7df836c044..146ec660c5 100644 --- a/OpenSim/Region/CoreModules/World/Land/RegionCombinerLargeLandChannel.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs @@ -30,8 +30,9 @@ using System.Collections.Generic; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.CoreModules.World.Land; -namespace OpenSim.Region.CoreModules.World.Land +namespace OpenSim.Region.RegionCombinerModule { public class RegionCombinerLargeLandChannel : ILandChannel { diff --git a/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs similarity index 70% rename from OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs rename to OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index d8c5ed9fcf..7ec1d4b216 100644 --- a/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -36,9 +36,15 @@ using OpenSim.Framework.Client; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Framework.Console; +using OpenSim.Region.Physics.Manager; +using Mono.Addins; -namespace OpenSim.Region.CoreModules.World.Land +[assembly: Addin("RegionCombinerModule", "0.1")] +[assembly: AddinDependency("OpenSim", "0.5")] +namespace OpenSim.Region.RegionCombinerModule { + + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class RegionCombinerModule : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -299,76 +305,13 @@ namespace OpenSim.Region.CoreModules.World.Land //xxy //xxx + if ((((int)conn.X * (int)Constants.RegionSize) + conn.XEnd >= (regionConnections.X * (int)Constants.RegionSize)) && (((int)conn.Y * (int)Constants.RegionSize) >= (regionConnections.Y * (int)Constants.RegionSize))) { - Vector3 offset = Vector3.Zero; - offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - - ((conn.X * (int)Constants.RegionSize))); - offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) - - ((conn.Y * (int)Constants.RegionSize))); - - Vector3 extents = Vector3.Zero; - extents.Y = conn.YEnd; - extents.X = conn.XEnd + regionConnections.XEnd; - - conn.UpdateExtents(extents); - - m_log.DebugFormat("Scene: {0} to the west of Scene{1} Offset: {2}. Extents:{3}", - conn.RegionScene.RegionInfo.RegionName, - regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); - - scene.BordersLocked = true; - conn.RegionScene.BordersLocked = true; - - RegionData ConnectedRegion = new RegionData(); - ConnectedRegion.Offset = offset; - ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; - ConnectedRegion.RegionScene = scene; - conn.ConnectedRegions.Add(ConnectedRegion); - - // Inform root region Physics about the extents of this region - conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); - - // Inform Child region that it needs to forward it's terrain to the root region - scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); - - // Extend the borders as appropriate - lock (conn.RegionScene.EastBorders) - conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; - - lock (conn.RegionScene.NorthBorders) - conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; - - lock (conn.RegionScene.SouthBorders) - conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; - - lock (scene.WestBorders) - { - - - scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - conn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West - - // Trigger auto teleport to root region - scene.WestBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; - scene.WestBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; - } - - // Reset Terrain.. since terrain loads before we get here, we need to load - // it again so it loads in the root region - - scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); - - // Unlock borders - conn.RegionScene.BordersLocked = false; - scene.BordersLocked = false; - - // Create a client event forwarder and add this region's events to the root region. - if (conn.ClientEventForwarder != null) - conn.ClientEventForwarder.AddSceneToEventForwarding(scene); - connectedYN = true; + connectedYN = DoWorkForOneRegionOverPlusXY(conn, regionConnections, scene); break; } @@ -381,57 +324,8 @@ namespace OpenSim.Region.CoreModules.World.Land && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd >= (regionConnections.Y * (int)Constants.RegionSize))) { - Vector3 offset = Vector3.Zero; - offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - - ((conn.X * (int)Constants.RegionSize))); - offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) - - ((conn.Y * (int)Constants.RegionSize))); - - Vector3 extents = Vector3.Zero; - extents.Y = regionConnections.YEnd + conn.YEnd; - extents.X = conn.XEnd; - conn.UpdateExtents(extents); - - scene.BordersLocked = true; - conn.RegionScene.BordersLocked = true; - - RegionData ConnectedRegion = new RegionData(); - ConnectedRegion.Offset = offset; - ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; - ConnectedRegion.RegionScene = scene; - conn.ConnectedRegions.Add(ConnectedRegion); - - m_log.DebugFormat("Scene: {0} to the northeast of Scene{1} Offset: {2}. Extents:{3}", - conn.RegionScene.RegionInfo.RegionName, - regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); - - conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); - scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); - - lock (conn.RegionScene.NorthBorders) - conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; - lock (conn.RegionScene.EastBorders) - conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; - lock (conn.RegionScene.WestBorders) - conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; - lock (scene.SouthBorders) - { - scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - conn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south - scene.SouthBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; - scene.SouthBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; - } - - // Reset Terrain.. since terrain normally loads first. - //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); - scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); - //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); - - scene.BordersLocked = false; - conn.RegionScene.BordersLocked = false; - if (conn.ClientEventForwarder != null) - conn.ClientEventForwarder.AddSceneToEventForwarding(scene); - connectedYN = true; - break; + connectedYN = DoWorkForOneRegionOverXPlusY(conn, regionConnections, scene); + break; } // If we're one region over +x +y @@ -443,142 +337,278 @@ namespace OpenSim.Region.CoreModules.World.Land && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd >= (regionConnections.Y * (int)Constants.RegionSize))) { - Vector3 offset = Vector3.Zero; - offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - - ((conn.X * (int)Constants.RegionSize))); - offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) - - ((conn.Y * (int)Constants.RegionSize))); + connectedYN = DoWorkForOneRegionOverPlusXPlusY(conn, regionConnections, scene); + break; - Vector3 extents = Vector3.Zero; - extents.Y = regionConnections.YEnd + conn.YEnd; - extents.X = regionConnections.XEnd + conn.XEnd; - conn.UpdateExtents(extents); - - scene.BordersLocked = true; - conn.RegionScene.BordersLocked = true; - - RegionData ConnectedRegion = new RegionData(); - ConnectedRegion.Offset = offset; - ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; - ConnectedRegion.RegionScene = scene; - - conn.ConnectedRegions.Add(ConnectedRegion); - - m_log.DebugFormat("Scene: {0} to the NorthEast of Scene{1} Offset: {2}. Extents:{3}", - conn.RegionScene.RegionInfo.RegionName, - regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); - - conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); - scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); - lock (conn.RegionScene.NorthBorders) - { - if (conn.RegionScene.NorthBorders.Count == 1)// && 2) - { - //compound border - // already locked above - conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; - - lock (conn.RegionScene.EastBorders) - conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; - lock (conn.RegionScene.WestBorders) - conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; - } - } - - lock (scene.SouthBorders) - { - scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - conn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south - scene.SouthBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; - scene.SouthBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; - } - - lock (conn.RegionScene.EastBorders) - { - if (conn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2) - { - - conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; - lock (conn.RegionScene.NorthBorders) - conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; - lock (conn.RegionScene.SouthBorders) - conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; - - - } - } - - lock (scene.WestBorders) - { - scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - conn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West - scene.WestBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; - scene.WestBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; - } - - /* - else - { - conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; - conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; - conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; - scene.SouthBorders[0].BorderLine.Z += (int)Constants.RegionSize; //auto teleport south - } - */ - - - // Reset Terrain.. since terrain normally loads first. - //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); - scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); - //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); - scene.BordersLocked = false; - conn.RegionScene.BordersLocked = false; - - if (conn.ClientEventForwarder != null) - conn.ClientEventForwarder.AddSceneToEventForwarding(scene); - - connectedYN = true; - - //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents); - - break; } } // If !connectYN means that this region is a root region if (!connectedYN) { - RegionData rdata = new RegionData(); - rdata.Offset = Vector3.Zero; - rdata.RegionId = scene.RegionInfo.originRegionID; - rdata.RegionScene = scene; - // save it's land channel - regionConnections.RegionLandChannel = scene.LandChannel; + DoWorkForRootRegion(regionConnections, scene); - // Substitue our landchannel - RegionCombinerLargeLandChannel lnd = new RegionCombinerLargeLandChannel(rdata, scene.LandChannel, - regionConnections.ConnectedRegions); - scene.LandChannel = lnd; - // Forward the permissions modules of each of the connected regions to the root region - lock (m_regions) - { - foreach (RegionData r in regionConnections.ConnectedRegions) - { - ForwardPermissionRequests(regionConnections, r.RegionScene); - } - } - // Create the root region's Client Event Forwarder - regionConnections.ClientEventForwarder = new RegionCombinerClientEventForwarder(regionConnections); - - // Sets up the CoarseLocationUpdate forwarder for this root region - scene.EventManager.OnNewPresence += SetCourseLocationDelegate; - - // Adds this root region to a dictionary of regions that are connectable - m_regions.Add(scene.RegionInfo.originRegionID, regionConnections); } } // Set up infinite borders around the entire AABB of the combined ConnectedRegions AdjustLargeRegionBounds(); } + private bool DoWorkForOneRegionOverPlusXY(RegionConnections conn, RegionConnections regionConnections, Scene scene) + { + Vector3 offset = Vector3.Zero; + offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - + ((conn.X * (int)Constants.RegionSize))); + offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) - + ((conn.Y * (int)Constants.RegionSize))); + + Vector3 extents = Vector3.Zero; + extents.Y = conn.YEnd; + extents.X = conn.XEnd + regionConnections.XEnd; + + conn.UpdateExtents(extents); + + m_log.DebugFormat("Scene: {0} to the west of Scene{1} Offset: {2}. Extents:{3}", + conn.RegionScene.RegionInfo.RegionName, + regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); + + scene.BordersLocked = true; + conn.RegionScene.BordersLocked = true; + + RegionData ConnectedRegion = new RegionData(); + ConnectedRegion.Offset = offset; + ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; + ConnectedRegion.RegionScene = scene; + conn.ConnectedRegions.Add(ConnectedRegion); + + // Inform root region Physics about the extents of this region + conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); + + // Inform Child region that it needs to forward it's terrain to the root region + scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); + + // Extend the borders as appropriate + lock (conn.RegionScene.EastBorders) + conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; + + lock (conn.RegionScene.NorthBorders) + conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; + + lock (conn.RegionScene.SouthBorders) + conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; + + lock (scene.WestBorders) + { + + + scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - conn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West + + // Trigger auto teleport to root region + scene.WestBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; + scene.WestBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; + } + + // Reset Terrain.. since terrain loads before we get here, we need to load + // it again so it loads in the root region + + scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); + + // Unlock borders + conn.RegionScene.BordersLocked = false; + scene.BordersLocked = false; + + // Create a client event forwarder and add this region's events to the root region. + if (conn.ClientEventForwarder != null) + conn.ClientEventForwarder.AddSceneToEventForwarding(scene); + + return true; + } + + private bool DoWorkForOneRegionOverXPlusY(RegionConnections conn, RegionConnections regionConnections, Scene scene) + { + Vector3 offset = Vector3.Zero; + offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - + ((conn.X * (int)Constants.RegionSize))); + offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) - + ((conn.Y * (int)Constants.RegionSize))); + + Vector3 extents = Vector3.Zero; + extents.Y = regionConnections.YEnd + conn.YEnd; + extents.X = conn.XEnd; + conn.UpdateExtents(extents); + + scene.BordersLocked = true; + conn.RegionScene.BordersLocked = true; + + RegionData ConnectedRegion = new RegionData(); + ConnectedRegion.Offset = offset; + ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; + ConnectedRegion.RegionScene = scene; + conn.ConnectedRegions.Add(ConnectedRegion); + + m_log.DebugFormat("Scene: {0} to the northeast of Scene{1} Offset: {2}. Extents:{3}", + conn.RegionScene.RegionInfo.RegionName, + regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); + + conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); + scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); + + lock (conn.RegionScene.NorthBorders) + conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; + lock (conn.RegionScene.EastBorders) + conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; + lock (conn.RegionScene.WestBorders) + conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; + lock (scene.SouthBorders) + { + scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - conn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south + scene.SouthBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; + scene.SouthBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; + } + + // Reset Terrain.. since terrain normally loads first. + //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); + scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); + //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); + + scene.BordersLocked = false; + conn.RegionScene.BordersLocked = false; + if (conn.ClientEventForwarder != null) + conn.ClientEventForwarder.AddSceneToEventForwarding(scene); + return true; + } + + private bool DoWorkForOneRegionOverPlusXPlusY(RegionConnections conn, RegionConnections regionConnections, Scene scene) + { + Vector3 offset = Vector3.Zero; + offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - + ((conn.X * (int)Constants.RegionSize))); + offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) - + ((conn.Y * (int)Constants.RegionSize))); + + Vector3 extents = Vector3.Zero; + extents.Y = regionConnections.YEnd + conn.YEnd; + extents.X = regionConnections.XEnd + conn.XEnd; + conn.UpdateExtents(extents); + + scene.BordersLocked = true; + conn.RegionScene.BordersLocked = true; + + RegionData ConnectedRegion = new RegionData(); + ConnectedRegion.Offset = offset; + ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; + ConnectedRegion.RegionScene = scene; + + conn.ConnectedRegions.Add(ConnectedRegion); + + m_log.DebugFormat("Scene: {0} to the NorthEast of Scene{1} Offset: {2}. Extents:{3}", + conn.RegionScene.RegionInfo.RegionName, + regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); + + conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); + scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); + lock (conn.RegionScene.NorthBorders) + { + if (conn.RegionScene.NorthBorders.Count == 1)// && 2) + { + //compound border + // already locked above + conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; + + lock (conn.RegionScene.EastBorders) + conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; + lock (conn.RegionScene.WestBorders) + conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; + } + } + + lock (scene.SouthBorders) + { + scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - conn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south + scene.SouthBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; + scene.SouthBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; + } + + lock (conn.RegionScene.EastBorders) + { + if (conn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2) + { + + conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; + lock (conn.RegionScene.NorthBorders) + conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; + lock (conn.RegionScene.SouthBorders) + conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; + + + } + } + + lock (scene.WestBorders) + { + scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - conn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West + scene.WestBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; + scene.WestBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; + } + + /* + else + { + conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; + conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; + conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; + scene.SouthBorders[0].BorderLine.Z += (int)Constants.RegionSize; //auto teleport south + } + */ + + + // Reset Terrain.. since terrain normally loads first. + //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); + scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); + //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); + scene.BordersLocked = false; + conn.RegionScene.BordersLocked = false; + + if (conn.ClientEventForwarder != null) + conn.ClientEventForwarder.AddSceneToEventForwarding(scene); + + return true; + + //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents); + + } + + private void DoWorkForRootRegion(RegionConnections regionConnections, Scene scene) + { + RegionData rdata = new RegionData(); + rdata.Offset = Vector3.Zero; + rdata.RegionId = scene.RegionInfo.originRegionID; + rdata.RegionScene = scene; + // save it's land channel + regionConnections.RegionLandChannel = scene.LandChannel; + + // Substitue our landchannel + RegionCombinerLargeLandChannel lnd = new RegionCombinerLargeLandChannel(rdata, scene.LandChannel, + regionConnections.ConnectedRegions); + scene.LandChannel = lnd; + // Forward the permissions modules of each of the connected regions to the root region + lock (m_regions) + { + foreach (RegionData r in regionConnections.ConnectedRegions) + { + ForwardPermissionRequests(regionConnections, r.RegionScene); + } + } + // Create the root region's Client Event Forwarder + regionConnections.ClientEventForwarder = new RegionCombinerClientEventForwarder(regionConnections); + + // Sets up the CoarseLocationUpdate forwarder for this root region + scene.EventManager.OnNewPresence += SetCourseLocationDelegate; + + // Adds this root region to a dictionary of regions that are connectable + m_regions.Add(scene.RegionInfo.originRegionID, regionConnections); + } + private void SetCourseLocationDelegate(ScenePresence presence) { presence.SetSendCourseLocationMethod(SendCourseLocationUpdates); diff --git a/OpenSim/Region/CoreModules/World/Land/RegionCombinerPermissionModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs similarity index 99% rename from OpenSim/Region/CoreModules/World/Land/RegionCombinerPermissionModule.cs rename to OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs index 76ca5e377c..4d1af57450 100644 --- a/OpenSim/Region/CoreModules/World/Land/RegionCombinerPermissionModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs @@ -32,7 +32,7 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -namespace OpenSim.Region.CoreModules.World.Land +namespace OpenSim.Region.RegionCombinerModule { public class RegionCombinerPermissionModule { diff --git a/OpenSim/Region/CoreModules/World/Land/RegionConnections.cs b/OpenSim/Region/RegionCombinerModule/RegionConnections.cs similarity index 98% rename from OpenSim/Region/CoreModules/World/Land/RegionConnections.cs rename to OpenSim/Region/RegionCombinerModule/RegionConnections.cs index 419ed74698..3aa9f20f1a 100644 --- a/OpenSim/Region/CoreModules/World/Land/RegionConnections.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionConnections.cs @@ -31,7 +31,7 @@ using OpenMetaverse; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -namespace OpenSim.Region.CoreModules.World.Land +namespace OpenSim.Region.RegionCombinerModule { public class RegionConnections { diff --git a/OpenSim/Region/CoreModules/World/Land/RegionCourseLocation.cs b/OpenSim/Region/RegionCombinerModule/RegionCourseLocation.cs similarity index 97% rename from OpenSim/Region/CoreModules/World/Land/RegionCourseLocation.cs rename to OpenSim/Region/RegionCombinerModule/RegionCourseLocation.cs index 175ca8932d..53a678f82f 100644 --- a/OpenSim/Region/CoreModules/World/Land/RegionCourseLocation.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCourseLocation.cs @@ -30,7 +30,7 @@ using System.Collections.Generic; using OpenMetaverse; using OpenSim.Framework; -namespace OpenSim.Region.CoreModules.World.Land +namespace OpenSim.Region.RegionCombinerModule { struct RegionCourseLocationStruct diff --git a/OpenSim/Region/CoreModules/World/Land/RegionData.cs b/OpenSim/Region/RegionCombinerModule/RegionData.cs similarity index 97% rename from OpenSim/Region/CoreModules/World/Land/RegionData.cs rename to OpenSim/Region/RegionCombinerModule/RegionData.cs index 3383527f9e..bd0e398acd 100644 --- a/OpenSim/Region/CoreModules/World/Land/RegionData.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionData.cs @@ -28,7 +28,7 @@ using OpenMetaverse; using OpenSim.Region.Framework.Scenes; -namespace OpenSim.Region.CoreModules.World.Land +namespace OpenSim.Region.RegionCombinerModule { public class RegionData { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs new file mode 100644 index 0000000000..d4facdd657 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs @@ -0,0 +1,134 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Remoting.Lifetime; +using OpenMetaverse; +using Nini.Config; +using OpenSim; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Shared.Api +{ + [Serializable] + public class MOD_Api : MarshalByRefObject, IMOD_Api, IScriptApi + { + internal IScriptEngine m_ScriptEngine; + internal SceneObjectPart m_host; + internal uint m_localID; + internal UUID m_itemID; + internal bool m_MODFunctionsEnabled = false; + internal IScriptModuleComms m_comms = null; + + public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) + { + m_ScriptEngine = ScriptEngine; + m_host = host; + m_localID = localID; + m_itemID = itemID; + + if (m_ScriptEngine.Config.GetBoolean("AllowMODFunctions", false)) + m_MODFunctionsEnabled = true; + + m_comms = m_ScriptEngine.World.RequestModuleInterface(); + if (m_comms == null) + m_MODFunctionsEnabled = false; + } + + public override Object InitializeLifetimeService() + { + ILease lease = (ILease)base.InitializeLifetimeService(); + + if (lease.CurrentState == LeaseState.Initial) + { + lease.InitialLeaseTime = TimeSpan.FromMinutes(0); +// lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0); +// lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0); + } + return lease; + } + + public Scene World + { + get { return m_ScriptEngine.World; } + } + + internal void MODError(string msg) + { + throw new Exception("MOD Runtime Error: " + msg); + } + + // + //Dumps an error message on the debug console. + // + + internal void MODShoutError(string message) + { + if (message.Length > 1023) + message = message.Substring(0, 1023); + + World.SimChat(Utils.StringToBytes(message), + ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true); + + IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); + wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); + } + + public string modSendCommand(string module, string command, string k) + { + if (!m_MODFunctionsEnabled) + { + MODShoutError("Module command functions not enabled"); + return UUID.Zero.ToString();; + } + + UUID req = UUID.Random(); + + m_comms.RaiseEvent(m_itemID, req.ToString(), module, command, k); + + return req.ToString(); + } + } +} diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 52396b6b2d..3ffcff0806 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -199,7 +199,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api //Dumps an error message on the debug console. // - internal void OSSLShoutError(string message) + internal void OSSLShoutError(string message) { if (message.Length > 1023) message = message.Substring(0, 1023); @@ -384,7 +384,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); if (World.Entities.ContainsKey(target)) { - World.Entities[target].Rotation = rotation; + EntityBase entity; + if (World.Entities.TryGetValue(target, out entity)) + { + if (entity is SceneObjectGroup) + ((SceneObjectGroup)entity).Rotation = rotation; + else if (entity is ScenePresence) + ((ScenePresence)entity).Rotation = rotation; + } } else { @@ -1169,7 +1176,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api land.SetMediaUrl(url); } - + public void osSetParcelSIPAddress(string SIPAddress) { // What actually is the difference to the LL function? @@ -1177,7 +1184,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelMediaURL"); m_host.AddScriptLPS(1); - + ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); @@ -1187,16 +1194,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api 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) + + if (voiceModule != null) voiceModule.setLandSIPAddress(SIPAddress,land.LandData.GlobalID); else OSSLError("osSetParcelSIPAddress: No voice module enabled for this land"); - - + + } public string osGetScriptEngineName() @@ -1476,12 +1483,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); // Create new asset - AssetBase asset = new AssetBase(); - asset.Name = notecardName; + AssetBase asset = new AssetBase(UUID.Random(), notecardName, (sbyte)AssetType.Notecard); asset.Description = "Script Generated Notecard"; - asset.Type = 7; - asset.FullID = UUID.Random(); - string notecardData = ""; + string notecardData = String.Empty; for (int i = 0; i < contents.Length; i++) { notecardData += contents.GetLSLStringItem(i) + "\n"; @@ -1521,10 +1525,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } - /*Instead of using the LSL Dataserver event to pull notecard data, + /*Instead of using the LSL Dataserver event to pull notecard data, this will simply read the requested line and return its data as a string. - - Warning - due to the synchronous method this function uses to fetch assets, its use + + Warning - due to the synchronous method this function uses to fetch assets, its use may be dangerous and unreliable while running in grid mode. */ public string osGetNotecardLine(string name, int line) @@ -1572,10 +1576,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } - /*Instead of using the LSL Dataserver event to pull notecard data line by line, + /*Instead of using the LSL Dataserver event to pull notecard data line by line, this will simply read the entire notecard and return its data as a string. - - Warning - due to the synchronous method this function uses to fetch assets, its use + + Warning - due to the synchronous method this function uses to fetch assets, its use may be dangerous and unreliable while running in grid mode. */ @@ -1630,10 +1634,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } - /*Instead of using the LSL Dataserver event to pull notecard data, + /*Instead of using the LSL Dataserver event to pull notecard data, this will simply read the number of note card lines and return this data as an integer. - - Warning - due to the synchronous method this function uses to fetch assets, its use + + Warning - due to the synchronous method this function uses to fetch assets, its use may be dangerous and unreliable while running in grid mode. */ @@ -1833,7 +1837,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return World.RegionInfo.RegionSettings.LoadedCreationID; } - + // Threat level is 'Low' because certain users could possibly be tricked into // dropping an unverified script into one of their own objects, which could // then gather the physical construction details of the object and transmit it @@ -1857,7 +1861,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, LSL_Key cloneFrom) { CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); - //QueueUserWorkItem + //QueueUserWorkItem INPCModule module = World.RequestModuleInterface(); if (module != null) @@ -1906,5 +1910,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api module.DeleteNPC(new UUID(npc.m_string), World); } } + + /// + /// Get current region's map texture UUID + /// + /// + public LSL_Key osGetMapTexture() + { + CheckThreatLevel(ThreatLevel.None, "osGetMapTexture"); + return m_ScriptEngine.World.RegionInfo.RegionSettings.TerrainImageID.ToString(); + } + + /// + /// Get a region's map texture UUID by region UUID or name. + /// + /// + /// + public LSL_Key osGetRegionMapTexture(string regionName) + { + CheckThreatLevel(ThreatLevel.High, "osGetRegionMapTexture"); + Scene scene = m_ScriptEngine.World; + UUID key = UUID.Zero; + GridRegion region; + + //If string is a key, use it. Otherwise, try to locate region by name. + if (UUID.TryParse(regionName, out key)) + region = scene.GridService.GetRegionByUUID(UUID.Zero, key); + else + region = scene.GridService.GetRegionByName(UUID.Zero, regionName); + + // If region was found, return the regions map texture key. + if (region != null) + key = region.TerrainImage; + + ScriptSleep(1000); + + return key.ToString(); + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs new file mode 100644 index 0000000000..e08eca5b24 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs @@ -0,0 +1,46 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System.Collections; +using OpenSim.Region.ScriptEngine.Interfaces; + +using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; + +namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces +{ + public interface IMOD_Api + { + //Module functions + string modSendCommand(string modules, string command, string k); + } +} diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index d8d3c31dd4..2a403bf0fe 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -79,7 +79,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces // Avatar Info Commands string osGetAgentIP(string agent); - LSL_List osGetAgents(); + LSL_List osGetAgents(); // Teleport commands void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); @@ -127,7 +127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces string osGetScriptEngineName(); string osGetSimulatorVersion(); Hashtable osParseJSON(string JSON); - + void osMessageObject(key objectUUID,string message); void osMakeNotecard(string notecardName, LSL_Types.list contents); @@ -138,7 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces string osAvatarName2Key(string firstname, string lastname); string osKey2Name(string id); - + // Grid Info Functions string osGetGridNick(); string osGetGridName(); @@ -151,7 +151,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces string osLoadedCreationDate(); string osLoadedCreationTime(); string osLoadedCreationID(); - + LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules); @@ -160,5 +160,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osNpcSay(key npc, string message); void osNpcRemove(key npc); + key osGetMapTexture(); + key osGetRegionMapTexture(string regionName); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs new file mode 100644 index 0000000000..6525c7690b --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs @@ -0,0 +1,66 @@ +/* + * 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.Runtime.Remoting.Lifetime; +using System.Threading; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; +using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; +using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; + +namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase +{ + public partial class ScriptBaseClass : MarshalByRefObject + { + public IMOD_Api m_MOD_Functions; + + public void ApiTypeMOD(IScriptApi api) + { + if (!(api is IMOD_Api)) + return; + + m_MOD_Functions = (IMOD_Api)api; + } + + public string modSendCommand(string module, string command, string k) + { + return m_MOD_Functions.modSendCommand(module, command, k); + } + } +} diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 8dcb1f5c02..4928e904b3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -94,7 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_OSSL_Functions.osWindActiveModelPluginName(); } - + // Not yet plugged in as available OSSL functions, so commented out // void osWindParamSet(string plugin, string param, float value) // { @@ -138,14 +138,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public string osSetDynamicTextureURLBlendFace(string dynamicID, string contentType, string url, string extraParams, bool blend, int disp, int timer, int alpha, int face) { - return m_OSSL_Functions.osSetDynamicTextureURLBlendFace(dynamicID, contentType, url, extraParams, + return m_OSSL_Functions.osSetDynamicTextureURLBlendFace(dynamicID, contentType, url, extraParams, blend, disp, timer, alpha, face); } public string osSetDynamicTextureDataBlendFace(string dynamicID, string contentType, string data, string extraParams, bool blend, int disp, int timer, int alpha, int face) { - return m_OSSL_Functions.osSetDynamicTextureDataBlendFace(dynamicID, contentType, data, extraParams, + return m_OSSL_Functions.osSetDynamicTextureDataBlendFace(dynamicID, contentType, data, extraParams, blend, disp, timer, alpha, face); } @@ -183,7 +183,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { m_OSSL_Functions.osSetParcelMediaURL(url); } - + public void osSetParcelSIPAddress(string SIPAddress) { m_OSSL_Functions.osSetParcelSIPAddress(SIPAddress); @@ -211,7 +211,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osTeleportAgent(agent, position, lookat); } - // Avatar info functions + // Avatar info functions public string osGetAgentIP(string agent) { return m_OSSL_Functions.osGetAgentIP(agent); @@ -326,17 +326,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_OSSL_Functions.osGetScriptEngineName(); } - + public string osGetSimulatorVersion() { return m_OSSL_Functions.osGetSimulatorVersion(); } - + public Hashtable osParseJSON(string JSON) { return m_OSSL_Functions.osParseJSON(JSON); } - + public void osMessageObject(key objectUUID,string message) { m_OSSL_Functions.osMessageObject(objectUUID,message); @@ -412,7 +412,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_OSSL_Functions.osLoadedCreationID(); } - + public LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules) { return m_OSSL_Functions.osGetLinkPrimitiveParams(linknumber, rules); @@ -622,5 +622,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase } } } + + public key osGetMapTexture() + { + return m_OSSL_Functions.osGetMapTexture(); + } + + public key osGetRegionMapTexture(string regionName) + { + return m_OSSL_Functions.osGetRegionMapTexture(regionName); + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp index feff86a87e..98bbc68965 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp @@ -20,6 +20,7 @@ + diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index b0fce75112..a60c0bac73 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -51,7 +51,6 @@ using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Region.ScriptEngine.Interfaces; using ScriptCompileQueue = OpenSim.Framework.LocklessQueue; -using Parallel = OpenSim.Framework.Parallel; namespace OpenSim.Region.ScriptEngine.XEngine { @@ -494,7 +493,16 @@ namespace OpenSim.Region.ScriptEngine.XEngine if (m_CurrentCompile == null) { - m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null); + // NOTE: Although we use a lockless queue, the lock here + // is required. It ensures that there are never two + // compile threads running, which, due to a race + // conndition, might otherwise happen + // + lock (m_CompileQueue) + { + if (m_CurrentCompile == null) + m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null); + } } } } @@ -514,16 +522,19 @@ namespace OpenSim.Region.ScriptEngine.XEngine } } - List compiles = new List(); object[] o; while (m_CompileQueue.Dequeue(out o)) + DoOnRezScript(o); + + // NOTE: Despite having a lockless queue, this lock is required + // to make sure there is never no compile thread while there + // are still scripts to compile. This could otherwise happen + // due to a race condition + // + lock (m_CompileQueue) { - compiles.Add(o); + m_CurrentCompile = null; } - - Parallel.For(0, compiles.Count, delegate(int i) { DoOnRezScript(compiles[i]); }); - - m_CurrentCompile = null; m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount, m_ScriptErrorMessage); m_ScriptFailCount = 0; diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs index ecda85a9e3..8e311d70d8 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs @@ -243,7 +243,7 @@ namespace OpenSim.Services.Connectors if (metadata == null) return false; - asset = new AssetBase(); + asset = new AssetBase(metadata.FullID, metadata.Name, metadata.Type); asset.Metadata = metadata; } asset.Data = data; diff --git a/OpenSim/Services/Connectors/Grid/HypergridServiceConnector.cs b/OpenSim/Services/Connectors/Grid/HypergridServiceConnector.cs index 3d7f112cfe..2f33babe95 100644 --- a/OpenSim/Services/Connectors/Grid/HypergridServiceConnector.cs +++ b/OpenSim/Services/Connectors/Grid/HypergridServiceConnector.cs @@ -140,12 +140,11 @@ namespace OpenSim.Services.Connectors.Grid Bitmap m = new Bitmap(info.RegionID.ToString() + ".jpg"); //m_log.Debug("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width); byte[] imageData = OpenJPEG.EncodeFromImage(m, true); - AssetBase ass = new AssetBase(UUID.Random(), "region " + info.RegionID.ToString()); + AssetBase ass = new AssetBase(UUID.Random(), "region " + info.RegionID.ToString(), (sbyte)AssetType.Texture); // !!! for now //info.RegionSettings.TerrainImageID = ass.FullID; - ass.Type = (int)AssetType.Texture; ass.Temporary = true; ass.Local = true; ass.Data = imageData; diff --git a/OpenSim/Services/PresenceService/PresenceService.cs b/OpenSim/Services/PresenceService/PresenceService.cs index 6e59642856..ba8eec866c 100644 --- a/OpenSim/Services/PresenceService/PresenceService.cs +++ b/OpenSim/Services/PresenceService/PresenceService.cs @@ -41,9 +41,9 @@ namespace OpenSim.Services.PresenceService { public class PresenceService : PresenceServiceBase, IPresenceService { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = +// LogManager.GetLogger( +// MethodBase.GetCurrentMethod().DeclaringType); public PresenceService(IConfigSource config) : base(config) diff --git a/OpenSim/Tests/Common/Mock/TestAssetService.cs b/OpenSim/Tests/Common/Mock/MockAssetService.cs similarity index 80% rename from OpenSim/Tests/Common/Mock/TestAssetService.cs rename to OpenSim/Tests/Common/Mock/MockAssetService.cs index 317ec064c9..cb380431d4 100644 --- a/OpenSim/Tests/Common/Mock/TestAssetService.cs +++ b/OpenSim/Tests/Common/Mock/MockAssetService.cs @@ -27,6 +27,8 @@ using System; using System.Collections.Generic; +using System.Reflection; +using log4net; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Data; @@ -35,16 +37,25 @@ using Nini.Config; namespace OpenSim.Tests.Common.Mock { - public class TestAssetService : IAssetService + public class MockAssetService : IAssetService { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private readonly Dictionary Assets = new Dictionary(); - public TestAssetService(IConfigSource config) - { - } + public MockAssetService() {} + + /// + /// This constructor is required if the asset service is being created reflectively (which is the case in some + /// tests). + /// + /// + public MockAssetService(IConfigSource config) {} public AssetBase Get(string id) { + m_log.DebugFormat("[MOCK ASSET SERVICE]: Getting asset with id {0}", id); + AssetBase asset; if (Assets.ContainsKey(id)) asset = Assets[id]; @@ -73,6 +84,8 @@ namespace OpenSim.Tests.Common.Mock public string Store(AssetBase asset) { + m_log.DebugFormat("[MOCK ASSET SERVICE]: Storing asset {0}", asset.ID); + Assets[asset.ID] = asset; return asset.ID; diff --git a/OpenSim/Tests/Common/Mock/TestInventoryService.cs b/OpenSim/Tests/Common/Mock/MockInventoryService.cs similarity index 97% rename from OpenSim/Tests/Common/Mock/TestInventoryService.cs rename to OpenSim/Tests/Common/Mock/MockInventoryService.cs index 5a0ee7ca65..1ea4bc1059 100644 --- a/OpenSim/Tests/Common/Mock/TestInventoryService.cs +++ b/OpenSim/Tests/Common/Mock/MockInventoryService.cs @@ -35,13 +35,13 @@ using Nini.Config; namespace OpenSim.Tests.Common.Mock { - public class TestInventoryService : IInventoryService + public class MockInventoryService : IInventoryService { - public TestInventoryService() + public MockInventoryService() { } - public TestInventoryService(IConfigSource config) + public MockInventoryService(IConfigSource config) { } diff --git a/OpenSim/Tests/Common/Mock/MockUserService.cs b/OpenSim/Tests/Common/Mock/MockUserService.cs new file mode 100644 index 0000000000..1e27fb744a --- /dev/null +++ b/OpenSim/Tests/Common/Mock/MockUserService.cs @@ -0,0 +1,123 @@ + +using System; +using System.Collections.Generic; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Communications.Cache; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Tests.Common +{ + public class MockUserService : IUserService + { + public void AddTemporaryUserProfile(UserProfileData userProfile) + { + throw new NotImplementedException(); + } + + public UserProfileData GetUserProfile(string firstName, string lastName) + { + throw new NotImplementedException(); + } + + public UserProfileData GetUserProfile(UUID userId) + { + throw new NotImplementedException(); + } + + public UserProfileData GetUserProfile(Uri uri) + { + UserProfileData userProfile = new UserProfileData(); + +// userProfile.ID = new UUID(Util.GetHashGuid(uri.ToString(), AssetCache.AssetInfo.Secret)); + + return userProfile; + } + + public Uri GetUserUri(UserProfileData userProfile) + { + throw new NotImplementedException(); + } + + public UserAgentData GetAgentByUUID(UUID userId) + { + throw new NotImplementedException(); + } + + public void ClearUserAgent(UUID avatarID) + { + throw new NotImplementedException(); + } + + public List GenerateAgentPickerRequestResponse(UUID QueryID, string Query) + { + throw new NotImplementedException(); + } + + public UserProfileData SetupMasterUser(string firstName, string lastName) + { + throw new NotImplementedException(); + } + + public UserProfileData SetupMasterUser(string firstName, string lastName, string password) + { + throw new NotImplementedException(); + } + + public UserProfileData SetupMasterUser(UUID userId) + { + throw new NotImplementedException(); + } + + public bool UpdateUserProfile(UserProfileData data) + { + throw new NotImplementedException(); + } + + public void AddNewUserFriend(UUID friendlistowner, UUID friend, uint perms) + { + throw new NotImplementedException(); + } + + public void RemoveUserFriend(UUID friendlistowner, UUID friend) + { + throw new NotImplementedException(); + } + + public void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms) + { + throw new NotImplementedException(); + } + + public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, Vector3 position, Vector3 lookat) + { + throw new NotImplementedException(); + } + + public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, float posx, float posy, float posz) + { + throw new NotImplementedException(); + } + + public List GetUserFriendList(UUID friendlistowner) + { + throw new NotImplementedException(); + } + + public bool VerifySession(UUID userID, UUID sessionID) + { + return true; + } + + public void SetInventoryService(IInventoryService inv) + { + throw new NotImplementedException(); + } + + public virtual bool AuthenticateUserByPassword(UUID userID, string password) + { + throw new NotImplementedException(); + } + } +} diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 0f642b945f..27025d9959 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -191,6 +191,7 @@ namespace OpenSim.Tests.Common.Mock public event FriendActionDelegate OnApproveFriendRequest; public event FriendActionDelegate OnDenyFriendRequest; public event FriendshipTermination OnTerminateFriendship; + public event GrantUserFriendRights OnGrantUserRights; public event EconomyDataRequest OnEconomyDataRequest; public event MoneyBalanceRequest OnMoneyBalanceRequest; @@ -631,6 +632,7 @@ namespace OpenSim.Tests.Common.Mock public virtual void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List items, List folders, + int version, bool fetchFolders, bool fetchItems) { diff --git a/OpenSim/Tests/Common/Setup/AssetHelpers.cs b/OpenSim/Tests/Common/Setup/AssetHelpers.cs new file mode 100644 index 0000000000..df69cd9e8b --- /dev/null +++ b/OpenSim/Tests/Common/Setup/AssetHelpers.cs @@ -0,0 +1,64 @@ +/* + * 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.Text; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Serialization; + +namespace OpenSim.Tests.Common +{ + public class AssetHelpers + { + /// + /// Create an asset from the given data + /// + /// + /// + /// + public static AssetBase CreateAsset(UUID assetUuid, string data) + { + AssetBase asset = new AssetBase(assetUuid, assetUuid.ToString(), (sbyte)AssetType.Object); + asset.Data = Encoding.ASCII.GetBytes(data); + return asset; + } + + /// + /// Create an asset from the given scene object + /// + /// + /// + /// + public static AssetBase CreateAsset(UUID assetUuid, SceneObjectGroup sog) + { + AssetBase asset = new AssetBase(assetUuid, assetUuid.ToString(), (sbyte)AssetType.Object); + asset.Data = Encoding.ASCII.GetBytes(SceneObjectSerializer.ToXml2Format(sog)); + return asset; + } + } +} diff --git a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs index eab5422015..8b18d07fb8 100644 --- a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs +++ b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs @@ -219,7 +219,7 @@ namespace OpenSim.Tests.Common.Setup if (real) config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService"); else - config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Tests.Common.dll:TestAssetService"); + config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Tests.Common.dll:MockAssetService"); config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll"); assetService.Initialise(config); assetService.AddRegion(testScene); @@ -238,7 +238,7 @@ namespace OpenSim.Tests.Common.Setup if (real) config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Services.InventoryService.dll:InventoryService"); else - config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Tests.Common.dll:TestInventoryService"); + config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Tests.Common.dll:MockInventoryService"); config.Configs["InventoryService"].Set("StorageProvider", "OpenSim.Tests.Common.dll"); inventoryService.Initialise(config); inventoryService.AddRegion(testScene); diff --git a/OpenSim/Tests/Common/Setup/UserProfileTestUtils.cs b/OpenSim/Tests/Common/Setup/UserProfileTestUtils.cs index 3ca44a12d1..1b06a46747 100644 --- a/OpenSim/Tests/Common/Setup/UserProfileTestUtils.cs +++ b/OpenSim/Tests/Common/Setup/UserProfileTestUtils.cs @@ -84,15 +84,35 @@ namespace OpenSim.Tests.Common.Setup public static CachedUserInfo CreateUserWithInventory( CommunicationsManager commsManager, string firstName, string lastName, UUID userId, OnInventoryReceivedDelegate callback) + { + return CreateUserWithInventory(commsManager, firstName, lastName, "troll", userId, callback); + } + + /// + /// Create a test user with a standard inventory + /// + /// + /// First name of user + /// Last name of user + /// Password + /// User ID + /// + /// Callback to invoke when inventory has been loaded. This is required because + /// loading may be asynchronous, even on standalone + /// + /// + public static CachedUserInfo CreateUserWithInventory( + CommunicationsManager commsManager, string firstName, string lastName, string password, + UUID userId, OnInventoryReceivedDelegate callback) { LocalUserServices lus = (LocalUserServices)commsManager.UserService; - lus.AddUser(firstName, lastName, "troll", "bill@bailey.com", 1000, 1000, userId); + lus.AddUser(firstName, lastName, password, "bill@bailey.com", 1000, 1000, userId); CachedUserInfo userInfo = commsManager.UserProfileCacheService.GetUserDetails(userId); userInfo.OnInventoryReceived += callback; userInfo.FetchInventory(); return userInfo; - } + } } } diff --git a/OpenSim/Tests/Common/TestHelper.cs b/OpenSim/Tests/Common/TestHelper.cs index 4abf2e3688..9d530635f3 100644 --- a/OpenSim/Tests/Common/TestHelper.cs +++ b/OpenSim/Tests/Common/TestHelper.cs @@ -54,6 +54,7 @@ namespace OpenSim.Tests.Common public static void InMethod() { StackTrace stackTrace = new StackTrace(); + Console.WriteLine(); Console.WriteLine("===> In Test Method : {0} <===", stackTrace.GetFrame(1).GetMethod().Name); } } diff --git a/README.txt b/README.txt index 3a87fe2f9c..d276c6ec19 100644 --- a/README.txt +++ b/README.txt @@ -1,7 +1,5 @@ Welcome to OpenSim! -Version 0.6.x - == OVERVIEW == OpenSim is a BSD Licensed Open Source project to develop a functioning @@ -26,8 +24,8 @@ See configuring OpenSim Prereqs: * Mono >= 2.4.2 - * Nant >= 0.86beta - * sqlite3 or mysql 5.x (you'll need a back end database) + * Nant >= 0.86 beta 1 (if building with the .NET framework on Windows), 0.85 (if building with the mono framework) + * sqlite3 or mysql 5.x (you'll need a backend database) From the distribution type: * ./runprebuild.sh @@ -89,4 +87,3 @@ OpenSim, as well as how to report bugs, and participate in the OpenSim project can always be found at http://opensimulator.org. Thanks for trying OpenSim, we hope it is a pleasant experience. - diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 6606270b00..116a8fd6ac 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -543,7 +543,7 @@ ; specifies if the capsule should be tilted (=true; old compatibility mode) ; or straight up-and-down (=false; better and more consistent physics behavior) - av_capsule_tilted = true + av_capsule_tilted = false ; used to calculate mass of avatar. ; float AVvolume = (float) (Math.PI*Math.Pow(CAPSULE_RADIUS, 2)*CAPSULE_LENGTH); diff --git a/prebuild.xml b/prebuild.xml index 33cb6479bc..047b66d5fd 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -909,7 +909,7 @@ - + ../../../bin/ @@ -1721,6 +1721,48 @@ + + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + + + + + + + + + + + + +