From 88771aeed3d45e60a18aa9a810eeb37b8e5def12 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 9 Mar 2010 23:10:14 +0000 Subject: Cache UserLevel in ScenePresence on SP creation. Change IsAdministrator to use that stored value. --- .../World/Permissions/PermissionsModule.cs | 8 +++++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 28 +++++++++++++++------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 2211f3e..845c4c2 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -490,6 +490,14 @@ namespace OpenSim.Region.CoreModules.World.Permissions if (m_allowGridGods) { + ScenePresence sp = m_scene.GetScenePresence(user); + if (sp != null) + { + if (sp.UserLevel >= 200) + return true; + return false; + } + UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, user); if (account != null) { diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4256be9..7661f1e 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -146,7 +146,8 @@ namespace OpenSim.Region.Framework.Scenes private float m_sitAvatarHeight = 2.0f; - private float m_godlevel; + private int m_godLevel; + private int m_userLevel; private bool m_invulnerable = true; @@ -294,9 +295,14 @@ namespace OpenSim.Region.Framework.Scenes get { return m_invulnerable; } } - public float GodLevel + public int UserLevel { - get { return m_godlevel; } + get { return m_userLevel; } + } + + public int GodLevel + { + get { return m_godLevel; } } public ulong RegionHandle @@ -668,6 +674,10 @@ namespace OpenSim.Region.Framework.Scenes m_regionInfo = reginfo; m_localId = m_scene.AllocateLocalId(); + UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); + + m_userLevel = account.UserLevel; + IGroupsModule gm = m_scene.RequestModuleInterface(); if (gm != null) m_grouptitle = gm.GetGroupTitle(m_uuid); @@ -2967,17 +2977,17 @@ namespace OpenSim.Region.Framework.Scenes if (account != null) { if (account.UserLevel > 0) - m_godlevel = account.UserLevel; + m_godLevel = account.UserLevel; else - m_godlevel = 200; + m_godLevel = 200; } } else { - m_godlevel = 0; + m_godLevel = 0; } - ControllingClient.SendAdminResponse(token, (uint)m_godlevel); + ControllingClient.SendAdminResponse(token, (uint)m_godLevel); } #region Child Agent Updates @@ -3068,7 +3078,7 @@ namespace OpenSim.Region.Framework.Scenes cAgent.ControlFlags = (uint)m_AgentControlFlags; if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) - cAgent.GodLevel = (byte)m_godlevel; + cAgent.GodLevel = (byte)m_godLevel; else cAgent.GodLevel = (byte) 0; @@ -3157,7 +3167,7 @@ namespace OpenSim.Region.Framework.Scenes m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) - m_godlevel = cAgent.GodLevel; + m_godLevel = cAgent.GodLevel; m_setAlwaysRun = cAgent.AlwaysRun; uint i = 0; -- cgit v1.1 From dbb2edf1a67442b5e41da3cd8010574114bba7c2 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 9 Mar 2010 17:09:44 -0800 Subject: Fixed caching of user accounts. --- .../LocalUserAccountServiceConnector.cs | 15 ++++---- .../RemoteUserAccountServiceConnector.cs | 15 ++++---- .../UserAccounts/UserAccountCache.cs | 44 +++++++++++++--------- .../UserAccounts/UserAccountServiceConnector.cs | 1 + .../UserAccountService/UserAccountService.cs | 2 + 5 files changed, 45 insertions(+), 32 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs index 07fee79..ce0ca40 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs @@ -142,26 +142,27 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts public UserAccount GetUserAccount(UUID scopeID, UUID userID) { - UserAccount account = m_Cache.Get(userID); - if (account != null) + bool inCache = false; + UserAccount account = m_Cache.Get(userID, out inCache); + if (inCache) return account; account = m_UserService.GetUserAccount(scopeID, userID); - if (account != null) - m_Cache.Cache(account); + m_Cache.Cache(userID, account); return account; } public UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName) { - UserAccount account = m_Cache.Get(firstName + " " + lastName); - if (account != null) + bool inCache = false; + UserAccount account = m_Cache.Get(firstName + " " + lastName, out inCache); + if (inCache) return account; account = m_UserService.GetUserAccount(scopeID, firstName, lastName); if (account != null) - m_Cache.Cache(account); + m_Cache.Cache(account.PrincipalID, account); return account; } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs index 1140692..488dbd5 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs @@ -119,26 +119,27 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts public override UserAccount GetUserAccount(UUID scopeID, UUID userID) { - UserAccount account = m_Cache.Get(userID); - if (account != null) + bool inCache = false; + UserAccount account = m_Cache.Get(userID, out inCache); + if (inCache) return account; account = base.GetUserAccount(scopeID, userID); - if (account != null) - m_Cache.Cache(account); + m_Cache.Cache(userID, account); return account; } public override UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName) { - UserAccount account = m_Cache.Get(firstName + " " + lastName); - if (account != null) + bool inCache = false; + UserAccount account = m_Cache.Get(firstName + " " + lastName, out inCache); + if (inCache) return account; account = base.GetUserAccount(scopeID, firstName, lastName); if (account != null) - m_Cache.Cache(account); + m_Cache.Cache(account.PrincipalID, account); return account; } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs index e430fc7..a355661 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs @@ -36,50 +36,58 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts { public class UserAccountCache { - //private static readonly ILog m_log = - // LogManager.GetLogger( - // MethodBase.GetCurrentMethod().DeclaringType); - - private ICnmCache m_UUIDCache; - private Dictionary m_NameCache; + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + private ExpiringCache m_UUIDCache; + private ExpiringCache m_NameCache; public UserAccountCache() { // Warning: the size values are a bit fuzzy. What matters // most for this cache is the count value (128 entries). - m_UUIDCache = CnmSynchronizedCache.Synchronized(new CnmMemoryCache( - 128, 128*512, TimeSpan.FromMinutes(30.0))); - m_NameCache = new Dictionary(); // this one is unbound + m_UUIDCache = new ExpiringCache(); + m_NameCache = new ExpiringCache(); // this one is unbound } - public void Cache(UserAccount account) + public void Cache(UUID userID, UserAccount account) { - m_UUIDCache.Set(account.PrincipalID, account, 512); - m_NameCache[account.Name] = account.PrincipalID; + // Cache even null accounts + m_UUIDCache.AddOrUpdate(userID, account, DateTime.Now + TimeSpan.FromMinutes(2.0d)); + if (account != null) + m_NameCache.AddOrUpdate(account.Name, account.PrincipalID, DateTime.Now + TimeSpan.FromMinutes(2.0d)); - //m_log.DebugFormat("[USER CACHE]: cached user {0} {1}", account.FirstName, account.LastName); + m_log.DebugFormat("[USER CACHE]: cached user {0}", userID); } - public UserAccount Get(UUID userID) + public UserAccount Get(UUID userID, out bool inCache) { UserAccount account = null; + inCache = false; if (m_UUIDCache.TryGetValue(userID, out account)) { //m_log.DebugFormat("[USER CACHE]: Account {0} {1} found in cache", account.FirstName, account.LastName); + inCache = true; return account; } return null; } - public UserAccount Get(string name) + public UserAccount Get(string name, out bool inCache) { - if (!m_NameCache.ContainsKey(name)) + inCache = false; + if (!m_NameCache.Contains(name)) return null; UserAccount account = null; - if (m_UUIDCache.TryGetValue(m_NameCache[name], out account)) - return account; + UUID uuid = UUID.Zero; + if (m_NameCache.TryGetValue(name, out uuid)) + if (m_UUIDCache.TryGetValue(uuid, out account)) + { + inCache = true; + return account; + } return null; } diff --git a/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs index 8e7c92b..2f9b520 100644 --- a/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs +++ b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs @@ -113,6 +113,7 @@ namespace OpenSim.Services.Connectors public virtual UserAccount GetUserAccount(UUID scopeID, UUID userID) { + m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUSerAccount {0}", userID); Dictionary sendData = new Dictionary(); //sendData["SCOPEID"] = scopeID.ToString(); sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); diff --git a/OpenSim/Services/UserAccountService/UserAccountService.cs b/OpenSim/Services/UserAccountService/UserAccountService.cs index 82c34e7..38caf74 100644 --- a/OpenSim/Services/UserAccountService/UserAccountService.cs +++ b/OpenSim/Services/UserAccountService/UserAccountService.cs @@ -200,7 +200,9 @@ namespace OpenSim.Services.UserAccountService } if (d.Length < 1) + { return null; + } return MakeUserAccount(d[0]); } -- cgit v1.1 From c5bb51b443267a8bab8dcd28c6674491cae2c01a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 9 Mar 2010 17:33:31 -0800 Subject: Changed a cryptic debug message and a wrong comment --- OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | 2 +- OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index de324c0..128515d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -481,7 +481,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends m_log.DebugFormat("[FRIENDS]: {0} offered friendship to {1}", principalID, friendID); // This user wants to be friends with the other user. - // Let's add both relations to the DB, but one of them is inactive (-1) + // Let's add the relation backwards, in case the other is not online FriendsService.StoreFriend(friendID, principalID.ToString(), 0); // Now let's ask the other user to be friends with this user diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index 83d3449..03da834 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs @@ -334,7 +334,7 @@ namespace OpenSim.Services.Connectors.Hypergrid } catch (Exception e) { - m_log.Debug("[HGrid]: Exception " + e.Message); + m_log.Debug("[USER AGENT CONNECTOR]: Unable to contact remote server "); reason = "Exception: " + e.Message; return false; } -- cgit v1.1 From f58a0394edf3c0e4d46faf1f3053b940ba0a1c8c Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Wed, 10 Mar 2010 13:15:36 +0900 Subject: Formatting cleanup. Add copyright notices. --- OpenSim/Data/IGridUserData.cs | 2 +- OpenSim/Data/MSSQL/MSSQLAvatarData.cs | 2 +- OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs | 6 ++-- OpenSim/Data/MSSQL/MSSQLGridUserData.cs | 4 +-- OpenSim/Data/MSSQL/MSSQLManager.cs | 4 +-- OpenSim/Data/MSSQL/MSSQLUserAccountData.cs | 2 +- OpenSim/Data/MySQL/MySQLGenericTableHandler.cs | 2 +- OpenSim/Data/MySQL/MySQLGridUserData.cs | 2 +- OpenSim/Data/MySQL/MySQLPresenceData.cs | 2 +- OpenSim/Data/Null/NullPresenceData.cs | 16 +++++------ OpenSim/Data/SQLite/SQLiteAuthenticationData.cs | 2 +- OpenSim/Framework/MultipartForm.cs | 29 ++++++++++++++++++- OpenSim/Framework/SLUtil.cs | 33 ++++++++++++++++++++-- OpenSim/Framework/UntrustedWebRequest.cs | 33 ++++++++++++++++++++-- OpenSim/Framework/WebUtil.cs | 29 ++++++++++++++++++- .../Avatar/Attachments/AttachmentsModule.cs | 8 +++--- .../CoreModules/Avatar/Friends/FriendsModule.cs | 4 +-- .../Avatar/InstantMessage/MessageTransferModule.cs | 2 +- .../InventoryAccess/InventoryAccessModule.cs | 2 +- .../Presence/Tests/PresenceConnectorsTests.cs | 4 +-- .../CoreModules/World/Land/LandManagementModule.cs | 10 +++---- .../Region/CoreModules/World/Land/LandObject.cs | 2 +- .../Framework/Interfaces/IAttachmentsModule.cs | 6 ++-- .../Framework/Interfaces/IInventoryAccessModule.cs | 29 ++++++++++++++++++- OpenSim/Region/Framework/Scenes/EventManager.cs | 8 +++--- OpenSim/Region/Framework/Scenes/Scene.cs | 16 +++++------ .../Region/Framework/Scenes/SceneObjectGroup.cs | 6 ++-- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- .../Shared/Api/Implementation/LSL_Api.cs | 2 +- .../Handlers/Hypergrid/UserAgentServerConnector.cs | 29 ++++++++++++++++++- .../Handlers/Inventory/XInventoryInConnector.cs | 2 +- OpenSim/Services/Base/ServiceBase.cs | 2 +- .../GridUser/GridUserServiceConnector.cs | 4 +-- .../Hypergrid/GatekeeperServiceConnector.cs | 29 ++++++++++++++++++- .../Hypergrid/UserAgentServiceConnector.cs | 29 ++++++++++++++++++- .../Connectors/Inventory/XInventoryConnector.cs | 2 +- .../Services/HypergridService/UserAgentService.cs | 29 ++++++++++++++++++- OpenSim/Services/LLLoginService/LLLoginResponse.cs | 2 +- OpenSim/Services/LLLoginService/LLLoginService.cs | 29 ++++++++++++++++++- .../Services/UserAccountService/GridUserService.cs | 2 +- 40 files changed, 349 insertions(+), 79 deletions(-) diff --git a/OpenSim/Data/IGridUserData.cs b/OpenSim/Data/IGridUserData.cs index abd2cef..bd7a435 100644 --- a/OpenSim/Data/IGridUserData.cs +++ b/OpenSim/Data/IGridUserData.cs @@ -44,7 +44,7 @@ namespace OpenSim.Data /// public interface IGridUserData { - GridUserData GetGridUserData(string userID); + GridUserData GetGridUserData(string userID); bool StoreGridUserData(GridUserData data); } } \ No newline at end of file diff --git a/OpenSim/Data/MSSQL/MSSQLAvatarData.cs b/OpenSim/Data/MSSQL/MSSQLAvatarData.cs index 4992183..49a6b09 100644 --- a/OpenSim/Data/MSSQL/MSSQLAvatarData.cs +++ b/OpenSim/Data/MSSQL/MSSQLAvatarData.cs @@ -47,7 +47,7 @@ namespace OpenSim.Data.MSSQL public MSSQLAvatarData(string connectionString, string realm) : base(connectionString, realm, "Avatar") - { + { } public bool Delete(UUID principalID, string name) diff --git a/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs b/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs index 506056d..904366e 100644 --- a/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs +++ b/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs @@ -110,7 +110,7 @@ namespace OpenSim.Data.MSSQL { List constraints = new List(); string query = string.Format(@"SELECT - COL_NAME(ic.object_id,ic.column_id) AS column_name + COL_NAME(ic.object_id,ic.column_id) AS column_name FROM sys.indexes AS i INNER JOIN sys.index_columns AS ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id @@ -157,7 +157,7 @@ namespace OpenSim.Data.MSSQL string where = String.Join(" AND ", terms.ToArray()); string query = String.Format("SELECT * FROM {0} WHERE {1}", - m_Realm, where); + m_Realm, where); cmd.Connection = conn; cmd.CommandText = query; @@ -296,7 +296,7 @@ namespace OpenSim.Data.MSSQL query.AppendFormat("[{0}] = {1} ", names[i], values[i]); if (constraints.Count > 0) { - List terms = new List(); + List terms = new List(); for (int j = 0; j < constraints.Count; j++) { terms.Add(" [" + constraints[j].Key + "] = @" + constraints[j].Key); diff --git a/OpenSim/Data/MSSQL/MSSQLGridUserData.cs b/OpenSim/Data/MSSQL/MSSQLGridUserData.cs index b4a945c..9993720 100644 --- a/OpenSim/Data/MSSQL/MSSQLGridUserData.cs +++ b/OpenSim/Data/MSSQL/MSSQLGridUserData.cs @@ -47,7 +47,7 @@ namespace OpenSim.Data.MSSQL public MSSQLGridUserData(string connectionString, string realm) : base(connectionString, realm, "UserGrid") - { + { } public GridUserData GetGridUserData(string userID) @@ -58,7 +58,7 @@ namespace OpenSim.Data.MSSQL return null; return ret[0]; - } + } public bool StoreGridUserData(GridUserData data) { diff --git a/OpenSim/Data/MSSQL/MSSQLManager.cs b/OpenSim/Data/MSSQL/MSSQLManager.cs index 4309b42..575fd21 100644 --- a/OpenSim/Data/MSSQL/MSSQLManager.cs +++ b/OpenSim/Data/MSSQL/MSSQLManager.cs @@ -46,7 +46,7 @@ namespace OpenSim.Data.MSSQL /// /// Connection string for ADO.net /// - private readonly string connectionString; + private readonly string connectionString; /// /// Initialize the manager and set the connectionstring @@ -196,7 +196,7 @@ namespace OpenSim.Data.MSSQL migration.Update(); } - } + } /// /// Returns the version of this DB provider diff --git a/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs b/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs index 9f18e5e..e7c8dc5 100644 --- a/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs +++ b/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs @@ -43,7 +43,7 @@ namespace OpenSim.Data.MSSQL { } //private string m_Realm; - //private List m_ColumnNames = null; + //private List m_ColumnNames = null; //private MSSQLManager m_database; //public MSSQLUserAccountData(string connectionString, string realm) diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index 756b42d..1253e0b 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs @@ -197,7 +197,7 @@ namespace OpenSim.Data.MySQL public virtual T[] Get(string where) { using (MySqlCommand cmd = new MySqlCommand()) - { + { string query = String.Format("select * from {0} where {1}", m_Realm, where); diff --git a/OpenSim/Data/MySQL/MySQLGridUserData.cs b/OpenSim/Data/MySQL/MySQLGridUserData.cs index 15834d2..df29ecd 100644 --- a/OpenSim/Data/MySQL/MySQLGridUserData.cs +++ b/OpenSim/Data/MySQL/MySQLGridUserData.cs @@ -54,7 +54,7 @@ namespace OpenSim.Data.MySQL return null; return ret[0]; - } + } public bool StoreGridUserData(GridUserData data) { diff --git a/OpenSim/Data/MySQL/MySQLPresenceData.cs b/OpenSim/Data/MySQL/MySQLPresenceData.cs index 68a68af..143dbe3 100644 --- a/OpenSim/Data/MySQL/MySQLPresenceData.cs +++ b/OpenSim/Data/MySQL/MySQLPresenceData.cs @@ -134,7 +134,7 @@ namespace OpenSim.Data.MySQL List deleteSessions = new List(); int online = 0; - while(reader.Read()) + while (reader.Read()) { if (bool.Parse(reader["Online"].ToString())) online++; diff --git a/OpenSim/Data/Null/NullPresenceData.cs b/OpenSim/Data/Null/NullPresenceData.cs index 9fc4595..b98b5c9 100644 --- a/OpenSim/Data/Null/NullPresenceData.cs +++ b/OpenSim/Data/Null/NullPresenceData.cs @@ -55,7 +55,7 @@ namespace OpenSim.Data.Null } public bool Store(PresenceData data) - { + { if (Instance != this) return Instance.Store(data); @@ -113,7 +113,7 @@ namespace OpenSim.Data.Null } public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt) - { + { if (Instance != this) return Instance.SetHomeLocation(userID, regionID, position, lookAt); @@ -130,28 +130,28 @@ namespace OpenSim.Data.Null p.Data["HomePosition"] = position.ToString(); p.Data["HomeLookAt"] = lookAt.ToString(); foundone = true; - } + } } return foundone; } public PresenceData[] Get(string field, string data) - { + { if (Instance != this) return Instance.Get(field, data); // m_log.DebugFormat( -// "[NULL PRESENCE DATA]: Getting presence data for field {0} with parameter {1}", field, data); +// "[NULL PRESENCE DATA]: Getting presence data for field {0} with parameter {1}", field, data); List presences = new List(); if (field == "UserID") { foreach (PresenceData p in m_presenceData.Values) { - if (p.UserID == data) + if (p.UserID == data) { - presences.Add(p); + presences.Add(p); // Console.WriteLine("HOME for " + p.UserID + " is " + (p.Data.ContainsKey("HomeRegionID") ? p.Data["HomeRegionID"] : "Not found")); } } @@ -194,7 +194,7 @@ namespace OpenSim.Data.Null } public void Prune(string userID) - { + { if (Instance != this) { Instance.Prune(userID); diff --git a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs index 84ce775..2c28375 100644 --- a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs +++ b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs @@ -120,7 +120,7 @@ namespace OpenSim.Data.SQLite } public bool Store(AuthenticationData data) - { + { if (data.Data.ContainsKey("UUID")) data.Data.Remove("UUID"); diff --git a/OpenSim/Framework/MultipartForm.cs b/OpenSim/Framework/MultipartForm.cs index 8ba6d22..90c4007 100644 --- a/OpenSim/Framework/MultipartForm.cs +++ b/OpenSim/Framework/MultipartForm.cs @@ -1,4 +1,31 @@ -using System; +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; using System.Collections.Generic; using System.Net; using System.IO; diff --git a/OpenSim/Framework/SLUtil.cs b/OpenSim/Framework/SLUtil.cs index 2fc5bdf..f6d6a7c 100644 --- a/OpenSim/Framework/SLUtil.cs +++ b/OpenSim/Framework/SLUtil.cs @@ -1,4 +1,31 @@ -using System; +/* + * 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.Reflection; using log4net; @@ -219,7 +246,7 @@ namespace OpenSim.Framework /// Parse a notecard in Linden format to a string of ordinary text. /// /// - /// + /// public static string ParseNotecardToString(string rawInput) { string[] output = ParseNotecardToList(rawInput).ToArray(); @@ -237,7 +264,7 @@ namespace OpenSim.Framework /// public static List ParseNotecardToList(string rawInput) { - string[] input = rawInput.Replace("\r", "").Split('\n'); + string[] input = rawInput.Replace("\r", "").Split('\n'); int idx = 0; int level = 0; List output = new List(); diff --git a/OpenSim/Framework/UntrustedWebRequest.cs b/OpenSim/Framework/UntrustedWebRequest.cs index 1af7c41..e6411cc 100644 --- a/OpenSim/Framework/UntrustedWebRequest.cs +++ b/OpenSim/Framework/UntrustedWebRequest.cs @@ -1,4 +1,31 @@ -using System; +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; using System.Collections.Generic; using System.IO; using System.Net; @@ -118,7 +145,7 @@ namespace OpenSim.Framework /// True to allow loopback addresses to be used /// The URI to test for whether it should be allowed. /// - /// true if [is URI allowable] [the specified URI]; otherwise, false. + /// true if [is URI allowable] [the specified URI]; otherwise, false. /// private static bool IsUriAllowable(Uri uri, bool allowLoopback) { @@ -180,7 +207,7 @@ namespace OpenSim.Framework /// /// The ip address to check. /// - /// true if this is a loopback IP address; false otherwise. + /// true if this is a loopback IP address; false otherwise. /// private static bool IsIPv6Loopback(IPAddress ip) { diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index d9782ff..16e44af 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs @@ -1,4 +1,31 @@ -using System; +/* + * 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.Collections.Specialized; using System.IO; diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index d458364..3b7fe88 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -36,7 +36,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.Attachments -{ +{ public class AttachmentsModule : IAttachmentsModule, IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -204,7 +204,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (m_scene.AvatarFactory != null) m_scene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); } - } + } public void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient) { @@ -222,7 +222,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } DetachSingleAttachmentToInv(itemID, remoteClient); - } + } // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? @@ -252,6 +252,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } } - } + } } } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 128515d..312db38 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -394,11 +394,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends public IClientAPI LocateClientObject(UUID agentID) { Scene scene = GetClientScene(agentID); - if(scene == null) + if (scene == null) return null; ScenePresence presence = scene.GetScenePresence(agentID); - if(presence == null) + if (presence == null) return null; return presence.ControllingClient; diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index c0d3f31..ad050a1 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -108,7 +108,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage if (!m_Enabled) return; - lock(m_Scenes) + lock (m_Scenes) { m_Scenes.Remove(scene); } diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 0fc467b..16e05b7 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -576,7 +576,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess foreach (SceneObjectPart part in partList) { if (part.OwnerID != item.Owner) - { + { part.LastOwnerID = part.OwnerID; part.OwnerID = item.Owner; part.Inventory.ChangeInventoryOwner(item.Owner); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs index 292ff8e..63a28fc 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs @@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests m_LocalConnector = new LocalPresenceServicesConnector(config); // Let's stick in a test presence - m_LocalConnector.m_PresenceService.LoginAgent(UUID.Zero.ToString(), UUID.Zero, UUID.Zero); + m_LocalConnector.m_PresenceService.LoginAgent(UUID.Zero.ToString(), UUID.Zero, UUID.Zero); } /// @@ -80,7 +80,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests p.Data = new Dictionary(); p.Data["Online"] = true.ToString(); m_presenceData.Add(UUID.Zero, p); - */ + */ string user1 = UUID.Zero.ToString(); UUID session1 = UUID.Zero; diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 38f371a..1279ac1 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -175,7 +175,7 @@ namespace OpenSim.Region.CoreModules.World.Land void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) { //If we are forcing a position for them to go - if( forcedPosition != null ) + if (forcedPosition != null) { ScenePresence clientAvatar = m_scene.GetScenePresence(remoteClient.AgentId); @@ -191,7 +191,7 @@ namespace OpenSim.Region.CoreModules.World.Land forcedPosition = null; } //if we are far away, teleport - else if(Vector3.Distance(clientAvatar.AbsolutePosition,forcedPosition.Value) > 3 ) + else if (Vector3.Distance(clientAvatar.AbsolutePosition,forcedPosition.Value) > 3) { Debug.WriteLine(string.Format("Teleporting out because {0} is too far from avatar position {1}",forcedPosition.Value,clientAvatar.AbsolutePosition)); clientAvatar.Teleport(forcedPosition.Value); @@ -332,7 +332,7 @@ namespace OpenSim.Region.CoreModules.World.Land public void SendYouAreRestrictedNotice(ScenePresence avatar) { - avatar.ControllingClient.SendAlertMessage( + avatar.ControllingClient.SendAlertMessage( "You are not allowed on this parcel because the land owner has restricted access."); } @@ -467,7 +467,7 @@ namespace OpenSim.Region.CoreModules.World.Land ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar)); } } - else if ( parcel.IsRestrictedFromLand(clientAvatar.UUID)) + else if (parcel.IsRestrictedFromLand(clientAvatar.UUID)) { //once we've sent the message once, keep going toward the target until we are done if (forcedPosition == null) @@ -479,7 +479,7 @@ namespace OpenSim.Region.CoreModules.World.Land else { //when we are finally in a safe place, lets release the forced position lock - forcedPosition = null; + forcedPosition = null; } } } diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 27d9fdb..e85136a 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -287,7 +287,7 @@ namespace OpenSim.Region.CoreModules.World.Land entry.Flags = AccessList.Ban; entry.Time = new DateTime(); //See if they are on the list, but make sure the owner isn't banned - if (LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar ) + if (LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) { //They are banned, so lets send them a notice about this parcel return true; diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 367ff3d..6cf2a2e 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -31,7 +31,7 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.Framework.Interfaces -{ +{ public interface IAttachmentsModule { /// @@ -43,7 +43,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// /// - /// true if the object was successfully attached, false otherwise + /// true if the object was successfully attached, false otherwise bool AttachObject( IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent); @@ -54,7 +54,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// /// - /// + /// UUID SetAttachmentInventoryStatus( SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt); diff --git a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs index 2401402..8185258 100644 --- a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs @@ -1,4 +1,31 @@ -using System; +/* + * 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 OpenSim.Framework; diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index f0d346f..dc9ae19 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -113,15 +113,15 @@ namespace OpenSim.Region.Framework.Scenes /// Fired when an object is touched/grabbed. /// /// The originalID is the local ID of the part that was actually touched. The localID itself is always that of - /// the root part. + /// the root part. public event ObjectGrabDelegate OnObjectGrab; - public delegate void ObjectGrabDelegate(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs); + public delegate void ObjectGrabDelegate(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs); public event ObjectGrabDelegate OnObjectGrabbing; public event ObjectDeGrabDelegate OnObjectDeGrab; public event ScriptResetDelegate OnScriptReset; - public event OnPermissionErrorDelegate OnPermissionError; + public event OnPermissionErrorDelegate OnPermissionError; /// /// Fired when a new script is created. @@ -169,7 +169,7 @@ namespace OpenSim.Region.Framework.Scenes public delegate void ClientClosed(UUID clientID, Scene scene); - public event ClientClosed OnClientClosed; + public event ClientClosed OnClientClosed; /// /// This is fired when a scene object property that a script might be interested in (such as color, scale or diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 311821a..87a753e 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1976,7 +1976,7 @@ namespace OpenSim.Region.Framework.Scenes public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) { return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates); - } + } /// /// Delete every object from the scene @@ -2644,7 +2644,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual void SubscribeToClientAttachmentEvents(IClientAPI client) { client.OnRezSingleAttachmentFromInv += RezSingleAttachment; - client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachments; + client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachments; client.OnObjectAttach += m_sceneGraph.AttachObject; client.OnObjectDetach += m_sceneGraph.DetachObject; @@ -2696,7 +2696,7 @@ namespace OpenSim.Region.Framework.Scenes } protected virtual void UnsubscribeToClientEvents(IClientAPI client) - { + { } /// @@ -2797,13 +2797,13 @@ namespace OpenSim.Region.Framework.Scenes } public virtual void UnSubscribeToClientAttachmentEvents(IClientAPI client) - { + { client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachments; - client.OnRezSingleAttachmentFromInv -= RezSingleAttachment; + client.OnRezSingleAttachmentFromInv -= RezSingleAttachment; client.OnObjectAttach -= m_sceneGraph.AttachObject; client.OnObjectDetach -= m_sceneGraph.DetachObject; - if (AttachmentsModule != null) + if (AttachmentsModule != null) client.OnDetachAttachmentIntoInv -= AttachmentsModule.ShowDetachInUserInventory; } @@ -3526,7 +3526,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (var parcel in AllParcels()) { - if( parcel.ContainsPoint((int)x,(int)y)) + if (parcel.ContainsPoint((int)x,(int)y)) { return parcel; } @@ -4965,7 +4965,7 @@ namespace OpenSim.Region.Framework.Scenes private Vector3 GetPositionAtAvatarHeightOrGroundHeight(ScenePresence avatar, float x, float y) { Vector3 ground = GetPositionAtGround(x, y); - if( avatar.AbsolutePosition.Z > ground.Z) + if (avatar.AbsolutePosition.Z > ground.Z) { ground.Z = avatar.AbsolutePosition.Z; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 37b4fd6..88deedf 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -569,7 +569,7 @@ namespace OpenSim.Region.Framework.Scenes ApplyPhysics(m_scene.m_physicalPrim); // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled - // for the same object with very different properties. The caller must schedule the update. + // for the same object with very different properties. The caller must schedule the update. //ScheduleGroupForFullUpdate(); } @@ -2032,11 +2032,11 @@ namespace OpenSim.Region.Framework.Scenes /// Immediately send a full update for this scene object. /// public void SendGroupFullUpdate() - { + { if (IsDeleted) return; -// m_log.DebugFormat("[SOG]: Sending immediate full group update for {0} {1}", Name, UUID); +// m_log.DebugFormat("[SOG]: Sending immediate full group update for {0} {1}", Name, UUID); RootPart.SendFullUpdateToAllClients(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 4729382..8967252 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2869,7 +2869,7 @@ namespace OpenSim.Region.Framework.Scenes { SendFullUpdateToClient(remoteClient, clientFlags); } - } + } /// /// Send a full update for this part to all clients. diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 59db81e..b040ca77 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4024,7 +4024,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; } - if( message == string.Empty) + if (message == string.Empty) { ShoutError("Trying to use llTextBox with empty message."); } diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs index 79c6b2a..6b1152b 100644 --- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs @@ -1,4 +1,31 @@ -using System; +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; using System.Collections; using System.Collections.Generic; using System.Net; diff --git a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs index f9db859..34f7dcc 100644 --- a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs +++ b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs @@ -289,7 +289,7 @@ namespace OpenSim.Server.Handlers.Asset foreach (InventoryItemBase i in icoll.Items) items[i.ID.ToString()] = EncodeItem(i); result["ITEMS"] = items; - } + } string xmlString = ServerUtils.BuildXmlResponse(result); m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); diff --git a/OpenSim/Services/Base/ServiceBase.cs b/OpenSim/Services/Base/ServiceBase.cs index 91d5c56..ef30cba 100644 --- a/OpenSim/Services/Base/ServiceBase.cs +++ b/OpenSim/Services/Base/ServiceBase.cs @@ -72,7 +72,7 @@ namespace OpenSim.Services.Base // m_log.DebugFormat("[SERVICE BASE]: Found type {0}", pluginType); if (pluginType.IsPublic) - { + { if (className != String.Empty && pluginType.ToString() != pluginType.Namespace + "." + className) diff --git a/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs b/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs index ce88236..0e85067 100644 --- a/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs +++ b/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs @@ -28,9 +28,9 @@ using System; namespace OpenSim.Services.Connectors -{ +{ public class GridUserServiceConnector - { + { public GridUserServiceConnector() { } diff --git a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs index 9f73b38..c426bba 100644 --- a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs @@ -1,4 +1,31 @@ -using System; +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; using System.Collections; using System.Collections.Generic; using System.Drawing; diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index 03da834..3e91e3a 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs @@ -1,4 +1,31 @@ -using System; +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; using System.Collections; using System.Collections.Generic; using System.IO; diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs index 9821dd4..0cc1978 100644 --- a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs +++ b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs @@ -126,7 +126,7 @@ namespace OpenSim.Services.Connectors }); if (ret == null) - return null; + return null; if (ret.Count == 0) return null; diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 15379b5..26f211b 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -1,4 +1,31 @@ -using System; +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; using System.Collections.Generic; using System.Net; using System.Reflection; diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs index 05f5b4c..1a59213 100644 --- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs +++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs @@ -623,7 +623,7 @@ namespace OpenSim.Services.LLLoginService } private InventoryData GetInventorySkeleton(List folders) - { + { UUID rootID = UUID.Zero; ArrayList AgentInventoryArray = new ArrayList(); Hashtable TempHash; diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index ae729f8..1578873 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -1,4 +1,31 @@ -using System; +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; using System.Collections.Generic; using System.Net; using System.Reflection; diff --git a/OpenSim/Services/UserAccountService/GridUserService.cs b/OpenSim/Services/UserAccountService/GridUserService.cs index 36cce75..c6e33bb 100644 --- a/OpenSim/Services/UserAccountService/GridUserService.cs +++ b/OpenSim/Services/UserAccountService/GridUserService.cs @@ -58,7 +58,7 @@ namespace OpenSim.Services.UserAccountService info.HomePosition = Vector3.Parse(d.Data["HomePosition"]); info.HomeLookAt = Vector3.Parse(d.Data["HomeLookAt"]); - return info; + return info; } public bool StoreGridUserInfo(GridUserInfo info) -- cgit v1.1 From 04a6b1caf8033a413efce7db4cda4de4bf935a01 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 10 Mar 2010 05:31:34 +0000 Subject: Reintroduce a check that was dropped from permissions --- OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 845c4c2..5c7f3b7 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -618,7 +618,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions return objectOwnerMask; // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set - if (IsEstateManager(user) && m_RegionOwnerIsGod) + if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner)) return objectOwnerMask; // Admin should be able to edit anything in the sim (including admin objects) -- cgit v1.1 From 2af97b46ecc96a58028e53045efffd75c07ec857 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Wed, 10 Mar 2010 14:05:49 -0800 Subject: * Cleaned up and commented the messy SendInventoryUpdate, fixed a broken debug line, and commented the debug line out since it can quickly become noisy --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index dad0efd..7277527 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1102,18 +1102,18 @@ namespace OpenSim.Region.Framework.Scenes if (folder == null) return; - m_log.DebugFormat("[AGENT INVENTORY]: Send Inventory Folder {0} Update to {1} {2}", folder.Name, client.FirstName, client.LastName); + // Fetch the folder contents InventoryCollection contents = InventoryService.GetFolderContent(client.AgentId, folder.ID); - InventoryFolderBase containingFolder = new InventoryFolderBase(); - containingFolder.ID = folder.ID; - containingFolder.Owner = client.AgentId; + + // Fetch the folder itself to get its current version + InventoryFolderBase containingFolder = new InventoryFolderBase(folder.ID, client.AgentId); containingFolder = InventoryService.GetFolder(containingFolder); - if (containingFolder != null) - { - int version = containingFolder.Version; - client.SendInventoryFolderDetails(client.AgentId, folder.ID, contents.Items, contents.Folders, version, fetchFolders, fetchItems); - } + //m_log.DebugFormat("[AGENT INVENTORY]: Sending inventory folder contents ({0} nodes) for \"{1}\" to {2} {3}", + // contents.Folders.Count + contents.Items.Count, containingFolder.Name, client.FirstName, client.LastName); + + if (containingFolder != null) + client.SendInventoryFolderDetails(client.AgentId, folder.ID, contents.Items, contents.Folders, containingFolder.Version, fetchFolders, fetchItems); } /// -- cgit v1.1 From 265c24ec33f53681e6b03684d9c453d0b1e91ce5 Mon Sep 17 00:00:00 2001 From: Mikko Pallari Date: Wed, 10 Mar 2010 14:44:53 +0200 Subject: Changed some properties and methods from private to protected in LLLoginResponse and LLLoginService so they could be inherited better. --- OpenSim/Services/LLLoginService/LLLoginResponse.cs | 6 +++--- OpenSim/Services/LLLoginService/LLLoginService.cs | 24 +++++++++++----------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs index 1a59213..ee30fa3 100644 --- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs +++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs @@ -47,9 +47,9 @@ namespace OpenSim.Services.LLLoginService { public class LLFailedLoginResponse : OpenSim.Services.Interfaces.FailedLoginResponse { - string m_key; - string m_value; - string m_login; + protected string m_key; + protected string m_value; + protected string m_login; public static LLFailedLoginResponse UserProblem; public static LLFailedLoginResponse AuthorizationProblem; diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 1578873..1eaf4d4 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -51,24 +51,24 @@ namespace OpenSim.Services.LLLoginService private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static bool Initialized = false; - private IUserAccountService m_UserAccountService; - private IAuthenticationService m_AuthenticationService; - private IInventoryService m_InventoryService; - private IGridService m_GridService; - private IPresenceService m_PresenceService; + protected IUserAccountService m_UserAccountService; + protected IAuthenticationService m_AuthenticationService; + protected IInventoryService m_InventoryService; + protected IGridService m_GridService; + protected IPresenceService m_PresenceService; private ISimulationService m_LocalSimulationService; private ISimulationService m_RemoteSimulationService; - private ILibraryService m_LibraryService; - private IFriendsService m_FriendsService; - private IAvatarService m_AvatarService; + protected ILibraryService m_LibraryService; + protected IFriendsService m_FriendsService; + protected IAvatarService m_AvatarService; private IUserAgentService m_UserAgentService; private GatekeeperServiceConnector m_GatekeeperConnector; private string m_DefaultRegionName; - private string m_WelcomeMessage; + protected string m_WelcomeMessage; private bool m_RequireInventory; - private int m_MinLoginLevel; + protected int m_MinLoginLevel; private string m_GatekeeperURL; IConfig m_LoginServerConfig; @@ -286,7 +286,7 @@ namespace OpenSim.Services.LLLoginService } } - private GridRegion FindDestination(UserAccount account, PresenceInfo pinfo, UUID sessionID, string startLocation, out GridRegion gatekeeper, out string where, out Vector3 position, out Vector3 lookAt) + protected GridRegion FindDestination(UserAccount account, PresenceInfo pinfo, UUID sessionID, string startLocation, out GridRegion gatekeeper, out string where, out Vector3 position, out Vector3 lookAt) { m_log.DebugFormat("[LLOGIN SERVICE]: FindDestination for start location {0}", startLocation); @@ -497,7 +497,7 @@ namespace OpenSim.Services.LLLoginService } } - private AgentCircuitData LaunchAgentAtGrid(GridRegion gatekeeper, GridRegion destination, UserAccount account, AvatarData avatar, + protected AgentCircuitData LaunchAgentAtGrid(GridRegion gatekeeper, GridRegion destination, UserAccount account, AvatarData avatar, UUID session, UUID secureSession, Vector3 position, string currentWhere, out string where, out string reason) { where = currentWhere; -- cgit v1.1 From 20406498711d1f26037ae32e1b7f8378b01ad848 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 11 Mar 2010 10:05:03 -0800 Subject: Adding the SimianGrid connectors --- .../SimianGrid/SimianAssetServiceConnector.cs | 407 ++++++++++ .../SimianAuthenticationServiceConnector.cs | 198 +++++ .../SimianGrid/SimianAvatarServiceConnector.cs | 259 ++++++ .../SimianGrid/SimianFriendsServiceConnector.cs | 229 ++++++ .../Services/Connectors/SimianGrid/SimianGrid.cs | 31 + .../SimianGrid/SimianGridServiceConnector.cs | 418 ++++++++++ .../SimianGrid/SimianInventoryServiceConnector.cs | 880 +++++++++++++++++++++ .../SimianGrid/SimianPresenceServiceConnector.cs | 502 ++++++++++++ .../Connectors/SimianGrid/SimianProfiles.cs | 432 ++++++++++ .../SimianUserAccountServiceConnector.cs | 307 +++++++ bin/OpenSim.ini.example | 1 + bin/config-include/SimianGrid.ini | 70 ++ prebuild.xml | 2 + 13 files changed, 3736 insertions(+) create mode 100644 OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs create mode 100644 OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs create mode 100644 OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs create mode 100644 OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs create mode 100644 bin/config-include/SimianGrid.ini diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs new file mode 100644 index 0000000..9fb7723 --- /dev/null +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs @@ -0,0 +1,407 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Reflection; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Services.Connectors.SimianGrid +{ + /// + /// Connects to the SimianGrid asset service + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SimianAssetServiceConnector : IAssetService, ISharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + private static string ZeroID = UUID.Zero.ToString(); + + private string m_serverUrl = String.Empty; + private IImprovedAssetCache m_cache; + + #region ISharedRegionModule + + public Type ReplaceableInterface { get { return null; } } + public void RegionLoaded(Scene scene) + { + if (m_cache == null) + { + IImprovedAssetCache cache = scene.RequestModuleInterface(); + if (cache is ISharedRegionModule) + m_cache = cache; + } + } + public void PostInitialise() { } + public void Close() { } + + public SimianAssetServiceConnector() { } + public string Name { get { return "SimianAssetServiceConnector"; } } + public void AddRegion(Scene scene) { scene.RegisterModuleInterface(this); } + public void RemoveRegion(Scene scene) { scene.UnregisterModuleInterface(this); } + + #endregion ISharedRegionModule + + public SimianAssetServiceConnector(IConfigSource source) + { + Initialise(source); + } + + public void Initialise(IConfigSource source) + { + IConfig gridConfig = source.Configs["AssetService"]; + if (gridConfig == null) + { + m_log.Error("[ASSET CONNECTOR]: AssetService missing from OpenSim.ini"); + throw new Exception("Asset connector init error"); + } + + string serviceUrl = gridConfig.GetString("AssetServerURI"); + if (String.IsNullOrEmpty(serviceUrl)) + { + m_log.Error("[ASSET CONNECTOR]: No AssetServerURI in section AssetService"); + throw new Exception("Asset connector init error"); + } + + if (!serviceUrl.EndsWith("/")) + serviceUrl = serviceUrl + '/'; + + m_serverUrl = serviceUrl; + } + + #region IAssetService + + public AssetBase Get(string id) + { + AssetBase asset = null; + + // Cache fetch + if (m_cache != null) + { + asset = m_cache.Get(id); + if (asset != null) + return asset; + } + + Uri url; + + // Determine if id is an absolute URL or a grid-relative UUID + if (!Uri.TryCreate(id, UriKind.Absolute, out url)) + url = new Uri(m_serverUrl + id); + + try + { + HttpWebRequest request = UntrustedHttpWebRequest.Create(url); + + using (WebResponse response = request.GetResponse()) + { + using (Stream responseStream = response.GetResponseStream()) + { + string creatorID = response.Headers.GetOne("X-Asset-Creator-Id") ?? String.Empty; + + // Create the asset object + asset = new AssetBase(id, String.Empty, SLUtil.ContentTypeToSLAssetType(response.ContentType), creatorID); + + UUID assetID; + if (UUID.TryParse(id, out assetID)) + asset.FullID = assetID; + + // Grab the asset data from the response stream + using (MemoryStream stream = new MemoryStream()) + { + responseStream.CopyTo(stream, Int32.MaxValue); + asset.Data = stream.ToArray(); + } + } + } + + // Cache store + if (m_cache != null && asset != null) + m_cache.Cache(asset); + + return asset; + } + catch (Exception ex) + { + m_log.Warn("[ASSET CONNECTOR]: Asset GET from " + url + " failed: " + ex.Message); + return null; + } + } + + /// + /// Get an asset's metadata + /// + /// + /// + public AssetMetadata GetMetadata(string id) + { + AssetMetadata metadata = null; + + // Cache fetch + if (m_cache != null) + { + AssetBase asset = m_cache.Get(id); + if (asset != null) + return asset.Metadata; + } + + Uri url; + + // Determine if id is an absolute URL or a grid-relative UUID + if (!Uri.TryCreate(id, UriKind.Absolute, out url)) + url = new Uri(m_serverUrl + id); + + try + { + HttpWebRequest request = UntrustedHttpWebRequest.Create(url); + request.Method = "HEAD"; + + using (WebResponse response = request.GetResponse()) + { + using (Stream responseStream = response.GetResponseStream()) + { + // Create the metadata object + metadata = new AssetMetadata(); + metadata.ContentType = response.ContentType; + metadata.ID = id; + + UUID uuid; + if (UUID.TryParse(id, out uuid)) + metadata.FullID = uuid; + + string lastModifiedStr = response.Headers.Get("Last-Modified"); + if (!String.IsNullOrEmpty(lastModifiedStr)) + { + DateTime lastModified; + if (DateTime.TryParse(lastModifiedStr, out lastModified)) + metadata.CreationDate = lastModified; + } + } + } + } + catch (Exception ex) + { + m_log.Warn("[ASSET CONNECTOR]: Asset GET from " + url + " failed: " + ex.Message); + } + + return metadata; + } + + public byte[] GetData(string id) + { + AssetBase asset = Get(id); + + if (asset != null) + return asset.Data; + + return null; + } + + /// + /// Get an asset asynchronously + /// + /// The asset id + /// Represents the requester. Passed back via the handler + /// The handler to call back once the asset has been retrieved + /// True if the id was parseable, false otherwise + public bool Get(string id, Object sender, AssetRetrieved handler) + { + Util.FireAndForget( + delegate(object o) + { + AssetBase asset = Get(id); + handler(id, sender, asset); + } + ); + + return true; + } + + /// + /// Creates a new asset + /// + /// Returns a random ID if none is passed into it + /// + /// + public string Store(AssetBase asset) + { + bool storedInCache = false; + string errorMessage = null; + + // AssetID handling + if (String.IsNullOrEmpty(asset.ID) || asset.ID == ZeroID) + { + asset.FullID = UUID.Random(); + asset.ID = asset.FullID.ToString(); + } + + // Cache handling + if (m_cache != null) + { + m_cache.Cache(asset); + storedInCache = true; + } + + // Local asset handling + if (asset.Local) + { + if (!storedInCache) + { + m_log.Error("Cannot store local " + asset.Metadata.ContentType + " asset without an asset cache"); + asset.ID = null; + asset.FullID = UUID.Zero; + } + + return asset.ID; + } + + // Distinguish public and private assets + bool isPublic = true; + switch ((AssetType)asset.Type) + { + case AssetType.CallingCard: + case AssetType.Gesture: + case AssetType.LSLBytecode: + case AssetType.LSLText: + isPublic = false; + break; + } + + // Make sure ContentType is set + if (String.IsNullOrEmpty(asset.Metadata.ContentType)) + asset.Metadata.ContentType = SLUtil.SLAssetTypeToContentType(asset.Type); + + // Build the remote storage request + List postParameters = new List() + { + new MultipartForm.Parameter("AssetID", asset.FullID.ToString()), + new MultipartForm.Parameter("CreatorID", asset.Metadata.CreatorID), + new MultipartForm.Parameter("Temporary", asset.Temporary ? "1" : "0"), + new MultipartForm.Parameter("Public", isPublic ? "1" : "0"), + new MultipartForm.File("Asset", asset.Name, asset.Metadata.ContentType, asset.Data) + }; + + // Make the remote storage request + try + { + HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl); + + HttpWebResponse response = MultipartForm.Post(request, postParameters); + using (Stream responseStream = response.GetResponseStream()) + { + try + { + string responseStr = responseStream.GetStreamString(); + OSD responseOSD = OSDParser.Deserialize(responseStr); + if (responseOSD.Type == OSDType.Map) + { + OSDMap responseMap = (OSDMap)responseOSD; + if (responseMap["Success"].AsBoolean()) + return asset.ID; + else + errorMessage = "Upload failed: " + responseMap["Message"].AsString(); + } + else + { + errorMessage = "Response format was invalid."; + } + } + catch + { + errorMessage = "Failed to parse the response."; + } + } + } + catch (WebException ex) + { + errorMessage = ex.Message; + } + + m_log.WarnFormat("[ASSET CONNECTOR]: Failed to store asset \"{0}\" ({1}, {2}): {3}", + asset.Name, asset.ID, asset.Metadata.ContentType, errorMessage); + return null; + } + + /// + /// Update an asset's content + /// + /// Attachments and bare scripts need this!! + /// + /// + /// + public bool UpdateContent(string id, byte[] data) + { + AssetBase asset = Get(id); + + if (asset == null) + { + m_log.Warn("[ASSET CONNECTOR]: Failed to fetch asset " + id + " for updating"); + return false; + } + + asset.Data = data; + + string result = Store(asset); + return !String.IsNullOrEmpty(result); + } + + /// + /// Delete an asset + /// + /// + /// + public bool Delete(string id) + { + if (m_cache != null) + m_cache.Expire(id); + + string url = m_serverUrl + id; + + OSDMap response = WebUtil.ServiceRequest(url, "DELETE"); + if (response["Success"].AsBoolean()) + return true; + else + m_log.Warn("[ASSET CONNECTOR]: Failed to delete asset " + id + " from the asset service"); + + return false; + } + + #endregion IAssetService + } +} diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs new file mode 100644 index 0000000..ec66341 --- /dev/null +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs @@ -0,0 +1,198 @@ +/* + * 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.Specialized; +using System.Reflection; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Services.Connectors.SimianGrid +{ + /// + /// Connects authentication/authorization to the SimianGrid backend + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SimianAuthenticationServiceConnector : IAuthenticationService, ISharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_serverUrl = String.Empty; + + #region ISharedRegionModule + + public Type ReplaceableInterface { get { return null; } } + public void RegionLoaded(Scene scene) { } + public void PostInitialise() { } + public void Close() { } + + public SimianAuthenticationServiceConnector() { } + public string Name { get { return "SimianAuthenticationServiceConnector"; } } + public void AddRegion(Scene scene) { scene.RegisterModuleInterface(this); } + public void RemoveRegion(Scene scene) { scene.UnregisterModuleInterface(this); } + + #endregion ISharedRegionModule + + public SimianAuthenticationServiceConnector(IConfigSource source) + { + Initialise(source); + } + + public void Initialise(IConfigSource source) + { + IConfig assetConfig = source.Configs["AuthenticationService"]; + if (assetConfig == null) + { + m_log.Error("[AUTH CONNECTOR]: AuthenticationService missing from OpenSim.ini"); + throw new Exception("Authentication connector init error"); + } + + string serviceURI = assetConfig.GetString("AuthenticationServerURI"); + if (String.IsNullOrEmpty(serviceURI)) + { + m_log.Error("[AUTH CONNECTOR]: No Server URI named in section AuthenticationService"); + throw new Exception("Authentication connector init error"); + } + + m_serverUrl = serviceURI; + } + + public string Authenticate(UUID principalID, string password, int lifetime) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetIdentities" }, + { "UserID", principalID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Identities"] is OSDArray) + { + OSDArray identities = (OSDArray)response["Identities"]; + for (int i = 0; i < identities.Count; i++) + { + OSDMap identity = identities[i] as OSDMap; + if (identity != null) + { + if (identity["Type"].AsString() == "md5hash") + { + string credential = identity["Credential"].AsString(); + + if (password == credential || Utils.MD5String(password) == credential) + return Authorize(principalID); + } + } + } + + m_log.Warn("[AUTH CONNECTOR]: Authentication failed for " + principalID); + } + else + { + m_log.Warn("[AUTH CONNECTOR]: Failed to retrieve identities for " + principalID + ": " + + response["Message"].AsString()); + } + + return String.Empty; + } + + public bool Verify(UUID principalID, string token, int lifetime) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetSession" }, + { "SessionID", token } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean()) + { + return true; + } + else + { + m_log.Warn("[AUTH CONNECTOR]: Could not verify session for " + principalID + ": " + + response["Message"].AsString()); + } + + return false; + } + + public bool Release(UUID principalID, string token) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "RemoveSession" }, + { "UserID", principalID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean()) + { + return true; + } + else + { + m_log.Warn("[AUTH CONNECTOR]: Failed to remove session for " + principalID + ": " + + response["Message"].AsString()); + } + + return false; + } + + public bool SetPassword(UUID principalID, string passwd) + { + // TODO: Use GetIdentities to find the md5hash identity for principalID + // and then update it with AddIdentity + m_log.Error("[AUTH CONNECTOR]: Changing passwords is not implemented yet"); + return false; + } + + private string Authorize(UUID userID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddSession" }, + { "UserID", userID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean()) + return response["SessionID"].AsUUID().ToString(); + else + return String.Empty; + } + } +} diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs new file mode 100644 index 0000000..220f143 --- /dev/null +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs @@ -0,0 +1,259 @@ +/* + * 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.Collections.Specialized; +using System.IO; +using System.Net; +using System.Reflection; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Services.Connectors.SimianGrid +{ + /// + /// Connects avatar appearance data to the SimianGrid backend + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SimianAvatarServiceConnector : IAvatarService, ISharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + private static string ZeroID = UUID.Zero.ToString(); + + private string m_serverUrl = String.Empty; + + #region ISharedRegionModule + + public Type ReplaceableInterface { get { return null; } } + public void RegionLoaded(Scene scene) { } + public void PostInitialise() { } + public void Close() { } + + public SimianAvatarServiceConnector() { } + public string Name { get { return "SimianAvatarServiceConnector"; } } + public void AddRegion(Scene scene) { scene.RegisterModuleInterface(this); } + public void RemoveRegion(Scene scene) { scene.UnregisterModuleInterface(this); } + + #endregion ISharedRegionModule + + public SimianAvatarServiceConnector(IConfigSource source) + { + Initialise(source); + } + + public void Initialise(IConfigSource source) + { + IConfig gridConfig = source.Configs["AvatarService"]; + if (gridConfig == null) + { + m_log.Error("[AVATAR CONNECTOR]: AvatarService missing from OpenSim.ini"); + throw new Exception("Avatar connector init error"); + } + + string serviceUrl = gridConfig.GetString("AvatarServerURI"); + if (String.IsNullOrEmpty(serviceUrl)) + { + m_log.Error("[AVATAR CONNECTOR]: No AvatarServerURI in section AvatarService"); + throw new Exception("Avatar connector init error"); + } + + if (!serviceUrl.EndsWith("/")) + serviceUrl = serviceUrl + '/'; + + m_serverUrl = serviceUrl; + } + + #region IAvatarService + + public AvatarData GetAvatar(UUID userID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetUser" }, + { "UserID", userID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean()) + { + OSDMap map = null; + try { map = OSDParser.DeserializeJson(response["LLAppearance"].AsString()) as OSDMap; } + catch { } + + if (map != null) + { + AvatarWearable[] wearables = new AvatarWearable[13]; + wearables[0] = new AvatarWearable(map["ShapeItem"].AsUUID(), map["ShapeAsset"].AsUUID()); + wearables[1] = new AvatarWearable(map["SkinItem"].AsUUID(), map["SkinAsset"].AsUUID()); + wearables[2] = new AvatarWearable(map["HairItem"].AsUUID(), map["HairAsset"].AsUUID()); + wearables[3] = new AvatarWearable(map["EyesItem"].AsUUID(), map["EyesAsset"].AsUUID()); + wearables[4] = new AvatarWearable(map["ShirtItem"].AsUUID(), map["ShirtAsset"].AsUUID()); + wearables[5] = new AvatarWearable(map["PantsItem"].AsUUID(), map["PantsAsset"].AsUUID()); + wearables[6] = new AvatarWearable(map["ShoesItem"].AsUUID(), map["ShoesAsset"].AsUUID()); + wearables[7] = new AvatarWearable(map["SocksItem"].AsUUID(), map["SocksAsset"].AsUUID()); + wearables[8] = new AvatarWearable(map["JacketItem"].AsUUID(), map["JacketAsset"].AsUUID()); + wearables[9] = new AvatarWearable(map["GlovesItem"].AsUUID(), map["GlovesAsset"].AsUUID()); + wearables[10] = new AvatarWearable(map["UndershirtItem"].AsUUID(), map["UndershirtAsset"].AsUUID()); + wearables[11] = new AvatarWearable(map["UnderpantsItem"].AsUUID(), map["UnderpantsAsset"].AsUUID()); + wearables[12] = new AvatarWearable(map["SkirtItem"].AsUUID(), map["SkirtAsset"].AsUUID()); + + AvatarAppearance appearance = new AvatarAppearance(userID); + appearance.Wearables = wearables; + appearance.AvatarHeight = (float)map["Height"].AsReal(); + + AvatarData avatar = new AvatarData(appearance); + + // Get attachments + map = null; + try { map = OSDParser.DeserializeJson(response["LLAttachments"].AsString()) as OSDMap; } + catch { } + + if (map != null) + { + foreach (KeyValuePair kvp in map) + avatar.Data[kvp.Key] = kvp.Value.AsString(); + } + + return avatar; + } + else + { + m_log.Warn("[AVATAR CONNECTOR]: Failed to get user appearance for " + userID + + ", LLAppearance is missing or invalid"); + return null; + } + } + else + { + m_log.Warn("[AVATAR CONNECTOR]: Failed to get user appearance for " + userID + ": " + + response["Message"].AsString()); + } + + return null; + } + + public bool SetAvatar(UUID userID, AvatarData avatar) + { + m_log.Debug("[AVATAR CONNECTOR]: SetAvatar called for " + userID); + + if (avatar.AvatarType == 1) // LLAvatar + { + AvatarAppearance appearance = avatar.ToAvatarAppearance(userID); + + OSDMap map = new OSDMap(); + + map["Height"] = OSD.FromReal(appearance.AvatarHeight); + + map["ShapeItem"] = OSD.FromUUID(appearance.BodyItem); + map["ShapeAsset"] = OSD.FromUUID(appearance.BodyAsset); + map["SkinItem"] = OSD.FromUUID(appearance.SkinItem); + map["SkinAsset"] = OSD.FromUUID(appearance.SkinAsset); + map["HairItem"] = OSD.FromUUID(appearance.HairItem); + map["HairAsset"] = OSD.FromUUID(appearance.HairAsset); + map["EyesItem"] = OSD.FromUUID(appearance.EyesItem); + map["EyesAsset"] = OSD.FromUUID(appearance.EyesAsset); + map["ShirtItem"] = OSD.FromUUID(appearance.ShirtItem); + map["ShirtAsset"] = OSD.FromUUID(appearance.ShirtAsset); + map["PantsItem"] = OSD.FromUUID(appearance.PantsItem); + map["PantsAsset"] = OSD.FromUUID(appearance.PantsAsset); + map["ShoesItem"] = OSD.FromUUID(appearance.ShoesItem); + map["ShoesAsset"] = OSD.FromUUID(appearance.ShoesAsset); + map["SocksItem"] = OSD.FromUUID(appearance.SocksItem); + map["SocksAsset"] = OSD.FromUUID(appearance.SocksAsset); + map["JacketItem"] = OSD.FromUUID(appearance.JacketItem); + map["JacketAsset"] = OSD.FromUUID(appearance.JacketAsset); + map["GlovesItem"] = OSD.FromUUID(appearance.GlovesItem); + map["GlovesAsset"] = OSD.FromUUID(appearance.GlovesAsset); + map["UndershirtItem"] = OSD.FromUUID(appearance.UnderShirtItem); + map["UndershirtAsset"] = OSD.FromUUID(appearance.UnderShirtAsset); + map["UnderpantsItem"] = OSD.FromUUID(appearance.UnderPantsItem); + map["UnderpantsAsset"] = OSD.FromUUID(appearance.UnderPantsAsset); + map["SkirtItem"] = OSD.FromUUID(appearance.SkirtItem); + map["SkirtAsset"] = OSD.FromUUID(appearance.SkirtAsset); + + OSDMap items = new OSDMap(); + foreach (KeyValuePair kvp in avatar.Data) + { + if (kvp.Key.StartsWith("_ap_")) + items.Add(kvp.Key, OSD.FromString(kvp.Value)); + } + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddUserData" }, + { "UserID", userID.ToString() }, + { "LLAppearance", OSDParser.SerializeJsonString(map) }, + { "LLAttachments", OSDParser.SerializeJsonString(items) } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + m_log.Warn("[AVATAR CONNECTOR]: Failed saving appearance for " + userID + ": " + response["Message"].AsString()); + + return success; + } + else + { + m_log.Error("[AVATAR CONNECTOR]: Can't save appearance for " + userID + ". Unhandled avatar type " + avatar.AvatarType); + return false; + } + } + + public bool ResetAvatar(UUID userID) + { + m_log.Error("[AVATAR CONNECTOR]: ResetAvatar called for " + userID + ", implement this"); + return false; + } + + public bool SetItems(UUID userID, string[] names, string[] values) + { + m_log.Error("[AVATAR CONNECTOR]: SetItems called for " + userID + " with " + names.Length + " names and " + values.Length + " values, implement this"); + return false; + } + + public bool RemoveItems(UUID userID, string[] names) + { + m_log.Error("[AVATAR CONNECTOR]: RemoveItems called for " + userID + " with " + names.Length + " names, implement this"); + return false; + } + + #endregion IAvatarService + } +} diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs new file mode 100644 index 0000000..3952a8c --- /dev/null +++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs @@ -0,0 +1,229 @@ +/* + * 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.Collections.Specialized; +using System.Reflection; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; + +using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; + +namespace OpenSim.Services.Connectors.SimianGrid +{ + /// + /// Stores and retrieves friend lists from the SimianGrid backend + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SimianFriendsServiceConnector : IFriendsService, ISharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_serverUrl = String.Empty; + + #region ISharedRegionModule + + public Type ReplaceableInterface { get { return null; } } + public void RegionLoaded(Scene scene) { } + public void PostInitialise() { } + public void Close() { } + + public SimianFriendsServiceConnector() { } + public string Name { get { return "SimianFriendsServiceConnector"; } } + public void AddRegion(Scene scene) { scene.RegisterModuleInterface(this); } + public void RemoveRegion(Scene scene) { scene.UnregisterModuleInterface(this); } + + #endregion ISharedRegionModule + + public SimianFriendsServiceConnector(IConfigSource source) + { + Initialise(source); + } + + public void Initialise(IConfigSource source) + { + IConfig assetConfig = source.Configs["FriendsService"]; + if (assetConfig == null) + { + m_log.Error("[FRIENDS CONNECTOR]: FriendsService missing from OpenSim.ini"); + throw new Exception("Friends connector init error"); + } + + string serviceURI = assetConfig.GetString("FriendsServerURI"); + if (String.IsNullOrEmpty(serviceURI)) + { + m_log.Error("[FRIENDS CONNECTOR]: No Server URI named in section FriendsService"); + throw new Exception("Friends connector init error"); + } + + m_serverUrl = serviceURI; + } + + #region IFriendsService + + public FriendInfo[] GetFriends(UUID principalID) + { + Dictionary friends = new Dictionary(); + + OSDArray friendsArray = GetFriended(principalID); + OSDArray friendedMeArray = GetFriendedBy(principalID); + + // Load the list of friends and their granted permissions + for (int i = 0; i < friendsArray.Count; i++) + { + OSDMap friendEntry = friendsArray[i] as OSDMap; + if (friendEntry != null) + { + UUID friendID = friendEntry["Key"].AsUUID(); + + FriendInfo friend = new FriendInfo(); + friend.PrincipalID = principalID; + friend.Friend = friendID.ToString(); + friend.MyFlags = friendEntry["Value"].AsInteger(); + friend.TheirFlags = -1; + + friends[friendID] = friend; + } + } + + // Load the permissions those friends have granted to this user + for (int i = 0; i < friendedMeArray.Count; i++) + { + OSDMap friendedMeEntry = friendedMeArray[i] as OSDMap; + if (friendedMeEntry != null) + { + UUID friendID = friendedMeEntry["OwnerID"].AsUUID(); + + FriendInfo friend; + if (friends.TryGetValue(friendID, out friend)) + friend.TheirFlags = friendedMeEntry["Value"].AsInteger(); + } + } + + // Convert the dictionary of friends to an array and return it + FriendInfo[] array = new FriendInfo[friends.Count]; + int j = 0; + foreach (FriendInfo friend in friends.Values) + array[j++] = friend; + + return array; + } + + public bool StoreFriend(UUID principalID, string friend, int flags) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddGeneric" }, + { "OwnerID", principalID.ToString() }, + { "Type", "Friend" }, + { "Key", friend }, + { "Value", flags.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + m_log.Error("[FRIENDS CONNECTOR]: Failed to store friend " + friend + " for user " + principalID + ": " + response["Message"].AsString()); + + return success; + } + + public bool Delete(UUID principalID, string friend) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "RemoveGeneric" }, + { "OwnerID", principalID.ToString() }, + { "Type", "Friend" }, + { "Key", friend } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + m_log.Error("[FRIENDS CONNECTOR]: Failed to remove friend " + friend + " for user " + principalID + ": " + response["Message"].AsString()); + + return success; + } + + #endregion IFriendsService + + private OSDArray GetFriended(UUID ownerID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "OwnerID", ownerID.ToString() }, + { "Type", "Friend" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) + { + return (OSDArray)response["Entries"]; + } + else + { + m_log.Warn("[FRIENDS CONNECTOR]: Failed to retrieve friends for user " + ownerID + ": " + response["Message"].AsString()); + return new OSDArray(0); + } + } + + private OSDArray GetFriendedBy(UUID ownerID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "Key", ownerID.ToString() }, + { "Type", "Friend" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) + { + return (OSDArray)response["Entries"]; + } + else + { + m_log.Warn("[FRIENDS CONNECTOR]: Failed to retrieve reverse friends for user " + ownerID + ": " + response["Message"].AsString()); + return new OSDArray(0); + } + } + } +} diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs new file mode 100644 index 0000000..41ed2f1 --- /dev/null +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs @@ -0,0 +1,31 @@ +/* + * 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 Mono.Addins; + +[assembly: Addin("SimianGrid", "1.0")] +[assembly: AddinDependency("OpenSim", "0.5")] diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs new file mode 100644 index 0000000..16819d1 --- /dev/null +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs @@ -0,0 +1,418 @@ +/* + * 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.Collections.Specialized; +using System.Net; +using System.Reflection; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenSim.Server.Base; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +namespace OpenSim.Services.Connectors.SimianGrid +{ + /// + /// Connects region registration and neighbor lookups to the SimianGrid + /// backend + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SimianGridServiceConnector : IGridService, ISharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_serverUrl = String.Empty; + + #region ISharedRegionModule + + public Type ReplaceableInterface { get { return null; } } + public void RegionLoaded(Scene scene) { } + public void PostInitialise() { } + public void Close() { } + + public SimianGridServiceConnector() { } + public string Name { get { return "SimianGridServiceConnector"; } } + public void AddRegion(Scene scene) { scene.RegisterModuleInterface(this); } + public void RemoveRegion(Scene scene) { scene.UnregisterModuleInterface(this); } + + #endregion ISharedRegionModule + + public SimianGridServiceConnector(IConfigSource source) + { + Initialise(source); + } + + public void Initialise(IConfigSource source) + { + IConfig gridConfig = source.Configs["GridService"]; + if (gridConfig == null) + { + m_log.Error("[GRID CONNECTOR]: GridService missing from OpenSim.ini"); + throw new Exception("Grid connector init error"); + } + + string serviceUrl = gridConfig.GetString("GridServerURI"); + if (String.IsNullOrEmpty(serviceUrl)) + { + m_log.Error("[GRID CONNECTOR]: No Server URI named in section GridService"); + throw new Exception("Grid connector init error"); + } + + m_serverUrl = serviceUrl; + } + + #region IGridService + + public string RegisterRegion(UUID scopeID, GridRegion regionInfo) + { + Vector3d minPosition = new Vector3d(regionInfo.RegionLocX, regionInfo.RegionLocY, 0.0); + Vector3d maxPosition = minPosition + new Vector3d(Constants.RegionSize, Constants.RegionSize, 4096.0); + + string httpAddress = "http://" + regionInfo.ExternalHostName + ":" + regionInfo.HttpPort + "/"; + + OSDMap extraData = new OSDMap + { + { "ServerURI", OSD.FromString(regionInfo.ServerURI) }, + { "InternalAddress", OSD.FromString(regionInfo.InternalEndPoint.Address.ToString()) }, + { "InternalPort", OSD.FromInteger(regionInfo.InternalEndPoint.Port) }, + { "ExternalAddress", OSD.FromString(regionInfo.ExternalEndPoint.Address.ToString()) }, + { "ExternalPort", OSD.FromInteger(regionInfo.ExternalEndPoint.Port) }, + { "MapTexture", OSD.FromUUID(regionInfo.TerrainImage) }, + { "Access", OSD.FromInteger(regionInfo.Access) }, + { "RegionSecret", OSD.FromString(regionInfo.RegionSecret) }, + { "EstateOwner", OSD.FromUUID(regionInfo.EstateOwner) }, + { "Token", OSD.FromString(regionInfo.Token) } + }; + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddScene" }, + { "SceneID", regionInfo.RegionID.ToString() }, + { "Name", regionInfo.RegionName }, + { "MinPosition", minPosition.ToString() }, + { "MaxPosition", maxPosition.ToString() }, + { "Address", httpAddress }, + { "Enabled", "1" }, + { "ExtraData", OSDParser.SerializeJsonString(extraData) } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean()) + return String.Empty; + else + return "Region registration for " + regionInfo.RegionName + " failed: " + response["Message"].AsString(); + } + + public bool DeregisterRegion(UUID regionID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddScene" }, + { "SceneID", regionID.ToString() }, + { "Enabled", "0" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + m_log.Warn("[GRID CONNECTOR]: Region deregistration for " + regionID + " failed: " + response["Message"].AsString()); + + return success; + } + + public List GetNeighbours(UUID scopeID, UUID regionID) + { + const int NEIGHBOR_RADIUS = 128; + + GridRegion region = GetRegionByUUID(scopeID, regionID); + + if (region != null) + { + List regions = GetRegionRange(scopeID, + region.RegionLocX - NEIGHBOR_RADIUS, region.RegionLocX + (int)Constants.RegionSize + NEIGHBOR_RADIUS, + region.RegionLocY - NEIGHBOR_RADIUS, region.RegionLocY + (int)Constants.RegionSize + NEIGHBOR_RADIUS); + + for (int i = 0; i < regions.Count; i++) + { + if (regions[i].RegionID == regionID) + { + regions.RemoveAt(i); + break; + } + } + + m_log.Debug("[GRID CONNECTOR]: Found " + regions.Count + " neighbors for region " + regionID); + return regions; + } + + return new List(0); + } + + public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetScene" }, + { "SceneID", regionID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean()) + { + return ResponseToGridRegion(response); + } + else + { + m_log.Warn("[GRID CONNECTOR]: Grid service did not find a match for region " + regionID); + return null; + } + } + + public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) + { + // Go one meter in from the requested x/y coords to avoid requesting a position + // that falls on the border of two sims + Vector3d position = new Vector3d(x + 1, y + 1, 0.0); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetScene" }, + { "Position", position.ToString() }, + { "Enabled", "1" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean()) + { + return ResponseToGridRegion(response); + } + else + { + //m_log.InfoFormat("[GRID CONNECTOR]: Grid service did not find a match for region at {0},{1}", + // x / Constants.RegionSize, y / Constants.RegionSize); + return null; + } + } + + public GridRegion GetRegionByName(UUID scopeID, string regionName) + { + List regions = GetRegionsByName(scopeID, regionName, 1); + + m_log.Debug("[GRID CONNECTOR]: Got " + regions.Count + " matches for region name " + regionName); + + if (regions.Count > 0) + return regions[0]; + + return null; + } + + public List GetRegionsByName(UUID scopeID, string name, int maxNumber) + { + List foundRegions = new List(); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetScenes" }, + { "NameQuery", name }, + { "Enabled", "1" } + }; + if (maxNumber > 0) + requestArgs["MaxNumber"] = maxNumber.ToString(); + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean()) + { + OSDArray array = response["Scenes"] as OSDArray; + if (array != null) + { + for (int i = 0; i < array.Count; i++) + { + GridRegion region = ResponseToGridRegion(array[i] as OSDMap); + if (region != null) + foundRegions.Add(region); + } + } + } + + return foundRegions; + } + + public List GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax) + { + List foundRegions = new List(); + + Vector3d minPosition = new Vector3d(xmin, ymin, 0.0); + Vector3d maxPosition = new Vector3d(xmax, ymax, 4096.0); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetScenes" }, + { "MinPosition", minPosition.ToString() }, + { "MaxPosition", maxPosition.ToString() }, + { "Enabled", "1" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean()) + { + OSDArray array = response["Scenes"] as OSDArray; + if (array != null) + { + for (int i = 0; i < array.Count; i++) + { + GridRegion region = ResponseToGridRegion(array[i] as OSDMap); + if (region != null) + foundRegions.Add(region); + } + } + } + + return foundRegions; + } + + public List GetDefaultRegions(UUID scopeID) + { + // TODO: Allow specifying the default grid location + const int DEFAULT_X = 1000 * 256; + const int DEFAULT_Y = 1000 * 256; + + GridRegion defRegion = GetNearestRegion(new Vector3d(DEFAULT_X, DEFAULT_Y, 0.0), true); + if (defRegion != null) + return new List(1) { defRegion }; + else + return new List(0); + } + + public List GetFallbackRegions(UUID scopeID, int x, int y) + { + GridRegion defRegion = GetNearestRegion(new Vector3d(x, y, 0.0), true); + if (defRegion != null) + return new List(1) { defRegion }; + else + return new List(0); + } + + public int GetRegionFlags(UUID scopeID, UUID regionID) + { + const int REGION_ONLINE = 4; + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetScene" }, + { "SceneID", regionID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean()) + { + return response["Enabled"].AsBoolean() ? REGION_ONLINE : 0; + } + else + { + m_log.Warn("[GRID CONNECTOR]: Grid service did not find a match for region " + regionID + " during region flags check"); + return -1; + } + } + + #endregion IGridService + + private GridRegion GetNearestRegion(Vector3d position, bool onlyEnabled) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetScene" }, + { "Position", position.ToString() }, + { "FindClosest", "1" } + }; + if (onlyEnabled) + requestArgs["Enabled"] = "1"; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean()) + { + return ResponseToGridRegion(response); + } + else + { + m_log.Warn("[GRID CONNECTOR]: Grid service did not find a match for region at " + position); + return null; + } + } + + private GridRegion ResponseToGridRegion(OSDMap response) + { + if (response == null) + return null; + + OSDMap extraData = response["ExtraData"] as OSDMap; + if (extraData == null) + return null; + + GridRegion region = new GridRegion(); + + region.RegionID = response["SceneID"].AsUUID(); + region.RegionName = response["Name"].AsString(); + + Vector3d minPosition = response["MinPosition"].AsVector3d(); + region.RegionLocX = (int)minPosition.X; + region.RegionLocY = (int)minPosition.Y; + + Uri httpAddress = response["Address"].AsUri(); + region.ExternalHostName = httpAddress.Host; + region.HttpPort = (uint)httpAddress.Port; + + region.ServerURI = extraData["ServerURI"].AsString(); + + IPAddress internalAddress; + IPAddress.TryParse(extraData["InternalAddress"].AsString(), out internalAddress); + if (internalAddress == null) + internalAddress = IPAddress.Any; + + region.InternalEndPoint = new IPEndPoint(internalAddress, extraData["InternalPort"].AsInteger()); + region.TerrainImage = extraData["MapTexture"].AsUUID(); + region.Access = (byte)extraData["Access"].AsInteger(); + region.RegionSecret = extraData["RegionSecret"].AsString(); + region.EstateOwner = extraData["EstateOwner"].AsUUID(); + region.Token = extraData["Token"].AsString(); + + return region; + } + } +} diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs new file mode 100644 index 0000000..c812899 --- /dev/null +++ b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs @@ -0,0 +1,880 @@ +/* + * 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.Collections.Specialized; +using System.Reflection; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Services.Connectors.SimianGrid +{ + /// + /// Permissions bitflags + /// + [Flags] + public enum PermissionMask : uint + { + None = 0, + Transfer = 1 << 13, + Modify = 1 << 14, + Copy = 1 << 15, + Move = 1 << 19, + Damage = 1 << 20, + All = 0x7FFFFFFF + } + + /// + /// Connects avatar inventories to the SimianGrid backend + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SimianInventoryServiceConnector : IInventoryService, ISharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_serverUrl = String.Empty; + private string m_userServerUrl = String.Empty; + private object m_gestureSyncRoot = new object(); + + #region ISharedRegionModule + + public Type ReplaceableInterface { get { return null; } } + public void RegionLoaded(Scene scene) { } + public void PostInitialise() { } + public void Close() { } + + public SimianInventoryServiceConnector() { } + public string Name { get { return "SimianInventoryServiceConnector"; } } + public void AddRegion(Scene scene) { scene.RegisterModuleInterface(this); } + public void RemoveRegion(Scene scene) { scene.UnregisterModuleInterface(this); } + + #endregion ISharedRegionModule + + public SimianInventoryServiceConnector(IConfigSource source) + { + Initialise(source); + } + + public void Initialise(IConfigSource source) + { + IConfig gridConfig = source.Configs["InventoryService"]; + if (gridConfig == null) + { + m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini"); + throw new Exception("Inventory connector init error"); + } + + string serviceUrl = gridConfig.GetString("InventoryServerURI"); + if (String.IsNullOrEmpty(serviceUrl)) + { + m_log.Error("[INVENTORY CONNECTOR]: No Server URI named in section InventoryService"); + throw new Exception("Inventory connector init error"); + } + + // FIXME: Get the user server URL too + + m_serverUrl = serviceUrl; + } + + /// + /// Create the entire inventory for a given user + /// + /// + /// + public bool CreateUserInventory(UUID userID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddInventory" }, + { "OwnerID", userID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + m_log.Warn("[INVENTORY CONNECTOR]: Inventory creation for " + userID + " failed: " + response["Message"].AsString()); + + return success; + } + + /// + /// Gets the skeleton of the inventory -- folders only + /// + /// + /// + public List GetInventorySkeleton(UUID userID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetInventoryNode" }, + { "ItemID", userID.ToString() }, + { "OwnerID", userID.ToString() }, + { "IncludeFolders", "1" }, + { "IncludeItems", "0" }, + { "ChildrenOnly", "0" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Items"] is OSDArray) + { + OSDArray items = (OSDArray)response["Items"]; + return GetFoldersFromResponse(items, userID, true); + } + else + { + m_log.Warn("[INVENTORY CONNECTOR]: Failed to retrieve inventory skeleton for " + userID + ": " + + response["Message"].AsString()); + return new List(0); + } + } + + /// + /// Synchronous inventory fetch. + /// + /// + /// + [Obsolete] + public InventoryCollection GetUserInventory(UUID userID) + { + m_log.Error("[INVENTORY CONNECTOR]: Obsolete GetUserInventory called for " + userID); + + InventoryCollection inventory = new InventoryCollection(); + inventory.UserID = userID; + inventory.Folders = new List(); + inventory.Items = new List(); + + return inventory; + } + + /// + /// Request the inventory for a user. This is an asynchronous operation that will call the callback when the + /// inventory has been received + /// + /// + /// + [Obsolete] + public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) + { + m_log.Error("[INVENTORY CONNECTOR]: Obsolete GetUserInventory called for " + userID); + callback(new List(0), new List(0)); + } + + /// + /// Retrieve the root inventory folder for the given user. + /// + /// + /// null if no root folder was found + public InventoryFolderBase GetRootFolder(UUID userID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetInventoryNode" }, + { "ItemID", userID.ToString() }, + { "OwnerID", userID.ToString() }, + { "IncludeFolders", "1" }, + { "IncludeItems", "0" }, + { "ChildrenOnly", "1" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Items"] is OSDArray) + { + OSDArray items = (OSDArray)response["Items"]; + List folders = GetFoldersFromResponse(items, userID, true); + + if (folders.Count > 0) + return folders[0]; + } + + return null; + } + + /// + /// Gets the user folder for the given folder-type + /// + /// + /// + /// + public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) + { + string contentType = SLUtil.SLAssetTypeToContentType((int)type); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetFolderForType" }, + { "ContentType", contentType }, + { "OwnerID", userID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Folder"] is OSDMap) + { + OSDMap folder = (OSDMap)response["Folder"]; + + return new InventoryFolderBase( + folder["ID"].AsUUID(), + folder["Name"].AsString(), + folder["OwnerID"].AsUUID(), + (short)SLUtil.ContentTypeToSLAssetType(folder["ContentType"].AsString()), + folder["ParentID"].AsUUID(), + (ushort)folder["Version"].AsInteger() + ); + } + else + { + m_log.Warn("[INVENTORY CONNECTOR]: Default folder not found for content type " + contentType); + return GetRootFolder(userID); + } + } + + /// + /// Get an item, given by its UUID + /// + /// + /// + public InventoryItemBase GetItem(InventoryItemBase item) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetInventoryNode" }, + { "ItemID", item.ID.ToString() }, + { "OwnerID", item.Owner.ToString() }, + { "IncludeFolders", "1" }, + { "IncludeItems", "1" }, + { "ChildrenOnly", "1" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Items"] is OSDArray) + { + List items = GetItemsFromResponse((OSDArray)response["Items"]); + if (items.Count > 0) + { + // The requested item should be the first in this list, but loop through + // and sanity check just in case + for (int i = 0; i < items.Count; i++) + { + if (items[i].ID == item.ID) + return items[i]; + } + } + } + + m_log.Warn("[INVENTORY CONNECTOR]: Item " + item.ID + " owned by " + item.Owner + " not found"); + return null; + } + + /// + /// Get a folder, given by its UUID + /// + /// + /// + public InventoryFolderBase GetFolder(InventoryFolderBase folder) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetInventoryNode" }, + { "ItemID", folder.ID.ToString() }, + { "OwnerID", folder.Owner.ToString() }, + { "IncludeFolders", "1" }, + { "IncludeItems", "0" }, + { "ChildrenOnly", "1" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Items"] is OSDArray) + { + OSDArray items = (OSDArray)response["Items"]; + List folders = GetFoldersFromResponse(items, folder.ID, true); + + if (folders.Count > 0) + return folders[0]; + } + + return null; + } + + /// + /// Gets everything (folders and items) inside a folder + /// + /// + /// + /// + public InventoryCollection GetFolderContent(UUID userID, UUID folderID) + { + InventoryCollection inventory = new InventoryCollection(); + inventory.UserID = userID; + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetInventoryNode" }, + { "ItemID", folderID.ToString() }, + { "OwnerID", userID.ToString() }, + { "IncludeFolders", "1" }, + { "IncludeItems", "1" }, + { "ChildrenOnly", "1" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Items"] is OSDArray) + { + OSDArray items = (OSDArray)response["Items"]; + + inventory.Folders = GetFoldersFromResponse(items, folderID, false); + inventory.Items = GetItemsFromResponse(items); + } + else + { + m_log.Warn("[INVENTORY CONNECTOR]: Error fetching folder " + folderID + " content for " + userID + ": " + + response["Message"].AsString()); + inventory.Folders = new List(0); + inventory.Items = new List(0); + } + + return inventory; + } + + /// + /// Gets the items inside a folder + /// + /// + /// + /// + public List GetFolderItems(UUID userID, UUID folderID) + { + InventoryCollection inventory = new InventoryCollection(); + inventory.UserID = userID; + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetInventoryNode" }, + { "ItemID", folderID.ToString() }, + { "OwnerID", userID.ToString() }, + { "IncludeFolders", "0" }, + { "IncludeItems", "1" }, + { "ChildrenOnly", "1" } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["Items"] is OSDArray) + { + OSDArray items = (OSDArray)response["Items"]; + return GetItemsFromResponse(items); + } + else + { + m_log.Warn("[INVENTORY CONNECTOR]: Error fetching folder " + folderID + " for " + userID + ": " + + response["Message"].AsString()); + return new List(0); + } + } + + /// + /// Add a new folder to the user's inventory + /// + /// + /// true if the folder was successfully added + public bool AddFolder(InventoryFolderBase folder) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddInventoryFolder" }, + { "FolderID", folder.ID.ToString() }, + { "ParentID", folder.ParentID.ToString() }, + { "OwnerID", folder.Owner.ToString() }, + { "Name", folder.Name }, + { "ContentType", SLUtil.SLAssetTypeToContentType(folder.Type) } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + { + m_log.Warn("[INVENTORY CONNECTOR]: Error creating folder " + folder.Name + " for " + folder.Owner + ": " + + response["Message"].AsString()); + } + + return success; + } + + /// + /// Update a folder in the user's inventory + /// + /// + /// true if the folder was successfully updated + public bool UpdateFolder(InventoryFolderBase folder) + { + return AddFolder(folder); + } + + /// + /// Move an inventory folder to a new location + /// + /// A folder containing the details of the new location + /// true if the folder was successfully moved + public bool MoveFolder(InventoryFolderBase folder) + { + return AddFolder(folder); + } + + /// + /// Delete an item from the user's inventory + /// + /// + /// true if the item was successfully deleted + //bool DeleteItem(InventoryItemBase item); + public bool DeleteFolders(UUID userID, List folderIDs) + { + return DeleteItems(userID, folderIDs); + } + + /// + /// Delete an item from the user's inventory + /// + /// + /// true if the item was successfully deleted + public bool DeleteItems(UUID userID, List itemIDs) + { + // TODO: RemoveInventoryNode should be replaced with RemoveInventoryNodes + bool allSuccess = true; + + for (int i = 0; i < itemIDs.Count; i++) + { + UUID itemID = itemIDs[i]; + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "RemoveInventoryNode" }, + { "OwnerID", userID.ToString() }, + { "ItemID", itemID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + { + m_log.Warn("[INVENTORY CONNECTOR]: Error removing item " + itemID + " for " + userID + ": " + + response["Message"].AsString()); + allSuccess = false; + } + } + + return allSuccess; + } + + /// + /// Purge an inventory folder of all its items and subfolders. + /// + /// + /// true if the folder was successfully purged + public bool PurgeFolder(InventoryFolderBase folder) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "PurgeInventoryFolder" }, + { "OwnerID", folder.Owner.ToString() }, + { "FolderID", folder.ID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + { + m_log.Warn("[INVENTORY CONNECTOR]: Error purging folder " + folder.ID + " for " + folder.Owner + ": " + + response["Message"].AsString()); + } + + return success; + } + + /// + /// Add a new item to the user's inventory + /// + /// + /// true if the item was successfully added + public bool AddItem(InventoryItemBase item) + { + // A folder of UUID.Zero means we need to find the most appropriate home for this item + if (item.Folder == UUID.Zero) + { + InventoryFolderBase folder = GetFolderForType(item.Owner, (AssetType)item.AssetType); + if (folder != null && folder.ID != UUID.Zero) + item.Folder = folder.ID; + else + item.Folder = item.Owner; // Root folder + } + + if ((AssetType)item.AssetType == AssetType.Gesture) + UpdateGesture(item.Owner, item.ID, item.Flags == 1); + + if (item.BasePermissions == 0) + m_log.WarnFormat("[INVENTORY CONNECTOR]: Adding inventory item {0} ({1}) with no base permissions", item.Name, item.ID); + + OSDMap permissions = new OSDMap + { + { "BaseMask", OSD.FromInteger(item.BasePermissions) }, + { "EveryoneMask", OSD.FromInteger(item.EveryOnePermissions) }, + { "GroupMask", OSD.FromInteger(item.GroupPermissions) }, + { "NextOwnerMask", OSD.FromInteger(item.NextPermissions) }, + { "OwnerMask", OSD.FromInteger(item.CurrentPermissions) } + }; + + OSDMap extraData = new OSDMap() + { + { "Flags", OSD.FromInteger(item.Flags) }, + { "GroupID", OSD.FromUUID(item.GroupID) }, + { "GroupOwned", OSD.FromBoolean(item.GroupOwned) }, + { "SalePrice", OSD.FromInteger(item.SalePrice) }, + { "SaleType", OSD.FromInteger(item.SaleType) }, + { "Permissions", permissions } + }; + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddInventoryItem" }, + { "ItemID", item.ID.ToString() }, + { "AssetID", item.AssetID.ToString() }, + { "ParentID", item.Folder.ToString() }, + { "OwnerID", item.Owner.ToString() }, + { "Name", item.Name }, + { "Description", item.Description }, + { "CreatorID", item.CreatorId }, + { "ExtraData", OSDParser.SerializeJsonString(extraData) } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + { + m_log.Warn("[INVENTORY CONNECTOR]: Error creating item " + item.Name + " for " + item.Owner + ": " + + response["Message"].AsString()); + } + + return success; + } + + /// + /// Update an item in the user's inventory + /// + /// + /// true if the item was successfully updated + public bool UpdateItem(InventoryItemBase item) + { + if (item.AssetID != UUID.Zero) + { + return AddItem(item); + } + else + { + // This is actually a folder update + InventoryFolderBase folder = new InventoryFolderBase(item.ID, item.Name, item.Owner, (short)item.AssetType, item.Folder, 0); + return UpdateFolder(folder); + } + } + + public bool MoveItems(UUID ownerID, List items) + { + bool success = true; + + while (items.Count > 0) + { + List currentItems = new List(); + UUID destFolderID = items[0].Folder; + + // Find all of the items being moved to the current destination folder + for (int i = 0; i < items.Count; i++) + { + InventoryItemBase item = items[i]; + if (item.Folder == destFolderID) + currentItems.Add(item); + } + + // Do the inventory move for the current items + success &= MoveItems(ownerID, items, destFolderID); + + // Remove the processed items from the list + for (int i = 0; i < currentItems.Count; i++) + items.Remove(currentItems[i]); + } + + return success; + } + + /// + /// Does the given user have an inventory structure? + /// + /// + /// + public bool HasInventoryForUser(UUID userID) + { + return GetRootFolder(userID) != null; + } + + /// + /// Get the active gestures of the agent. + /// + /// + /// + public List GetActiveGestures(UUID userID) + { + OSDArray items = FetchGestures(userID); + + string[] itemIDs = new string[items.Count]; + for (int i = 0; i < items.Count; i++) + itemIDs[i] = items[i].AsUUID().ToString(); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetInventoryNodes" }, + { "OwnerID", userID.ToString() }, + { "Items", String.Join(",", itemIDs) } + }; + + // FIXME: Implement this in SimianGrid + return new List(0); + } + + /// + /// Get the union of permissions of all inventory items + /// that hold the given assetID. + /// + /// + /// + /// The permissions or 0 if no such asset is found in + /// the user's inventory + public int GetAssetPermissions(UUID userID, UUID assetID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetInventoryNodes" }, + { "OwnerID", userID.ToString() }, + { "AssetID", assetID.ToString() } + }; + + // FIXME: Implement this in SimianGrid + return (int)PermissionMask.All; + } + + private List GetFoldersFromResponse(OSDArray items, UUID baseFolder, bool includeBaseFolder) + { + List invFolders = new List(items.Count); + + for (int i = 0; i < items.Count; i++) + { + OSDMap item = items[i] as OSDMap; + + if (item != null && item["Type"].AsString() == "Folder") + { + UUID folderID = item["ID"].AsUUID(); + + if (folderID == baseFolder && !includeBaseFolder) + continue; + + invFolders.Add(new InventoryFolderBase( + folderID, + item["Name"].AsString(), + item["OwnerID"].AsUUID(), + (short)SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString()), + item["ParentID"].AsUUID(), + (ushort)item["Version"].AsInteger() + )); + } + } + + return invFolders; + } + + private List GetItemsFromResponse(OSDArray items) + { + List invItems = new List(items.Count); + + for (int i = 0; i < items.Count; i++) + { + OSDMap item = items[i] as OSDMap; + + if (item != null && item["Type"].AsString() == "Item") + { + InventoryItemBase invItem = new InventoryItemBase(); + + invItem.AssetID = item["AssetID"].AsUUID(); + invItem.AssetType = SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString()); + invItem.CreationDate = item["CreationDate"].AsInteger(); + invItem.CreatorId = item["CreatorID"].AsString(); + invItem.CreatorIdAsUuid = item["CreatorID"].AsUUID(); + invItem.Description = item["Description"].AsString(); + invItem.Folder = item["ParentID"].AsUUID(); + invItem.ID = item["ID"].AsUUID(); + invItem.InvType = SLUtil.ContentTypeToSLInvType(item["ContentType"].AsString()); + invItem.Name = item["Name"].AsString(); + invItem.Owner = item["OwnerID"].AsUUID(); + + OSDMap extraData = item["ExtraData"] as OSDMap; + if (extraData != null && extraData.Count > 0) + { + invItem.Flags = extraData["Flags"].AsUInteger(); + invItem.GroupID = extraData["GroupID"].AsUUID(); + invItem.GroupOwned = extraData["GroupOwned"].AsBoolean(); + invItem.SalePrice = extraData["SalePrice"].AsInteger(); + invItem.SaleType = (byte)extraData["SaleType"].AsInteger(); + + OSDMap perms = extraData["Permissions"] as OSDMap; + if (perms != null) + { + invItem.BasePermissions = perms["BaseMask"].AsUInteger(); + invItem.CurrentPermissions = perms["OwnerMask"].AsUInteger(); + invItem.EveryOnePermissions = perms["EveryoneMask"].AsUInteger(); + invItem.GroupPermissions = perms["GroupMask"].AsUInteger(); + invItem.NextPermissions = perms["NextOwnerMask"].AsUInteger(); + } + } + + if (invItem.BasePermissions == 0) + { + m_log.InfoFormat("[INVENTORY CONNECTOR]: Forcing item permissions to full for item {0} ({1})", + invItem.Name, invItem.ID); + invItem.BasePermissions = (uint)PermissionMask.All; + invItem.CurrentPermissions = (uint)PermissionMask.All; + invItem.EveryOnePermissions = (uint)PermissionMask.All; + invItem.GroupPermissions = (uint)PermissionMask.All; + invItem.NextPermissions = (uint)PermissionMask.All; + } + + invItems.Add(invItem); + } + } + + return invItems; + } + + private bool MoveItems(UUID ownerID, List items, UUID destFolderID) + { + string[] itemIDs = new string[items.Count]; + for (int i = 0; i < items.Count; i++) + itemIDs[i] = items[i].ID.ToString(); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "MoveInventoryNodes" }, + { "OwnerID", ownerID.ToString() }, + { "FolderID", destFolderID.ToString() }, + { "Items", String.Join(",", itemIDs) } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + { + m_log.Warn("[INVENTORY CONNECTOR]: Failed to move " + items.Count + " items to " + + destFolderID + ": " + response["Message"].AsString()); + } + + return success; + } + + private void UpdateGesture(UUID userID, UUID itemID, bool enabled) + { + OSDArray gestures = FetchGestures(userID); + OSDArray newGestures = new OSDArray(); + + for (int i = 0; i < gestures.Count; i++) + { + UUID gesture = gestures[i].AsUUID(); + if (gesture != itemID) + newGestures.Add(OSD.FromUUID(gesture)); + } + + if (enabled) + newGestures.Add(OSD.FromUUID(itemID)); + + SaveGestures(userID, newGestures); + } + + private OSDArray FetchGestures(UUID userID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetUser" }, + { "UserID", userID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_userServerUrl, requestArgs); + if (response["Success"].AsBoolean()) + { + OSDMap user = response["User"] as OSDMap; + if (user != null && response.ContainsKey("Gestures")) + { + OSD gestures = OSDParser.DeserializeJson(response["Gestures"].AsString()); + if (gestures != null && gestures is OSDArray) + return (OSDArray)gestures; + else + m_log.Error("[INVENTORY CONNECTOR]: Unrecognized active gestures data for " + userID); + } + } + else + { + m_log.Warn("[INVENTORY CONNECTOR]: Failed to fetch active gestures for " + userID + ": " + + response["Message"].AsString()); + } + + return new OSDArray(); + } + + private void SaveGestures(UUID userID, OSDArray gestures) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddUserData" }, + { "UserID", userID.ToString() }, + { "Gestures", OSDParser.SerializeJsonString(gestures) } + }; + + OSDMap response = WebUtil.PostToService(m_userServerUrl, requestArgs); + if (!response["Success"].AsBoolean()) + { + m_log.Warn("[INVENTORY CONNECTOR]: Failed to save active gestures for " + userID + ": " + + response["Message"].AsString()); + } + } + } +} diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs new file mode 100644 index 0000000..65de1c5 --- /dev/null +++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs @@ -0,0 +1,502 @@ +/* + * 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.Collections.Specialized; +using System.Net; +using System.Reflection; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenSim.Server.Base; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; + +namespace OpenSim.Services.Connectors.SimianGrid +{ + /// + /// Connects avatar presence information (for tracking current location and + /// message routing) to the SimianGrid backend + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SimianPresenceServiceConnector : IPresenceService, ISharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_serverUrl = String.Empty; + + #region ISharedRegionModule + + public Type ReplaceableInterface { get { return null; } } + public void RegionLoaded(Scene scene) { } + public void PostInitialise() { } + public void Close() { } + + public SimianPresenceServiceConnector() { } + public string Name { get { return "SimianPresenceServiceConnector"; } } + public void AddRegion(Scene scene) + { + scene.RegisterModuleInterface(this); + + scene.EventManager.OnMakeRootAgent += MakeRootAgentHandler; + scene.EventManager.OnNewClient += NewClientHandler; + scene.EventManager.OnSignificantClientMovement += SignificantClientMovementHandler; + + LogoutRegionAgents(scene.RegionInfo.RegionID); + } + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); + + scene.EventManager.OnMakeRootAgent -= MakeRootAgentHandler; + scene.EventManager.OnNewClient -= NewClientHandler; + scene.EventManager.OnSignificantClientMovement -= SignificantClientMovementHandler; + + LogoutRegionAgents(scene.RegionInfo.RegionID); + } + + #endregion ISharedRegionModule + + public SimianPresenceServiceConnector(IConfigSource source) + { + Initialise(source); + } + + public void Initialise(IConfigSource source) + { + IConfig gridConfig = source.Configs["PresenceService"]; + if (gridConfig == null) + { + m_log.Error("[PRESENCE CONNECTOR]: PresenceService missing from OpenSim.ini"); + throw new Exception("Presence connector init error"); + } + + string serviceUrl = gridConfig.GetString("PresenceServerURI"); + if (String.IsNullOrEmpty(serviceUrl)) + { + m_log.Error("[PRESENCE CONNECTOR]: No PresenceServerURI in section PresenceService"); + throw new Exception("Presence connector init error"); + } + + m_serverUrl = serviceUrl; + } + + #region IPresenceService + + public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID) + { + m_log.ErrorFormat("[PRESENCE CONNECTOR]: Login requested, UserID={0}, SessionID={1}, SecureSessionID={2}", + userID, sessionID, secureSessionID); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddSession" }, + { "UserID", userID.ToString() } + }; + if (sessionID != UUID.Zero) + { + requestArgs["SessionID"] = sessionID.ToString(); + requestArgs["SecureSessionID"] = secureSessionID.ToString(); + } + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + m_log.Warn("[PRESENCE CONNECTOR]: Failed to login agent " + userID + ": " + response["Message"].AsString()); + + return success; + } + + public bool LogoutAgent(UUID sessionID, Vector3 position, Vector3 lookAt) + { + m_log.InfoFormat("[PRESENCE CONNECTOR]: Logout requested for agent with sessionID " + sessionID); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "RemoveSession" }, + { "SessionID", sessionID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + m_log.Warn("[PRESENCE CONNECTOR]: Failed to logout agent with sessionID " + sessionID + ": " + response["Message"].AsString()); + + return success; + } + + public bool LogoutRegionAgents(UUID regionID) + { + m_log.InfoFormat("[PRESENCE CONNECTOR]: Logout requested for all agents in region " + regionID); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "RemoveSessions" }, + { "SceneID", regionID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + m_log.Warn("[PRESENCE CONNECTOR]: Failed to logout agents from region " + regionID + ": " + response["Message"].AsString()); + + return success; + } + + public bool ReportAgent(UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt) + { + //m_log.DebugFormat("[PRESENCE CONNECTOR]: Updating session data for agent with sessionID " + sessionID); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "UpdateSession" }, + { "SessionID", sessionID.ToString() }, + { "SceneID", regionID.ToString() }, + { "ScenePosition", position.ToString() }, + { "SceneLookAt", lookAt.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + m_log.Warn("[PRESENCE CONNECTOR]: Failed to update agent session " + sessionID + ": " + response["Message"].AsString()); + + return success; + } + + public PresenceInfo GetAgent(UUID sessionID) + { + m_log.DebugFormat("[PRESENCE CONNECTOR]: Requesting session data for agent with sessionID " + sessionID); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetSession" }, + { "SessionID", sessionID.ToString() } + }; + + OSDMap sessionResponse = WebUtil.PostToService(m_serverUrl, requestArgs); + if (sessionResponse["Success"].AsBoolean()) + { + UUID userID = sessionResponse["UserID"].AsUUID(); + m_log.DebugFormat("[PRESENCE CONNECTOR]: Requesting user data for " + userID); + + requestArgs = new NameValueCollection + { + { "RequestMethod", "GetUser" }, + { "UserID", userID.ToString() } + }; + + OSDMap userResponse = WebUtil.PostToService(m_serverUrl, requestArgs); + if (userResponse["Success"].AsBoolean()) + return ResponseToPresenceInfo(sessionResponse, userResponse); + else + m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + userResponse["Message"].AsString()); + } + else + { + m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve session " + sessionID + ": " + sessionResponse["Message"].AsString()); + } + + return null; + } + + public PresenceInfo[] GetAgents(string[] userIDs) + { + List presences = new List(userIDs.Length); + + for (int i = 0; i < userIDs.Length; i++) + { + UUID userID; + if (UUID.TryParse(userIDs[i], out userID) && userID != UUID.Zero) + presences.AddRange(GetSessions(userID)); + } + + return presences.ToArray(); + } + + public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt) + { + m_log.DebugFormat("[PRESENCE CONNECTOR]: Setting home location for user " + userID); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddUserData" }, + { "UserID", userID.ToString() }, + { "HomeLocation", SerializeLocation(regionID, position, lookAt) } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + m_log.Warn("[PRESENCE CONNECTOR]: Failed to set home location for " + userID + ": " + response["Message"].AsString()); + + return success; + } + + #endregion IPresenceService + + #region Presence Detection + + private void MakeRootAgentHandler(ScenePresence sp) + { + m_log.DebugFormat("[PRESENCE DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName); + + ReportAgent(sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); + SetLastLocation(sp.UUID, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); + } + + private void NewClientHandler(IClientAPI client) + { + client.OnConnectionClosed += LogoutHandler; + } + + private void SignificantClientMovementHandler(IClientAPI client) + { + ScenePresence sp; + if (client.Scene is Scene && ((Scene)client.Scene).TryGetAvatar(client.AgentId, out sp)) + ReportAgent(sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); + } + + private void LogoutHandler(IClientAPI client) + { + if (client.IsLoggingOut) + { + client.OnConnectionClosed -= LogoutHandler; + + object obj; + if (client.Scene.TryGetAvatar(client.AgentId, out obj) && obj is ScenePresence) + { + // The avatar is still in the scene, we can get the exact logout position + ScenePresence sp = (ScenePresence)obj; + SetLastLocation(client.AgentId, client.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); + } + else + { + // The avatar was already removed from the scene, store LastLocation using the most recent session data + m_log.Warn("[PRESENCE]: " + client.Name + " has already been removed from the scene, storing approximate LastLocation"); + SetLastLocation(client.SessionId); + } + + LogoutAgent(client.SessionId, Vector3.Zero, Vector3.UnitX); + } + } + + #endregion Presence Detection + + #region Helpers + + private OSDMap GetUserData(UUID userID) + { + m_log.DebugFormat("[PRESENCE CONNECTOR]: Requesting user data for " + userID); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetUser" }, + { "UserID", userID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["User"] is OSDMap) + return response; + else + m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + response["Message"].AsString()); + + return null; + } + + private OSDMap GetSessionData(UUID sessionID) + { + m_log.DebugFormat("[PRESENCE CONNECTOR]: Requesting session data for session " + sessionID); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetSession" }, + { "SessionID", sessionID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean()) + return response; + else + m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve session data for session " + sessionID); + + return null; + } + + private List GetSessions(UUID userID) + { + List presences = new List(1); + + OSDMap userResponse = GetUserData(userID); + if (userResponse != null) + { + m_log.DebugFormat("[PRESENCE CONNECTOR]: Requesting sessions for " + userID); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetSession" }, + { "UserID", userID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean()) + { + PresenceInfo presence = ResponseToPresenceInfo(response, userResponse); + if (presence != null) + presences.Add(presence); + } + else + { + m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve sessions for " + userID + ": " + response["Message"].AsString()); + } + } + + return presences; + } + + /// + /// Fetch the last known avatar location with GetSession and persist it + /// as user data with AddUserData + /// + private bool SetLastLocation(UUID sessionID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetSession" }, + { "SessionID", sessionID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (success) + { + UUID userID = response["UserID"].AsUUID(); + UUID sceneID = response["SceneID"].AsUUID(); + Vector3 position = response["ScenePosition"].AsVector3(); + Vector3 lookAt = response["SceneLookAt"].AsVector3(); + + return SetLastLocation(userID, sceneID, position, lookAt); + } + else + { + m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve presence information for session " + sessionID + + " while saving last location: " + response["Message"].AsString()); + } + + return success; + } + + private bool SetLastLocation(UUID userID, UUID sceneID, Vector3 position, Vector3 lookAt) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddUserData" }, + { "UserID", userID.ToString() }, + { "LastLocation", SerializeLocation(sceneID, position, lookAt) } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + m_log.Warn("[PRESENCE CONNECTOR]: Failed to set last location for " + userID + ": " + response["Message"].AsString()); + + return success; + } + + private PresenceInfo ResponseToPresenceInfo(OSDMap sessionResponse, OSDMap userResponse) + { + if (sessionResponse == null) + return null; + + PresenceInfo info = new PresenceInfo(); + + info.Online = true; + info.UserID = sessionResponse["UserID"].AsUUID().ToString(); + info.RegionID = sessionResponse["SceneID"].AsUUID(); + info.Position = sessionResponse["ScenePosition"].AsVector3(); + info.LookAt = sessionResponse["SceneLookAt"].AsVector3(); + + if (userResponse != null && userResponse["User"] is OSDMap) + { + OSDMap user = (OSDMap)userResponse["User"]; + + info.Login = user["LastLoginDate"].AsDate(); + info.Logout = user["LastLogoutDate"].AsDate(); + DeserializeLocation(user["HomeLocation"].AsString(), out info.HomeRegionID, out info.HomePosition, out info.HomeLookAt); + } + + return info; + } + + private string SerializeLocation(UUID regionID, Vector3 position, Vector3 lookAt) + { + return "{" + String.Format("\"SceneID\":\"{0}\",\"Position\":\"{1}\",\"LookAt\":\"{2}\"", regionID, position, lookAt) + "}"; + } + + private bool DeserializeLocation(string location, out UUID regionID, out Vector3 position, out Vector3 lookAt) + { + OSDMap map = null; + + try { map = OSDParser.DeserializeJson(location) as OSDMap; } + catch { } + + if (map != null) + { + regionID = map["SceneID"].AsUUID(); + if (Vector3.TryParse(map["Position"].AsString(), out position) && + Vector3.TryParse(map["LookAt"].AsString(), out lookAt)) + { + return true; + } + } + + regionID = UUID.Zero; + position = Vector3.Zero; + lookAt = Vector3.Zero; + return false; + } + + #endregion Helpers + } +} diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs new file mode 100644 index 0000000..1e19982 --- /dev/null +++ b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs @@ -0,0 +1,432 @@ +/* + * 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.Collections.Specialized; +using System.Reflection; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Framework.Client; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Services.Connectors.SimianGrid +{ + /// + /// Avatar profile flags + /// + [Flags] + public enum ProfileFlags : uint + { + AllowPublish = 1, + MaturePublish = 2, + Identified = 4, + Transacted = 8, + Online = 16 + } + + /// + /// Connects avatar profile and classified queries to the SimianGrid + /// backend + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SimianProfiles : INonSharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_serverUrl = String.Empty; + + #region INonSharedRegionModule + + public Type ReplaceableInterface { get { return null; } } + public void RegionLoaded(Scene scene) { } + public void Close() { } + + public SimianProfiles() { } + public string Name { get { return "SimianProfiles"; } } + public void AddRegion(Scene scene) { CheckEstateManager(scene); scene.EventManager.OnClientConnect += ClientConnectHandler; } + public void RemoveRegion(Scene scene) { scene.EventManager.OnClientConnect -= ClientConnectHandler; } + + #endregion INonSharedRegionModule + + public SimianProfiles(IConfigSource source) + { + Initialise(source); + } + + public void Initialise(IConfigSource source) + { + IConfig gridConfig = source.Configs["UserAccountService"]; + if (gridConfig == null) + { + m_log.Error("[PROFILES]: UserAccountService missing from OpenSim.ini"); + throw new Exception("Profiles init error"); + } + + string serviceUrl = gridConfig.GetString("UserAccountServerURI"); + if (String.IsNullOrEmpty(serviceUrl)) + { + m_log.Error("[PROFILES]: No UserAccountServerURI in section UserAccountService"); + throw new Exception("Profiles init error"); + } + + if (!serviceUrl.EndsWith("/")) + serviceUrl = serviceUrl + '/'; + + m_serverUrl = serviceUrl; + } + + private void ClientConnectHandler(IClientCore clientCore) + { + if (clientCore is IClientAPI) + { + IClientAPI client = (IClientAPI)clientCore; + + // Classifieds + client.AddGenericPacketHandler("avatarclassifiedsrequest", AvatarClassifiedsRequestHandler); + client.OnClassifiedInfoRequest += ClassifiedInfoRequestHandler; + client.OnClassifiedInfoUpdate += ClassifiedInfoUpdateHandler; + client.OnClassifiedDelete += ClassifiedDeleteHandler; + + // Picks + client.AddGenericPacketHandler("avatarpicksrequest", HandleAvatarPicksRequest); + client.AddGenericPacketHandler("pickinforequest", HandlePickInfoRequest); + client.OnPickInfoUpdate += PickInfoUpdateHandler; + client.OnPickDelete += PickDeleteHandler; + + // Notes + client.AddGenericPacketHandler("avatarnotesrequest", HandleAvatarNotesRequest); + client.OnAvatarNotesUpdate += AvatarNotesUpdateHandler; + + // Profiles + client.OnRequestAvatarProperties += RequestAvatarPropertiesHandler; + client.OnUpdateAvatarProperties += UpdateAvatarPropertiesHandler; + client.OnAvatarInterestUpdate += AvatarInterestUpdateHandler; + client.OnUserInfoRequest += UserInfoRequestHandler; + client.OnUpdateUserInfo += UpdateUserInfoHandler; + } + } + + #region Classifieds + + private void AvatarClassifiedsRequestHandler(Object sender, string method, List args) + { + if (!(sender is IClientAPI)) + return; + IClientAPI client = (IClientAPI)sender; + + UUID targetAvatarID; + if (args.Count < 1 || !UUID.TryParse(args[0], out targetAvatarID)) + { + m_log.Error("[PROFILES]: Unrecognized arguments for " + method); + return; + } + + // FIXME: Query the generic key/value store for classifieds + client.SendAvatarClassifiedReply(targetAvatarID, new Dictionary(0)); + } + + private void ClassifiedInfoRequestHandler(UUID classifiedID, IClientAPI client) + { + // FIXME: Fetch this info + client.SendClassifiedInfoReply(classifiedID, UUID.Zero, 0, Utils.DateTimeToUnixTime(DateTime.UtcNow + TimeSpan.FromDays(1)), + 0, String.Empty, String.Empty, UUID.Zero, 0, UUID.Zero, String.Empty, Vector3.Zero, String.Empty, 0, 0); + } + + private void ClassifiedInfoUpdateHandler(UUID classifiedID, uint category, string name, string description, + UUID parcelID, uint parentEstate, UUID snapshotID, Vector3 globalPos, byte classifiedFlags, int price, + IClientAPI client) + { + // FIXME: Save this info + } + + private void ClassifiedDeleteHandler(UUID classifiedID, IClientAPI client) + { + // FIXME: Delete the specified classified ad + } + + #endregion Classifieds + + #region Picks + + private void HandleAvatarPicksRequest(Object sender, string method, List args) + { + if (!(sender is IClientAPI)) + return; + IClientAPI client = (IClientAPI)sender; + + UUID targetAvatarID; + if (args.Count < 1 || !UUID.TryParse(args[0], out targetAvatarID)) + { + m_log.Error("[PROFILES]: Unrecognized arguments for " + method); + return; + } + + // FIXME: Fetch these + client.SendAvatarPicksReply(targetAvatarID, new Dictionary(0)); + } + + private void HandlePickInfoRequest(Object sender, string method, List args) + { + if (!(sender is IClientAPI)) + return; + IClientAPI client = (IClientAPI)sender; + + UUID avatarID; + UUID pickID; + if (args.Count < 2 || !UUID.TryParse(args[0], out avatarID) || !UUID.TryParse(args[1], out pickID)) + { + m_log.Error("[PROFILES]: Unrecognized arguments for " + method); + return; + } + + // FIXME: Fetch this + client.SendPickInfoReply(pickID, avatarID, false, UUID.Zero, String.Empty, String.Empty, UUID.Zero, String.Empty, + String.Empty, String.Empty, Vector3.Zero, 0, false); + } + + private void PickInfoUpdateHandler(IClientAPI client, UUID pickID, UUID creatorID, bool topPick, string name, + string desc, UUID snapshotID, int sortOrder, bool enabled) + { + // FIXME: Save this + } + + private void PickDeleteHandler(IClientAPI client, UUID pickID) + { + // FIXME: Delete + } + + #endregion Picks + + #region Notes + + private void HandleAvatarNotesRequest(Object sender, string method, List args) + { + if (!(sender is IClientAPI)) + return; + IClientAPI client = (IClientAPI)sender; + + UUID targetAvatarID; + if (args.Count < 1 || !UUID.TryParse(args[0], out targetAvatarID)) + { + m_log.Error("[PROFILES]: Unrecognized arguments for " + method); + return; + } + + // FIXME: Fetch this + client.SendAvatarNotesReply(targetAvatarID, String.Empty); + } + + private void AvatarNotesUpdateHandler(IClientAPI client, UUID targetID, string notes) + { + // FIXME: Save this + } + + #endregion Notes + + #region Profiles + + private void RequestAvatarPropertiesHandler(IClientAPI client, UUID avatarID) + { + OSDMap user = FetchUserData(avatarID); + + ProfileFlags flags = ProfileFlags.AllowPublish | ProfileFlags.MaturePublish; + + if (user != null) + { + OSDMap about = null; + if (user.ContainsKey("LLAbout")) + { + try { about = OSDParser.DeserializeJson(user["LLAbout"].AsString()) as OSDMap; } + catch { } + } + + if (about == null) + about = new OSDMap(0); + + // Check if this user is a grid operator + byte[] charterMember; + if (user["AccessLevel"].AsInteger() >= 200) + charterMember = Utils.StringToBytes("Operator"); + else + charterMember = Utils.EmptyBytes; + + // Check if the user is online + if (client.Scene is Scene) + { + OpenSim.Services.Interfaces.PresenceInfo[] presences = ((Scene)client.Scene).PresenceService.GetAgents(new string[] { avatarID.ToString() }); + if (presences != null && presences.Length > 0) + flags |= ProfileFlags.Online; + } + + // Check if the user is identified + if (user["Identified"].AsBoolean()) + flags |= ProfileFlags.Identified; + + client.SendAvatarProperties(avatarID, about["About"].AsString(), user["CreationDate"].AsDate().ToString("M/d/yyyy", + System.Globalization.CultureInfo.InvariantCulture), charterMember, about["FLAbout"].AsString(), (uint)flags, + about["FLImage"].AsUUID(), about["Image"].AsUUID(), about["URL"].AsString(), user["Partner"].AsUUID()); + + } + else + { + m_log.Warn("[PROFILES]: Failed to fetch profile information for " + client.Name + ", returning default values"); + client.SendAvatarProperties(avatarID, String.Empty, "1/1/1970", Utils.EmptyBytes, + String.Empty, (uint)flags, UUID.Zero, UUID.Zero, String.Empty, UUID.Zero); + } + } + + private void UpdateAvatarPropertiesHandler(IClientAPI client, UserProfileData profileData) + { + OSDMap map = new OSDMap + { + { "About", OSD.FromString(profileData.AboutText) }, + { "Image", OSD.FromUUID(profileData.Image) }, + { "FLAbout", OSD.FromString(profileData.FirstLifeAboutText) }, + { "FLImage", OSD.FromUUID(profileData.FirstLifeImage) }, + { "URL", OSD.FromString(profileData.ProfileUrl) } + }; + + AddUserData(client.AgentId, "LLAbout", map); + } + + private void AvatarInterestUpdateHandler(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, + string skillstext, string languages) + { + OSDMap map = new OSDMap + { + { "WantMask", OSD.FromInteger(wantmask) }, + { "WantText", OSD.FromString(wanttext) }, + { "SkillsMask", OSD.FromInteger(skillsmask) }, + { "SkillsText", OSD.FromString(skillstext) }, + { "Languages", OSD.FromString(languages) } + }; + + AddUserData(client.AgentId, "LLInterests", map); + } + + private void UserInfoRequestHandler(IClientAPI client) + { + m_log.Error("[PROFILES]: UserInfoRequestHandler"); + + // Fetch this user's e-mail address + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetUser" }, + { "UserID", client.AgentId.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + string email = response["Email"].AsString(); + + if (!response["Success"].AsBoolean()) + m_log.Warn("[PROFILES]: GetUser failed during a user info request for " + client.Name); + + client.SendUserInfoReply(false, true, email); + } + + private void UpdateUserInfoHandler(bool imViaEmail, bool visible, IClientAPI client) + { + m_log.Info("[PROFILES]: Ignoring user info update from " + client.Name); + } + + #endregion Profiles + + /// + /// Sanity checks regions for a valid estate owner at startup + /// + private void CheckEstateManager(Scene scene) + { + EstateSettings estate = scene.RegionInfo.EstateSettings; + + if (estate.EstateOwner == UUID.Zero) + { + // Attempt to lookup the grid admin + UserAccount admin = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, UUID.Zero); + if (admin != null) + { + m_log.InfoFormat("[PROFILES]: Setting estate {0} (ID: {1}) owner to {2}", estate.EstateName, + estate.EstateID, admin.Name); + + estate.EstateOwner = admin.PrincipalID; + estate.Save(); + } + else + { + m_log.WarnFormat("[PROFILES]: Estate {0} (ID: {1}) does not have an owner", estate.EstateName, estate.EstateID); + } + } + } + + private bool AddUserData(UUID userID, string key, OSDMap value) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddUserData" }, + { "UserID", userID.ToString() }, + { key, OSDParser.SerializeJsonString(value) } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (!success) + m_log.WarnFormat("[PROFILES]: Failed to add user data with key {0} for {1}: {2}", key, userID, response["Message"].AsString()); + + return success; + } + + private OSDMap FetchUserData(UUID userID) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetUser" }, + { "UserID", userID.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean() && response["User"] is OSDMap) + { + return (OSDMap)response["User"]; + } + else + { + m_log.Error("[PROFILES]: Failed to fetch user data for " + userID + ": " + response["Message"].AsString()); + } + + return null; + } + } +} diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs new file mode 100644 index 0000000..14097d0 --- /dev/null +++ b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs @@ -0,0 +1,307 @@ +/* + * 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.Collections.Specialized; +using System.IO; +using System.Reflection; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Services.Connectors.SimianGrid +{ + /// + /// Connects user account data (creating new users, looking up existing + /// users) to the SimianGrid backend + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SimianUserAccountServiceConnector : IUserAccountService, ISharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_serverUrl = String.Empty; + private ExpiringCache m_accountCache = new ExpiringCache(); + + #region ISharedRegionModule + + public Type ReplaceableInterface { get { return null; } } + public void RegionLoaded(Scene scene) { } + public void PostInitialise() { } + public void Close() { } + + public SimianUserAccountServiceConnector() { } + public string Name { get { return "SimianUserAccountServiceConnector"; } } + public void AddRegion(Scene scene) { scene.RegisterModuleInterface(this); } + public void RemoveRegion(Scene scene) { scene.UnregisterModuleInterface(this); } + + #endregion ISharedRegionModule + + public SimianUserAccountServiceConnector(IConfigSource source) + { + Initialise(source); + } + + public void Initialise(IConfigSource source) + { + IConfig assetConfig = source.Configs["UserAccountService"]; + if (assetConfig == null) + { + m_log.Error("[ACCOUNT CONNECTOR]: UserAccountService missing from OpenSim.ini"); + throw new Exception("User account connector init error"); + } + + string serviceURI = assetConfig.GetString("UserAccountServerURI"); + if (String.IsNullOrEmpty(serviceURI)) + { + m_log.Error("[ACCOUNT CONNECTOR]: No UserAccountServerURI in section UserAccountService"); + throw new Exception("User account connector init error"); + } + + m_serverUrl = serviceURI; + } + + public UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetUser" }, + { "Name", firstName + ' ' + lastName } + }; + + return GetUser(requestArgs); + } + + public UserAccount GetUserAccount(UUID scopeID, string email) + { + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetUser" }, + { "Email", email } + }; + + return GetUser(requestArgs); + } + + public UserAccount GetUserAccount(UUID scopeID, UUID userID) + { + // Cache check + UserAccount account; + if (m_accountCache.TryGetValue(userID, out account)) + return account; + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetUser" }, + { "UserID", userID.ToString() } + }; + + return GetUser(requestArgs); + } + + public List GetUserAccounts(UUID scopeID, string query) + { + List accounts = new List(); + + m_log.DebugFormat("[ACCOUNT CONNECTOR]: Searching for user accounts with name query " + query); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetUsers" }, + { "NameQuery", query } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean()) + { + OSDArray array = response["Users"] as OSDArray; + if (array != null && array.Count > 0) + { + for (int i = 0; i < array.Count; i++) + { + UserAccount account = ResponseToUserAccount(array[i] as OSDMap); + if (account != null) + accounts.Add(account); + } + } + else + { + m_log.Warn("[ACCOUNT CONNECTOR]: Account search failed, response data was in an invalid format"); + } + } + else + { + m_log.Warn("[ACCOUNT CONNECTOR]: Failed to search for account data by name " + query); + } + + return accounts; + } + + public bool StoreUserAccount(UserAccount data) + { + m_log.InfoFormat("[ACCOUNT CONNECTOR]: Storing user account for " + data.Name); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "AddUser" }, + { "UserID", data.PrincipalID.ToString() }, + { "Name", data.Name }, + { "Email", data.Email }, + { "AccessLevel", data.UserLevel.ToString() } + }; + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + + if (response["Success"].AsBoolean()) + { + m_log.InfoFormat("[ACCOUNT CONNECTOR]: Storing user account data for " + data.Name); + + requestArgs = new NameValueCollection + { + { "RequestMethod", "AddUserData" }, + { "UserID", data.PrincipalID.ToString() }, + { "CreationDate", data.Created.ToString() }, + { "UserFlags", data.UserFlags.ToString() }, + { "UserTitle", data.UserTitle } + }; + + response = WebUtil.PostToService(m_serverUrl, requestArgs); + bool success = response["Success"].AsBoolean(); + + if (success) + { + // Cache the user account info + m_accountCache.AddOrUpdate(data.PrincipalID, data, DateTime.Now + TimeSpan.FromMinutes(2.0d)); + } + else + { + m_log.Warn("[ACCOUNT CONNECTOR]: Failed to store user account data for " + data.Name + ": " + response["Message"].AsString()); + } + + return success; + } + else + { + m_log.Warn("[ACCOUNT CONNECTOR]: Failed to store user account for " + data.Name + ": " + response["Message"].AsString()); + } + + return false; + } + + /// + /// Helper method for the various ways of retrieving a user account + /// + /// Service query parameters + /// A UserAccount object on success, null on failure + private UserAccount GetUser(NameValueCollection requestArgs) + { + string lookupValue = (requestArgs.Count > 1) ? requestArgs[1] : "(Unknown)"; + m_log.DebugFormat("[ACCOUNT CONNECTOR]: Looking up user account with query: " + lookupValue); + + OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); + if (response["Success"].AsBoolean()) + { + OSDMap user = response["User"] as OSDMap; + if (user != null) + return ResponseToUserAccount(user); + else + m_log.Warn("[ACCOUNT CONNECTOR]: Account search failed, response data was in an invalid format"); + } + else + { + m_log.Warn("[ACCOUNT CONNECTOR]: Failed to lookup user account with query: " + lookupValue); + } + + return null; + } + + /// + /// Convert a User object in LLSD format to a UserAccount + /// + /// LLSD containing user account data + /// A UserAccount object on success, null on failure + private UserAccount ResponseToUserAccount(OSDMap response) + { + if (response == null) + return null; + + UserAccount account = new UserAccount(); + account.PrincipalID = response["UserID"].AsUUID(); + account.Created = response["CreationDate"].AsInteger(); + account.Email = response["Email"].AsString(); + account.ServiceURLs = new Dictionary(0); + account.UserFlags = response["UserFlags"].AsInteger(); + account.UserLevel = response["AccessLevel"].AsInteger(); + account.UserTitle = response["UserTitle"].AsString(); + GetFirstLastName(response["Name"].AsString(), out account.FirstName, out account.LastName); + + // Cache the user account info + m_accountCache.AddOrUpdate(account.PrincipalID, account, DateTime.Now + TimeSpan.FromMinutes(2.0d)); + + return account; + } + + /// + /// Convert a name with a single space in it to a first and last name + /// + /// A full name such as "John Doe" + /// First name + /// Last name (surname) + private static void GetFirstLastName(string name, out string firstName, out string lastName) + { + if (String.IsNullOrEmpty(name)) + { + firstName = String.Empty; + lastName = String.Empty; + } + else + { + string[] names = name.Split(' '); + + if (names.Length == 2) + { + firstName = names[0]; + lastName = names[1]; + } + else + { + firstName = String.Empty; + lastName = name; + } + } + } + } +} diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 74100f5..23c3241 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -1248,6 +1248,7 @@ ;Include-HGStandalone = "config-include/StandaloneHypergrid.ini" ;Include-Grid = "config-include/Grid.ini" ;Include-HGGrid = "config-include/GridHypergrid.ini" + ;Include-SimianGrid = "config-include/SimianGrid.ini" ; Then choose ; config-include/StandaloneCommon.ini.example (if you're in standlone) OR diff --git a/bin/config-include/SimianGrid.ini b/bin/config-include/SimianGrid.ini new file mode 100644 index 0000000..af33860 --- /dev/null +++ b/bin/config-include/SimianGrid.ini @@ -0,0 +1,70 @@ +[Modules] + GridServices = "OpenSim.Services.Connectors.dll:SimianGridServiceConnector" + PresenceServices = "OpenSim.Services.Connectors.dll:SimianPresenceServiceConnector" + UserAccountServices = "OpenSim.Services.Connectors.dll:SimianGridUserAccountServiceConnector" + AuthenticationServices = "OpenSim.Services.Connectors.dll:SimianAuthenticationServiceConnector" + AssetServices = "OpenSim.Services.Connectors.dll:SimianAssetServiceConnector" + InventoryServices = "OpenSim.Services.Connectors.dll:SimianInventoryServiceConnector" + AvatarServices = "OpenSim.Services.Connectors.dll:SimianAvatarServiceConnector" + + NeighbourServices = "RemoteNeighbourServicesConnector" + SimulationServices = "RemoteSimulationConnectorModule" + EntityTransferModule = "BasicEntityTransferModule" + InventoryAccessModule = "BasicInventoryAccessModule" + + LandServiceInConnector = true + NeighbourServiceInConnector = true + SimulationServiceInConnector = true + LibraryModule = false + + AssetCaching = "FlotsamAssetCache" + +[Friends] + Connector = "OpenSim.Services.Connectors.dll:SimianFriendsServiceConnector" + +[GridService] + LocalServiceModule = "OpenSim.Services.GridService.dll:GridService" + StorageProvider = "OpenSim.Data.Null.dll:NullRegionData" + GridServerURI = "http://localhost/Grid/" + +[LibraryService] + LocalServiceModule = "OpenSim.Services.InventoryService.dll:LibraryService" + LibraryName = "OpenSim Library" + DefaultLibrary = "./inventory/Libraries.xml" + +[AssetService] + DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll" + AssetLoaderArgs = "assets/AssetSets.xml" + AssetServerURI = "http://localhost/Grid/?id=" + +[InventoryService] + InventoryServerURI = "http://localhost/Grid/" + +[AvatarService] + AvatarServerURI = "http://localhost/Grid/" + +[PresenceService] + PresenceServerURI = "http://localhost/Grid/" + +[UserAccountService] + UserAccountServerURI = "http://localhost/Grid/" + +[AuthenticationService] + AuthenticationServerURI = "http://localhost/Grid/" + +[FriendsService] + FriendsServerURI = "http://localhost/Grid/" + +[AssetCache] + CacheDirectory = ./assetcache + LogLevel = 0 + HitRateDisplay = 100 + MemoryCacheEnabled = false + ; How long {in hours} to keep assets cached in memory, .5 == 30 minutes + MemoryCacheTimeout = 2 + ; How long {in hours} to keep assets cached on disk, .5 == 30 minutes + ; Specify 0 if you do not want your disk cache to expire + FileCacheTimeout = 0 + ; How often {in hours} should the disk be checked for expired filed + ; Specify 0 to disable expiration checking + FileCleanupTimer = 0 ;roughly every 10 minutes diff --git a/prebuild.xml b/prebuild.xml index cf0eecc..5cc742c 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -929,7 +929,9 @@ + + -- cgit v1.1 From a578feefba7d740180b8c891fc9e257dbb4ab48d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Mar 2010 20:20:38 +0000 Subject: very minor spacing adjustment --- OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs index d13408d..5ee2045 100644 --- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs @@ -73,7 +73,6 @@ namespace OpenSim.Framework.Servers.HttpServer /// true if the handler was successfully registered, false if a handler with the same name already existed. /// bool AddHTTPHandler(string methodName, GenericHTTPMethod handler); - bool AddPollServiceHTTPHandler(string methodName, GenericHTTPMethod handler, PollServiceEventArgs args); -- cgit v1.1 From e844524b4130bae62d0ede3ae4fa123b96848aac Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Mar 2010 21:04:56 +0000 Subject: Upgrade Newtonsoft.Json.dll from 1.3 to 3.5r6 Actually using the one built against Net 2.0 (labelled Newtonsoft.Json.Net20.dll) since the 3.5 build is not compatible with Mono 2.4 (though it is with Mono 2.6) --- CONTRIBUTORS.txt | 1 + bin/Newtonsoft.Json.XML | 6817 ++++++++++++++++++++++++++++++++++++++++------- bin/Newtonsoft.Json.dll | Bin 73728 -> 356352 bytes bin/Newtonsoft.Json.pdb | Bin 192000 -> 742912 bytes 4 files changed, 5828 insertions(+), 990 deletions(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 5b4959a..e5c8cb9 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -164,6 +164,7 @@ This software uses components from the following developers: * log4net (http://logging.apache.org/log4net/) * GlynnTucker.Cache (http://gtcache.sourceforge.net/) * NDesk.Options 0.2.1 (http://www.ndesk.org/Options) +* Json.NET 3.5 Release 6. The binary used is actually Newtonsoft.Json.Net20.dll for Mono 2.4 compatability (http://james.newtonking.com/projects/json-net.aspx) Some plugins are based on Cable Beach Cable Beach is Copyright (c) 2008 Intel Corporation diff --git a/bin/Newtonsoft.Json.XML b/bin/Newtonsoft.Json.XML index b84e336..5af3593 100644 --- a/bin/Newtonsoft.Json.XML +++ b/bin/Newtonsoft.Json.XML @@ -1,990 +1,5827 @@ - - - - Newtonsoft.Json - - - - - Determines whether the string contains white space. - - The string to test for white space. - - true if the string contains white space; otherwise, false. - - - - - Determines whether the string is all white space. Empty string will return false. - - The string to test whether it is all white space. - - true if the string is all white space; otherwise, false. - - - - - Ensures the target string ends with the specified string. - - The target. - The value. - The target string with the value string at the end. - - - - Determines whether the SqlString is null or empty. - - The string. - - true if the SqlString is null or empty; otherwise, false. - - - - - Perform an action if the string is not null or empty. - - The value. - The action to perform. - - - - Indents the specified string. - - The string to indent. - The number of characters to indent by. - - - - - Indents the specified string. - - The string to indent. - The number of characters to indent by. - The indent character. - - - - - Numbers the lines. - - The string to number. - - - - - Nulls an empty string. - - The string. - Null if the string was null, otherwise the string unchanged. - - - - The exception thrown when an error occurs while reading Json text. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class - with a specified error message. - - The error message that explains the reason for the exception. - - - - Initializes a new instance of the class - with a specified error message and a reference to the inner exception that is the cause of this exception. - - The error message that explains the reason for the exception. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Gets the type of the typed list's items. - - The type. - The type of the typed list's items. - - - - Tests whether the list's items are their unitialized value. - - The list. - Whether the list's items are their unitialized value - - - - Gets the member's underlying type. - - The member. - The underlying type of the member. - - - - Determines whether the member is an indexed property. - - The member. - - true if the member is an indexed property; otherwise, false. - - - - - Determines whether the property is an indexed property. - - The property. - - true if the property is an indexed property; otherwise, false. - - - - - Gets the member's value on the object. - - The member. - The target object. - The member's value on the object. - - - - Sets the member's value on the target object. - - The member. - The target. - The value. - - - - Determines whether the specified MemberInfo can be read. - - The MemberInfo to determine whether can be read. - - true if the specified MemberInfo can be read; otherwise, false. - - - - - Determines whether the specified MemberInfo can be set. - - The MemberInfo to determine whether can be set. - - true if the specified MemberInfo can be set; otherwise, false. - - - - - Specifies reference loop handling options for the . - - - - - Throw a when a loop is encountered. - - - - - Ignore loop references and do not serialize. - - - - - Serialize loop references. - - - - - Serializes and deserializes objects into and from the Json format. - The enables you to control how objects are encoded into Json. - - - - - Initializes a new instance of the class. - - - - - Deserializes the Json structure contained by the specified . - - The that contains the Json structure to deserialize. - The being deserialized. - - - - Deserializes the Json structure contained by the specified - into an instance of the specified type. - - The type of object to create. - The of object being deserialized. - The instance of being deserialized. - - - - Serializes the specified and writes the Json structure - to a Stream using the specified . - - The used to write the Json structure. - The to serialize. - - - - Serializes the specified and writes the Json structure - to a Stream using the specified . - - The used to write the Json structure. - The to serialize. - - - - Get or set how reference loops (e.g. a class referencing itself) is handled. - - - - - Represents a JavaScript array. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class that - contains elements copied from the specified collection. - - The collection whose elements are copied to the new array. - - - - Initializes a new instance of the class that - is empty and has the specified initial capacity. - - The number of elements that the new array can initially store. - - - - Provides methods for converting between common language runtime types and JavaScript types. - - - - - Represents JavaScript's boolean value true as a string. This field is read-only. - - - - - Represents JavaScript's boolean value false as a string. This field is read-only. - - - - - Represents JavaScript's null as a string. This field is read-only. - - - - - Represents JavaScript's undefined as a string. This field is read-only. - - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - The string delimiter character. - A Json string representation of the . - - - - Converts the to it's JavaScript string representation. - - The value to convert. - A Json string representation of the . - - - - Serializes the specified object to a Json object. - - The object to serialize. - A Json string representation of the object. - - - - Deserializes the specified object to a Json object. - - The object to deserialize. - The deserialized object from the Json string. - - - - Deserializes the specified object to a Json object. - - The object to deserialize. - The of object being deserialized. - The deserialized object from the Json string. - - - - Deserializes the specified object to a Json object. - - The type of the object to deserialize. - The object to deserialize. - The deserialized object from the Json string. - - - - Deserializes the specified object to a Json object. - - The type of the object to deserialize. - The object to deserialize. - Converters to use while deserializing. - The deserialized object from the Json string. - - - - The exception thrown when an error occurs during Json serialization or deserialization. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class - with a specified error message. - - The error message that explains the reason for the exception. - - - - Initializes a new instance of the class - with a specified error message and a reference to the inner exception that is the cause of this exception. - - The error message that explains the reason for the exception. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - The exception thrown when an error occurs while reading Json text. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class - with a specified error message. - - The error message that explains the reason for the exception. - - - - Initializes a new instance of the class - with a specified error message and a reference to the inner exception that is the cause of this exception. - - The error message that explains the reason for the exception. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Represents a JavaScript constructor. - - - - - Determines whether the collection is null or empty. - - The collection. - - true if the collection is null or empty; otherwise, false. - - - - - Determines whether the collection is null or empty. - - The collection. - - true if the collection is null or empty; otherwise, false. - - - - - Determines whether the collection is null, empty or its contents are uninitialized values. - - The list. - - true if the collection is null or empty or its contents are uninitialized values; otherwise, false. - - - - - Makes a slice of the specified list in between the start and end indexes. - - The list. - The start index. - The end index. - A slice of the list. - - - - Makes a slice of the specified list in between the start and end indexes, - getting every so many items based upon the step. - - The list. - The start index. - The end index. - The step. - A slice of the list. - - - - Group the collection using a function which returns the key. - - The source collection to group. - The key selector. - A Dictionary with each key relating to a list of objects in a list grouped under it. - - - - Adds the elements of the specified collection to the specified generic IList. - - The list to add to. - The collection of elements to add. - - - - Builds a string. Unlike StringBuilder this class lets you reuse it's internal buffer. - - - - - Represents a JavaScript object. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class that - contains values copied from the specified . - - The whose elements are copied to the new object. - - - - Specifies the type of Json token. - - - - - This is returned by the if a method has not been called. - - - - - An object start token. - - - - - An array start token. - - - - - An object property name. - - - - - A comment. - - - - - An interger. - - - - - A float. - - - - - A string. - - - - - A boolean. - - - - - A null token. - - - - - An undefined token. - - - - - An object end token. - - - - - An array end token. - - - - - A JavaScript object constructor. - - - - - A Date. - - - - - Checks if the attributeName is a namespace attribute. - - Attribute name to test. - The attribute name prefix if it has one, otherwise an empty string. - True if attribute name is for a namespace attribute, otherwise false. - - - - Specifies the state of the . - - - - - An exception has been thrown, which has left the in an invalid state. - You may call the method to put the in the Closed state. - Any other method calls results in an being thrown. - - - - - The method has been called. - - - - - An object is being written. - - - - - A array is being written. - - - - - A property is being written. - - - - - A write method has not been called. - - - - - Specifies formatting options for the . - - - - - No special formatting is applied. This is the default. - - - - - Causes child objects to be indented according to the and settings. - - - - - Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. - - - - - Creates an instance of the JsonWriter class using the specified . - - The TextWriter to write to. - - - - Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. - - - - - Closes this stream and the underlying stream. - - - - - Writes the beginning of a Json object. - - - - - Writes the end of a Json object. - - - - - Writes the beginning of a Json array. - - - - - Writes the end of an array. - - - - - Writes the property name of a name/value pair on a Json object. - - - - - - Writes the end of the current Json object or array. - - - - - Writes a null value. - - - - - Writes an undefined value. - - - - - Writes raw JavaScript manually. - - The raw JavaScript to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes out a comment /*...*/ containing the specified text. - - Text to place inside the comment. - - - - Writes out the given white space. - - The string of white space characters. - - - - Gets the state of the writer. - - - - - Indicates how the output is formatted. - - - - - Gets or sets how many IndentChars to write for each level in the hierarchy when is set to Formatting.Indented. - - - - - Gets or sets which character to use to quote attribute values. - - - - - Gets or sets which character to use for indenting when is set to Formatting.Indented. - - - - - Gets or sets a value indicating whether object names will be surrounded with quotes. - - - - - Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. - - - - - Initializes a new instance of the class with the specified . - - The TextReader containing the XML data to read. - - - - Reads the next Json token from the stream. - - - - - - Changes the to Closed. - - - - - Gets the quotation mark character used to enclose the value of a string. - - - - - Gets the type of the current Json token. - - - - - Gets the text value of the current Json token. - - - - - Gets The Common Language Runtime (CLR) type for the current Json token. - - - - + + + + Newtonsoft.Json.Net20 + + + + + Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. + + + + + Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. + + + + + Initializes a new instance of the class with the specified . + + + + + Reads the next JSON token from the stream. + + true if the next token was read successfully; false if there are no more tokens to read. + + + + Reads the next JSON token from the stream as a . + + A or a null reference if the next JSON token is null. + + + + Skips the children of the current token. + + + + + Sets the current token. + + The new token. + + + + Sets the current token and value. + + The new token. + The value. + + + + Sets the state based on current token type. + + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Releases unmanaged and - optionally - managed resources + + true to release both managed and unmanaged resources; false to release only unmanaged resources. + + + + Changes the to Closed. + + + + + Gets the current reader state. + + The current reader state. + + + + Gets the quotation mark character used to enclose the value of a string. + + + + + Gets the type of the current Json token. + + + + + Gets the text value of the current Json token. + + + + + Gets The Common Language Runtime (CLR) type for the current Json token. + + + + + Gets the depth of the current token in the JSON document. + + The depth of the current token in the JSON document. + + + + Specifies the state of the reader. + + + + + The Read method has not been called. + + + + + The end of the file has been reached successfully. + + + + + Reader is at a property. + + + + + Reader is at the start of an object. + + + + + Reader is in an object. + + + + + Reader is at the start of an array. + + + + + Reader is in an array. + + + + + The Close method has been called. + + + + + Reader has just read a value. + + + + + Reader is at the start of a constructor. + + + + + Reader in a constructor. + + + + + An error occurred that prevents the read operation from continuing. + + + + + The end of the file has been reached successfully. + + + + + Initializes a new instance of the class. + + The stream. + + + + Initializes a new instance of the class. + + The stream. + if set to true the root object will be read as a JSON array. + The used when reading values from BSON. + + + + Reads the next JSON token from the stream as a . + + + A or a null reference if the next JSON token is null. + + + + + Reads the next JSON token from the stream. + + + true if the next token was read successfully; false if there are no more tokens to read. + + + + + Gets or sets a value indicating whether the root object will be read as a JSON array. + + + true if the root object will be read as a JSON array; otherwise, false. + + + + + Gets or sets the used when reading values from BSON. + + The used when reading values from BSON. + + + + Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. + + + + + Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. + + + + + Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. + + + + + Creates an instance of the JsonWriter class. + + + + + Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + + + + + Closes this stream and the underlying stream. + + + + + Writes the beginning of a Json object. + + + + + Writes the end of a Json object. + + + + + Writes the beginning of a Json array. + + + + + Writes the end of an array. + + + + + Writes the start of a constructor with the given name. + + The name of the constructor. + + + + Writes the end constructor. + + + + + Writes the property name of a name/value pair on a Json object. + + The name of the property. + + + + Writes the end of the current Json object or array. + + + + + Writes the current token. + + The to read the token from. + + + + Writes the specified end token. + + The end token to write. + + + + Writes indent characters. + + + + + Writes the JSON value delimiter. + + + + + Writes an indent space. + + + + + Writes a null value. + + + + + Writes an undefined value. + + + + + Writes raw JSON without changing the writer's state. + + The raw JSON to write. + + + + Writes raw JSON where a value is expected and updates the writer's state. + + The raw JSON to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + An error will raised if the value cannot be written as a single JSON token. + + The value to write. + + + + Writes out a comment /*...*/ containing the specified text. + + Text to place inside the comment. + + + + Writes out the given white space. + + The string of white space characters. + + + + Gets the top. + + The top. + + + + Gets the state of the writer. + + + + + Indicates how the output is formatted. + + + + + Initializes a new instance of the class writing to the given . + + The container being written to. + + + + Initializes a new instance of the class. + + + + + Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + + + + + Closes this stream and the underlying stream. + + + + + Writes the beginning of a Json object. + + + + + Writes the beginning of a Json array. + + + + + Writes the start of a constructor with the given name. + + The name of the constructor. + + + + Writes the end. + + The token. + + + + Writes the property name of a name/value pair on a Json object. + + The name of the property. + + + + Writes a null value. + + + + + Writes an undefined value. + + + + + Writes raw JSON. + + The raw JSON to write. + + + + Writes out a comment /*...*/ containing the specified text. + + Text to place inside the comment. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Gets the token being writen. + + The token being writen. + + + + Initializes a new instance of the class. + + The stream. + + + + Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + + + + + Writes the end. + + The token. + + + + Writes out a comment /*...*/ containing the specified text. + + Text to place inside the comment. + + + + Writes the start of a constructor with the given name. + + The name of the constructor. + + + + Writes raw JSON. + + The raw JSON to write. + + + + Writes raw JSON where a value is expected and updates the writer's state. + + The raw JSON to write. + + + + Specifies how constructors are used when initializing objects during deserialization by the . + + + + + First attempt to use the public default constructor then fall back to single paramatized constructor. + + + + + Allow Json.NET to use a non-public default constructor. + + + + + Converts a binary value to and from a base 64 string value. + + + + + Converts an object to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Create a custom object + + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Creates an object which will then be populated by the serializer. + + Type of the object. + + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts a to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified value type. + + Type of the value. + + true if this instance can convert the specified value type; otherwise, false. + + + + + Converts a to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified value type. + + Type of the value. + + true if this instance can convert the specified value type; otherwise, false. + + + + + Provides a base class for converting a to and from JSON. + + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts an to and from its name string value. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Represents a view of a . + + + + + Initializes a new instance of the class. + + The name. + Type of the property. + + + + When overridden in a derived class, returns whether resetting an object changes its value. + + + true if resetting the component changes its value; otherwise, false. + + The component to test for reset capability. + + + + + When overridden in a derived class, gets the current value of the property on a component. + + + The value of a property for a given component. + + The component with the property for which to retrieve the value. + + + + + When overridden in a derived class, resets the value for this property of the component to the default value. + + The component with the property value that is to be reset to the default value. + + + + + When overridden in a derived class, sets the value of the component to a different value. + + The component with the property value that is to be set. + The new value. + + + + + When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted. + + + true if the property should be persisted; otherwise, false. + + The component with the property to be examined for persistence. + + + + + When overridden in a derived class, gets the type of the component this property is bound to. + + + A that represents the type of component this property is bound to. When the or methods are invoked, the object specified might be an instance of this type. + + + + + When overridden in a derived class, gets a value indicating whether this property is read-only. + + + true if the property is read-only; otherwise, false. + + + + + When overridden in a derived class, gets the type of the property. + + + A that represents the type of the property. + + + + + Gets the hash code for the name of the member. + + + + The hash code for the name of the member. + + + + + Represents a view of a . + + + + + Initializes a new instance of the class. + + The value. + + + + Returns the properties for this instance of a component. + + + A that represents the properties for this component instance. + + + + + Returns the properties for this instance of a component using the attribute array as a filter. + + An array of type that is used as a filter. + + A that represents the filtered properties for this component instance. + + + + + Returns a collection of custom attributes for this instance of a component. + + + An containing the attributes for this object. + + + + + Returns the class name of this instance of a component. + + + The class name of the object, or null if the class does not have a name. + + + + + Returns the name of this instance of a component. + + + The name of the object, or null if the object does not have a name. + + + + + Returns a type converter for this instance of a component. + + + A that is the converter for this object, or null if there is no for this object. + + + + + Returns the default event for this instance of a component. + + + An that represents the default event for this object, or null if this object does not have events. + + + + + Returns the default property for this instance of a component. + + + A that represents the default property for this object, or null if this object does not have properties. + + + + + Returns an editor of the specified type for this instance of a component. + + A that represents the editor for this object. + + An of the specified type that is the editor for this object, or null if the editor cannot be found. + + + + + Returns the events for this instance of a component using the specified attribute array as a filter. + + An array of type that is used as a filter. + + An that represents the filtered events for this component instance. + + + + + Returns the events for this instance of a component. + + + An that represents the events for this component instance. + + + + + Returns an object that contains the property described by the specified property descriptor. + + A that represents the property whose owner is to be found. + + An that represents the owner of the specified property. + + + + + Represents a raw JSON string. + + + + + Represents a value in JSON (string, integer, date, etc). + + + + + Represents an abstract JSON token. + + + + + Represents a collection of objects. + + The type of token + + + + Gets the with the specified key. + + + + + + Provides an interface to enable a class to return line and position information. + + + + + Gets a value indicating whether the class can return line information. + + + true if LineNumber and LinePosition can be provided; otherwise, false. + + + + + Gets the current line number. + + The current line number or 0 if no line information is available (for example, HasLineInfo returns false). + + + + Gets the current line position. + + The current line position or 0 if no line information is available (for example, HasLineInfo returns false). + + + + Compares the values of two tokens, including the values of all descendant tokens. + + The first to compare. + The second to compare. + true if the tokens are equal; otherwise false. + + + + Adds the specified content immediately after this token. + + A content object that contains simple content or a collection of content objects to be added after this token. + + + + Adds the specified content immediately before this token. + + A content object that contains simple content or a collection of content objects to be added before this token. + + + + Returns a collection of the ancestor tokens of this token. + + A collection of the ancestor tokens of this token. + + + + Returns a collection of the sibling tokens after this token, in document order. + + A collection of the sibling tokens after this tokens, in document order. + + + + Returns a collection of the sibling tokens before this token, in document order. + + A collection of the sibling tokens before this token, in document order. + + + + Gets the with the specified key converted to the specified type. + + The type to convert the token to. + The token key. + The converted token value. + + + + Returns a collection of the child tokens of this token, in document order. + + An of containing the child tokens of this , in document order. + + + + Returns a collection of the child tokens of this token, in document order, filtered by the specified type. + + The type to filter the child tokens on. + A containing the child tokens of this , in document order. + + + + Returns a collection of the child values of this token, in document order. + + The type to convert the values to. + A containing the child values of this , in document order. + + + + Removes this token from its parent. + + + + + Replaces this token with the specified token. + + The value. + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Returns the indented JSON for this token. + + + The indented JSON for this token. + + + + + Returns the JSON for this token using the given formatting and converters. + + Indicates how the output is formatted. + A collection of which will be used when writing the token. + The JSON for this token using the given formatting and converters. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Creates an for this token. + + An that can be used to read this token and its descendants. + + + + Creates a from an object. + + The object that will be used to create . + A with the value of the specified object + + + + Creates a from an object using the specified . + + The object that will be used to create . + The that will be used when reading the object. + A with the value of the specified object + + + + Creates a from a . + + An positioned at the token to read into this . + + An that contains the token and its descendant tokens + that were read from the reader. The runtime type of the token is determined + by the token type of the first token encountered in the reader. + + + + + Selects the token that matches the object path. + + + The object path from the current to the + to be returned. This must be a string of property names or array indexes separated + by periods, such as Tables[0].DefaultView[0].Price in C# or + Tables(0).DefaultView(0).Price in Visual Basic. + + The that matches the object path or a null reference if no matching token is found. + + + + Selects the token that matches the object path. + + + The object path from the current to the + to be returned. This must be a string of property names or array indexes separated + by periods, such as Tables[0].DefaultView[0].Price in C# or + Tables(0).DefaultView(0).Price in Visual Basic. + + A flag to indicate whether an error should be thrown if no token is found. + The that matches the object path. + + + + Gets a comparer that can compare two tokens for value equality. + + A that can compare two nodes for value equality. + + + + Gets or sets the parent. + + The parent. + + + + Gets the root of this . + + The root of this . + + + + Gets the node type for this . + + The type. + + + + Gets a value indicating whether this token has childen tokens. + + + true if this token has child values; otherwise, false. + + + + + Gets the next sibling token of this node. + + The that contains the next sibling token. + + + + Gets the previous sibling token of this node. + + The that contains the previous sibling token. + + + + Gets the with the specified key. + + The with the specified key. + + + + Get the first child token of this token. + + A containing the first child token of the . + + + + Get the last child token of this token. + + A containing the last child token of the . + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Creates a comment with the given value. + + The value. + A comment with the given value. + + + + Creates a string with the given value. + + The value. + A string with the given value. + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Indicates whether the current object is equal to another object of the same type. + + + true if the current object is equal to the parameter; otherwise, false. + + An object to compare with this object. + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + The parameter is null. + + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + Gets a value indicating whether this token has childen tokens. + + + true if this token has child values; otherwise, false. + + + + + Gets the node type for this . + + The type. + + + + Gets or sets the underlying token value. + + The underlying token value. + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class. + + The raw json. + + + + Creates an instance of with the content of the reader's current token. + + The reader. + An instance of with the content of the reader's current token. + + + + Indicating whether a property is required. + + + + + The property is not required. The default state. + + + + + The property must be defined in JSON but can be a null value. + + + + + The property must be defined in JSON and cannot be a null value. + + + + + Used to resolve references when serializing and deserializing JSON by the . + + + + + Resolves a reference to its object. + + The reference to resolve. + The object that + + + + Gets the reference for the sepecified object. + + The object to get a reference for. + The reference to the object. + + + + Determines whether the specified object is referenced. + + The object to test for a reference. + + true if the specified object is referenced; otherwise, false. + + + + + Adds a reference to the specified object. + + The reference. + The object to reference. + + + + Specifies reference handling options for the . + + + + + Do not preserve references when serializing types. + + + + + Preserve references when serializing into a JSON object structure. + + + + + Preserve references when serializing into a JSON array structure. + + + + + Preserve references when serializing. + + + + + Instructs the how to serialize the collection. + + + + + Instructs the how to serialize the object. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the specified container Id. + + The container Id. + + + + Gets or sets the id. + + The id. + + + + Gets or sets the title. + + The title. + + + + Gets or sets the description. + + The description. + + + + Gets or sets a value that indicates whether to preserve object reference data. + + + true to keep object reference; otherwise, false. The default is false. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with a flag indicating whether the array can contain null items + + A flag indicating whether the array can contain null items. + + + + Initializes a new instance of the class with the specified container Id. + + The container Id. + + + + Gets or sets a value indicating whether null items are allowed in the collection. + + true if null items are allowed in the collection; otherwise, false. + + + + Specifies default value handling options for the . + + + + + Include null values when serializing and deserializing objects. + + + + + Ignore null values when serializing and deserializing objects. + + + + + Instructs the to use the specified when serializing the member or class. + + + + + Initializes a new instance of the class. + + Type of the converter. + + + + Gets the type of the converter. + + The type of the converter. + + + + Instructs the how to serialize the object. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the specified member serialization. + + The member serialization. + + + + Initializes a new instance of the class with the specified container Id. + + The container Id. + + + + Gets or sets the member serialization. + + The member serialization. + + + + Specifies the settings on a object. + + + + + Initializes a new instance of the class. + + + + + Gets or sets how reference loops (e.g. a class referencing itself) is handled. + + Reference loop handling. + + + + Gets or sets how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. + + Missing member handling. + + + + Gets or sets how objects are created during deserialization. + + The object creation handling. + + + + Gets or sets how null values are handled during serialization and deserialization. + + Null value handling. + + + + Gets or sets how null default are handled during serialization and deserialization. + + The default value handling. + + + + Gets or sets a collection that will be used during serialization. + + The converters. + + + + Gets or sets how object references are preserved by the serializer. + + The preserve references handling. + + + + Gets or sets how type name writing and reading is handled by the serializer. + + The type name handling. + + + + Gets or sets how constructors are used during deserialization. + + The constructor handling. + + + + Gets or sets the contract resolver used by the serializer when + serializing .NET objects to JSON and vice versa. + + The contract resolver. + + + + Gets or sets the used by the serializer when resolving references. + + The reference resolver. + + + + Gets or sets the used by the serializer when resolving type names. + + The binder. + + + + Gets or sets the error handler called during serialization and deserialization. + + The error handler called during serialization and deserialization. + + + + Gets or sets the used by the serializer when invoking serialization callback methods. + + The context. + + + + Represents a reader that provides validation. + + + + + Initializes a new instance of the class that + validates the content returned from the given . + + The to read from while validating. + + + + Reads the next JSON token from the stream as a . + + + A or a null reference if the next JSON token is null. + + + + + Reads the next JSON token from the stream. + + + true if the next token was read successfully; false if there are no more tokens to read. + + + + + Sets an event handler for receiving schema validation errors. + + + + + Gets the text value of the current Json token. + + + + + + Gets the depth of the current token in the JSON document. + + The depth of the current token in the JSON document. + + + + Gets the quotation mark character used to enclose the value of a string. + + + + + + Gets the type of the current Json token. + + + + + + Gets The Common Language Runtime (CLR) type for the current Json token. + + + + + + Gets or sets the schema. + + The schema. + + + + Gets the used to construct this . + + The specified in the constructor. + + + + Compares tokens to determine whether they are equal. + + + + + Determines whether the specified objects are equal. + + The first object of type to compare. + The second object of type to compare. + + true if the specified objects are equal; otherwise, false. + + + + + Returns a hash code for the specified object. + + The for which a hash code is to be returned. + A hash code for the specified object. + The type of is a reference type and is null. + + + + Specifies the member serialization options for the . + + + + + All members are serialized by default. Members can be excluded using the . + + + + + Only members must be marked with the are serialized. + + + + + Specifies how object creation is handled by the . + + + + + Reuse existing objects, create new objects when needed. + + + + + Only reuse existing objects. + + + + + Always create new objects. + + + + + Converts a to and from the ISO 8601 date format (e.g. 2008-04-12T12:53Z). + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Gets or sets the date time styles used when converting a date to and from JSON. + + The date time styles used when converting a date to and from JSON. + + + + Gets or sets the date time format used when converting a date to and from JSON. + + The date time format used when converting a date to and from JSON. + + + + Gets or sets the culture used when converting a date to and from JSON. + + The culture used when converting a date to and from JSON. + + + + Converts a to and from a JavaScript date constructor (e.g. new Date(52231943)). + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Specifies whether a DateTime object represents a local time, a Coordinated Universal Time (UTC), or is not specified as either local time or UTC. + + + + + The time represented is local time. + + + + + The time represented is UTC. + + + + + The time represented is not specified as either local time or Coordinated Universal Time (UTC). + + + + + Preserves the DateTimeKind field of a date when a DateTime object is converted to a string and the string is then converted back to a DateTime object. + + + + + Converts an to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The calling serializer. + The value. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Checks if the attributeName is a namespace attribute. + + Attribute name to test. + The attribute name prefix if it has one, otherwise an empty string. + True if attribute name is for a namespace attribute, otherwise false. + + + + Determines whether this instance can convert the specified value type. + + Type of the value. + + true if this instance can convert the specified value type; otherwise, false. + + + + + Gets or sets the name of the root element to insert when deserializing to XML if the JSON structure has produces multiple root elements. + + The name of the deserialize root element. + + + + Converts a object to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The calling serializer. + The value. + + + + Determines whether this instance can convert the specified value type. + + Type of the value. + + true if this instance can convert the specified value type; otherwise, false. + + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. + + + + + Initializes a new instance of the class with the specified . + + The TextReader containing the XML data to read. + + + + Reads the next JSON token from the stream. + + + true if the next token was read successfully; false if there are no more tokens to read. + + + + + Reads the next JSON token from the stream as a . + + + A or a null reference if the next JSON token is null. + + + + + Changes the state to closed. + + + + + Gets a value indicating whether the class can return line information. + + + true if LineNumber and LinePosition can be provided; otherwise, false. + + + + + Gets the current line number. + + + The current line number or 0 if no line information is available (for example, HasLineInfo returns false). + + + + + Gets the current line position. + + + The current line position or 0 if no line information is available (for example, HasLineInfo returns false). + + + + + Instructs the to always serialize the member with the specified name. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the specified name. + + Name of the property. + + + + Gets or sets the null value handling used when serializing this property. + + The null value handling. + + + + Gets or sets the default value handling used when serializing this property. + + The default value handling. + + + + Gets or sets the reference loop handling used when serializing this property. + + The reference loop handling. + + + + Gets or sets the object creation handling used when deserializing this property. + + The object creation handling. + + + + Gets or sets whether this property's value is serialized as a reference. + + Whether this property's value is serialized as a reference. + + + + Gets or sets the name of the property. + + The name of the property. + + + + Gets or sets a value indicating whether this property is required. + + + A value indicating whether this property is required. + + + + + Instructs the not to serialize the public field or public read/write property value. + + + + + Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. + + + + + Creates an instance of the JsonWriter class using the specified . + + The TextWriter to write to. + + + + Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + + + + + Closes this stream and the underlying stream. + + + + + Writes the beginning of a Json object. + + + + + Writes the beginning of a Json array. + + + + + Writes the start of a constructor with the given name. + + The name of the constructor. + + + + Writes the specified end token. + + The end token to write. + + + + Writes the property name of a name/value pair on a Json object. + + The name of the property. + + + + Writes indent characters. + + + + + Writes the JSON value delimiter. + + + + + Writes an indent space. + + + + + Writes a null value. + + + + + Writes an undefined value. + + + + + Writes raw JSON. + + The raw JSON to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes out a comment /*...*/ containing the specified text. + + Text to place inside the comment. + + + + Writes out the given white space. + + The string of white space characters. + + + + Gets or sets how many IndentChars to write for each level in the hierarchy when is set to Formatting.Indented. + + + + + Gets or sets which character to use to quote attribute values. + + + + + Gets or sets which character to use for indenting when is set to Formatting.Indented. + + + + + Gets or sets a value indicating whether object names will be surrounded with quotes. + + + + + The exception thrown when an error occurs while reading Json text. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + The exception thrown when an error occurs while reading Json text. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + Gets the line number indicating where the error occurred. + + The line number indicating where the error occurred. + + + + Gets the line position indicating where the error occurred. + + The line position indicating where the error occurred. + + + + Represents a collection of . + + + + + Provides methods for converting between common language runtime types and JSON types. + + + + + Represents JavaScript's boolean value true as a string. This field is read-only. + + + + + Represents JavaScript's boolean value false as a string. This field is read-only. + + + + + Represents JavaScript's null as a string. This field is read-only. + + + + + Represents JavaScript's undefined as a string. This field is read-only. + + + + + Represents JavaScript's positive infinity as a string. This field is read-only. + + + + + Represents JavaScript's negative infinity as a string. This field is read-only. + + + + + Represents JavaScript's NaN as a string. This field is read-only. + + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + The string delimiter character. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Serializes the specified object to a JSON string. + + The object to serialize. + A JSON string representation of the object. + + + + Serializes the specified object to a JSON string. + + The object to serialize. + Indicates how the output is formatted. + + A JSON string representation of the object. + + + + + Serializes the specified object to a JSON string using a collection of . + + The object to serialize. + A collection converters used while serializing. + A JSON string representation of the object. + + + + Serializes the specified object to a JSON string using a collection of . + + The object to serialize. + Indicates how the output is formatted. + A collection converters used while serializing. + A JSON string representation of the object. + + + + Serializes the specified object to a JSON string using a collection of . + + The object to serialize. + Indicates how the output is formatted. + The used to serialize the object. + If this is null, default serialization settings will be is used. + + A JSON string representation of the object. + + + + + Deserializes the specified object to a Json object. + + The object to deserialize. + The deserialized object from the Json string. + + + + Deserializes the specified object to a Json object. + + The object to deserialize. + The of object being deserialized. + The deserialized object from the Json string. + + + + Deserializes the specified object to a Json object. + + The type of the object to deserialize. + The object to deserialize. + The deserialized object from the Json string. + + + + Deserializes the specified JSON to the given anonymous type. + + + The anonymous type to deserialize to. This can't be specified + traditionally and must be infered from the anonymous type passed + as a parameter. + + The object to deserialize. + The anonymous type object. + The deserialized anonymous type from the JSON string. + + + + Deserializes the JSON string to the specified type. + + The type of the object to deserialize. + The object to deserialize. + Converters to use while deserializing. + The deserialized object from the JSON string. + + + + Deserializes the JSON string to the specified type. + + The type of the object to deserialize. + The object to deserialize. + + The used to deserialize the object. + If this is null, default serialization settings will be is used. + + The deserialized object from the JSON string. + + + + Deserializes the JSON string to the specified type. + + The object to deserialize. + The type of the object to deserialize. + Converters to use while deserializing. + The deserialized object from the JSON string. + + + + Deserializes the JSON string to the specified type. + + The JSON to deserialize. + The type of the object to deserialize. + + The used to deserialize the object. + If this is null, default serialization settings will be is used. + + The deserialized object from the JSON string. + + + + Populates the object with values from the JSON string. + + The JSON to populate values from. + The target object to populate values onto. + + + + Populates the object with values from the JSON string. + + The JSON to populate values from. + The target object to populate values onto. + + The used to deserialize the object. + If this is null, default serialization settings will be is used. + + + + + Serializes the XML node to a JSON string. + + The node to serialize. + A JSON string of the XmlNode. + + + + Deserializes the XmlNode from a JSON string. + + The JSON string. + The deserialized XmlNode + + + + Deserializes the XmlNode from a JSON string nested in a root elment. + + The JSON string. + The name of the root element to append when deserializing. + The deserialized XmlNode + + + + The exception thrown when an error occurs during Json serialization or deserialization. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + Serializes and deserializes objects into and from the JSON format. + The enables you to control how objects are encoded into JSON. + + + + + Initializes a new instance of the class. + + + + + Creates a new instance using the specified . + + The settings to be applied to the . + A new instance using the specified . + + + + Populates the JSON values onto the target object. + + The that contains the JSON structure to reader values from. + The target object to populate values onto. + + + + Populates the JSON values onto the target object. + + The that contains the JSON structure to reader values from. + The target object to populate values onto. + + + + Deserializes the Json structure contained by the specified . + + The that contains the JSON structure to deserialize. + The being deserialized. + + + + Deserializes the Json structure contained by the specified + into an instance of the specified type. + + The containing the object. + The of object being deserialized. + The instance of being deserialized. + + + + Deserializes the Json structure contained by the specified + into an instance of the specified type. + + The containing the object. + The type of the object to deserialize. + The instance of being deserialized. + + + + Deserializes the Json structure contained by the specified + into an instance of the specified type. + + The containing the object. + The of object being deserialized. + The instance of being deserialized. + + + + Serializes the specified and writes the Json structure + to a Stream using the specified . + + The used to write the Json structure. + The to serialize. + + + + Serializes the specified and writes the Json structure + to a Stream using the specified . + + The used to write the Json structure. + The to serialize. + + + + Occurs when the errors during serialization and deserialization. + + + + + Gets or sets the used by the serializer when resolving references. + + + + + Gets or sets the used by the serializer when resolving type names. + + + + + Gets or sets how type name writing and reading is handled by the serializer. + + + + + Gets or sets how object references are preserved by the serializer. + + + + + Get or set how reference loops (e.g. a class referencing itself) is handled. + + + + + Get or set how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. + + + + + Get or set how null values are handled during serialization and deserialization. + + + + + Get or set how null default are handled during serialization and deserialization. + + + + + Gets or sets how objects are created during deserialization. + + The object creation handling. + + + + Gets or sets how constructors are used during deserialization. + + The constructor handling. + + + + Gets a collection that will be used during serialization. + + Collection that will be used during serialization. + + + + Gets or sets the contract resolver used by the serializer when + serializing .NET objects to JSON and vice versa. + + + + + Gets or sets the used by the serializer when invoking serialization callback methods. + + The context. + + + + Contains the LINQ to JSON extension methods. + + + + + Returns a collection of tokens that contains the ancestors of every token in the source collection. + + The type of the objects in source, constrained to . + An of that contains the source collection. + An of that contains the ancestors of every node in the source collection. + + + + Returns a collection of tokens that contains the descendants of every token in the source collection. + + The type of the objects in source, constrained to . + An of that contains the source collection. + An of that contains the descendants of every node in the source collection. + + + + Returns a collection of child properties of every object in the source collection. + + An of that contains the source collection. + An of that contains the properties of every object in the source collection. + + + + Returns a collection of child values of every object in the source collection with the given key. + + An of that contains the source collection. + The token key. + An of that contains the values of every node in the source collection with the given key. + + + + Returns a collection of child values of every object in the source collection. + + An of that contains the source collection. + An of that contains the values of every node in the source collection. + + + + Returns a collection of converted child values of every object in the source collection with the given key. + + The type to convert the values to. + An of that contains the source collection. + The token key. + An that contains the converted values of every node in the source collection with the given key. + + + + Returns a collection of converted child values of every object in the source collection. + + The type to convert the values to. + An of that contains the source collection. + An that contains the converted values of every node in the source collection. + + + + Converts the value. + + The type to convert the value to. + A cast as a of . + A converted value. + + + + Converts the value. + + The source collection type. + The type to convert the value to. + A cast as a of . + A converted value. + + + + Returns a collection of child tokens of every array in the source collection. + + The source collection type. + An of that contains the source collection. + An of that contains the values of every node in the source collection. + + + + Returns a collection of converted child tokens of every array in the source collection. + + An of that contains the source collection. + The type to convert the values to. + The source collection type. + An that contains the converted values of every node in the source collection. + + + + Returns the input typed as . + + An of that contains the source collection. + The input typed as . + + + + Returns the input typed as . + + The source collection type. + An of that contains the source collection. + The input typed as . + + + + Represents a JSON constructor. + + + + + Represents a token that can contain other tokens. + + + + + Raises the event. + + The instance containing the event data. + + + + Raises the event. + + The instance containing the event data. + + + + Returns a collection of the child tokens of this token, in document order. + + + An of containing the child tokens of this , in document order. + + + + + Returns a collection of the child values of this token, in document order. + + The type to convert the values to. + + A containing the child values of this , in document order. + + + + + Returns a collection of the descendant tokens for this token in document order. + + An containing the descendant tokens of the . + + + + Adds the specified content as children of this . + + The content to be added. + + + + Adds the specified content as the first children of this . + + The content to be added. + + + + Creates an that can be used to add tokens to the . + + An that is ready to have content written to it. + + + + Replaces the children nodes of this token with the specified content. + + The content. + + + + Removes the child nodes from this token. + + + + + Occurs when the list changes or an item in the list changes. + + + + + Occurs before an item is added to the collection. + + + + + Gets a value indicating whether this token has childen tokens. + + + true if this token has child values; otherwise, false. + + + + + Get the first child token of this token. + + + A containing the first child token of the . + + + + + Get the last child token of this token. + + + A containing the last child token of the . + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class with the specified name and content. + + The constructor name. + The contents of the constructor. + + + + Initializes a new instance of the class with the specified name and content. + + The constructor name. + The contents of the constructor. + + + + Initializes a new instance of the class with the specified name. + + The constructor name. + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Loads an from a . + + A that will be read for the content of the . + A that contains the JSON that was read from the specified . + + + + Gets or sets the name of this constructor. + + The constructor name. + + + + Gets the node type for this . + + The type. + + + + Gets the with the specified key. + + The with the specified key. + + + + Represents a collection of objects. + + The type of token + + + + An empty collection of objects. + + + + + Initializes a new instance of the struct. + + The enumerable. + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Returns an enumerator that iterates through a collection. + + + An object that can be used to iterate through the collection. + + + + + Determines whether the specified is equal to this instance. + + The to compare with this instance. + + true if the specified is equal to this instance; otherwise, false. + + + + + Returns a hash code for this instance. + + + A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + + + + + Gets the with the specified key. + + + + + + Represents a JSON object. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class with the specified content. + + The contents of the object. + + + + Initializes a new instance of the class with the specified content. + + The contents of the object. + + + + Gets an of this object's properties. + + An of this object's properties. + + + + Gets a the specified name. + + The property name. + A with the specified name or null. + + + + Gets an of this object's property values. + + An of this object's property values. + + + + Loads an from a . + + A that will be read for the content of the . + A that contains the JSON that was read from the specified . + + + + Load a from a string that contains JSON. + + A that contains JSON. + A populated from the string that contains JSON. + + + + Creates a from an object. + + The object that will be used to create . + A with the values of the specified object + + + + Creates a from an object. + + The object that will be used to create . + The that will be used to read the object. + A with the values of the specified object + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Adds the specified property name. + + Name of the property. + The value. + + + + Removes the property with the specified name. + + Name of the property. + true if item was successfully removed; otherwise, false. + + + + Tries the get value. + + Name of the property. + The value. + true if a value was successfully retrieved; otherwise, false. + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Raises the event with the provided arguments. + + Name of the property. + + + + Occurs when a property value changes. + + + + + Gets the node type for this . + + The type. + + + + Gets the with the specified key. + + The with the specified key. + + + + Gets or sets the with the specified property name. + + + + + + Gets the number of elements contained in the . + + + The number of elements contained in the . + + + + Represents a JSON array. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class with the specified content. + + The contents of the array. + + + + Initializes a new instance of the class with the specified content. + + The contents of the array. + + + + Loads an from a . + + A that will be read for the content of the . + A that contains the JSON that was read from the specified . + + + + Load a from a string that contains JSON. + + A that contains JSON. + A populated from the string that contains JSON. + + + + Creates a from an object. + + The object that will be used to create . + A with the values of the specified object + + + + Creates a from an object. + + The object that will be used to create . + The that will be used to read the object. + A with the values of the specified object + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Determines the index of a specific item in the . + + The object to locate in the . + + The index of if found in the list; otherwise, -1. + + + + + Inserts an item to the at the specified index. + + The zero-based index at which should be inserted. + The object to insert into the . + + is not a valid index in the . + The is read-only. + + + + Removes the item at the specified index. + + The zero-based index of the item to remove. + + is not a valid index in the . + The is read-only. + + + + Adds an item to the . + + The object to add to the . + The is read-only. + + + + Removes all items from the . + + The is read-only. + + + + Determines whether the contains a specific value. + + The object to locate in the . + + true if is found in the ; otherwise, false. + + + + + Removes the first occurrence of a specific object from the . + + The object to remove from the . + + true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . + + The is read-only. + + + + Gets the node type for this . + + The type. + + + + Gets the with the specified key. + + The with the specified key. + + + + Gets or sets the at the specified index. + + + + + + Gets the number of elements contained in the . + + + The number of elements contained in the . + + + + Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. + + + + + Initializes a new instance of the class. + + The token to read from. + + + + Reads the next JSON token from the stream as a . + + + A or a null reference if the next JSON token is null. + + + + + Reads the next JSON token from the stream. + + + true if the next token was read successfully; false if there are no more tokens to read. + + + + + Represents a JSON property. + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Returns a collection of the child tokens of this token, in document order. + + + An of containing the child tokens of this , in document order. + + + + + Initializes a new instance of the class. + + The property name. + The property content. + + + + Initializes a new instance of the class. + + The property name. + The property content. + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Loads an from a . + + A that will be read for the content of the . + A that contains the JSON that was read from the specified . + + + + Gets the property name. + + The property name. + + + + Gets or sets the property value. + + The property value. + + + + Gets the node type for this . + + The type. + + + + Specifies the type of token. + + + + + No token type has been set. + + + + + A JSON object. + + + + + A JSON array. + + + + + A JSON constructor. + + + + + A JSON object property. + + + + + A comment. + + + + + An integer value. + + + + + A float value. + + + + + A string value. + + + + + A boolean value. + + + + + A null value. + + + + + An undefined value. + + + + + A date value. + + + + + A raw JSON value. + + + + + A collection of bytes value. + + + + + Contains the JSON schema extension methods. + + + + + Determines whether the is valid. + + The source to test. + The schema to test with. + + true if the specified is valid; otherwise, false. + + + + + Validates the specified . + + The source to test. + The schema to test with. + + + + Validates the specified . + + The source to test. + The schema to test with. + The validation event handler. + + + + Returns detailed information about the schema exception. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + Gets the line number indicating where the error occurred. + + The line number indicating where the error occurred. + + + + Gets the line position indicating where the error occurred. + + The line position indicating where the error occurred. + + + + Resolves from an id. + + + + + Initializes a new instance of the class. + + + + + Gets a for the specified id. + + The id. + A for the specified id. + + + + Gets or sets the loaded schemas. + + The loaded schemas. + + + + Specifies undefined schema Id handling options for the . + + + + + Do not infer a schema Id. + + + + + Use the .NET type name as the schema Id. + + + + + Use the assembly qualified .NET type name as the schema Id. + + + + + Returns detailed information related to the . + + + + + Gets the associated with the validation event. + + The JsonSchemaException associated with the validation event. + + + + Gets the text description corresponding to the validation event. + + The text description. + + + + Represents the callback method that will handle JSON schema validation events and the . + + + + + Resolves member mappings for a type, camel casing property names. + + + + + Used by to resolves a for a given . + + + + + Used by to resolves a for a given . + + + + + Resolves the contract for a given type. + + The type to resolve a contract for. + The contract for a given type. + + + + Initializes a new instance of the class. + + + + + Resolves the contract for a given type. + + The type to resolve a contract for. + The contract for a given type. + + + + Gets the serializable members for the type. + + The type to get serializable members for. + The serializable members for the type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Resolves the default for the contract. + + Type of the object. + + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates properties for the given . + + The contract to create properties for. + Properties for the given . + + + + Creates the used by the serializer to get and set values from a member. + + The member. + The used by the serializer to get and set values from a member. + + + + Creates a for the given . + + The member's declaring types . + The member to create a for. + A created for the given . + + + + Resolves the name of the property. + + Name of the property. + Name of the property. + + + + Gets or sets the default members search flags. + + The default members search flags. + + + + Resolves the name of the property. + + Name of the property. + The property name camel cased. + + + + The default serialization binder used when resolving and loading classes from type names. + + + + + When overridden in a derived class, controls the binding of a serialized object to a type. + + Specifies the name of the serialized object. + Specifies the name of the serialized object. + + The type of the object the formatter creates a new instance of. + + + + + Get and set values for a using dynamic methods. + + + + + Provides methods to get and set values. + + + + + Sets the value. + + The target to set the value on. + The value to set on the target. + + + + Gets the value. + + The target to get the value from. + The value. + + + + Initializes a new instance of the class. + + The member info. + + + + Sets the value. + + The target to set the value on. + The value to set on the target. + + + + Gets the value. + + The target to get the value from. + The value. + + + + Provides information surrounding an error. + + + + + Gets or sets the error. + + The error. + + + + Gets the original object that caused the error. + + The original object that caused the error. + + + + Gets the member that caused the error. + + The member that caused the error. + + + + Gets or sets a value indicating whether this is handled. + + true if handled; otherwise, false. + + + + Provides data for the Error event. + + + + + Initializes a new instance of the class. + + The current object. + The error context. + + + + Gets the current object the error event is being raised against. + + The current object the error event is being raised against. + + + + Gets the error context. + + The error context. + + + + Contract details for a used by the . + + + + + Contract details for a used by the . + + + + + Gets the underlying type for the contract. + + The underlying type for the contract. + + + + Gets or sets the type created during deserialization. + + The type created during deserialization. + + + + Gets or sets whether this type contract is serialized as a reference. + + Whether this type contract is serialized as a reference. + + + + Gets or sets the default for this contract. + + The converter. + + + + Gets or sets the method called immediately after deserialization of the object. + + The method called immediately after deserialization of the object. + + + + Gets or sets the method called during deserialization of the object. + + The method called during deserialization of the object. + + + + Gets or sets the method called after serialization of the object graph. + + The method called after serialization of the object graph. + + + + Gets or sets the method called before serialization of the object. + + The method called before serialization of the object. + + + + Gets or sets the default creator. + + The default creator. + + + + Gets or sets a value indicating whether [default creator non public]. + + true if the default object creator is non-public; otherwise, false. + + + + Gets or sets the method called when an error is thrown during the serialization of the object. + + The method called when an error is thrown during the serialization of the object. + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Maps a JSON property to a .NET member. + + + + + Gets the name of the property. + + The name of the property. + + + + Gets the that will get and set the during serialization. + + The that will get and set the during serialization. + + + + Gets or sets the type of the property. + + The type of the property. + + + + Gets or sets the for the property. + If set this converter takes presidence over the contract converter for the property type. + + The converter. + + + + Gets a value indicating whether this is ignored. + + true if ignored; otherwise, false. + + + + Gets a value indicating whether this is readable. + + true if readable; otherwise, false. + + + + Gets a value indicating whether this is writable. + + true if writable; otherwise, false. + + + + Gets the member converter. + + The member converter. + + + + Gets the default value. + + The default value. + + + + Gets a value indicating whether this is required. + + A value indicating whether this is required. + + + + Gets a value indicating whether this property preserves object references. + + + true if this instance is reference; otherwise, false. + + + + + Gets the property null value handling. + + The null value handling. + + + + Gets the property default value handling. + + The default value handling. + + + + Gets the property reference loop handling. + + The reference loop handling. + + + + Gets the property object creation handling. + + The object creation handling. + + + + A collection of objects. + + + + + Initializes a new instance of the class. + + The contract. + + + + When implemented in a derived class, extracts the key from the specified element. + + The element from which to extract the key. + The key for the specified element. + + + + Adds a object. + + The property to add to the collection. + + + + Gets the closest matching object. + First attempts to get an exact case match of propertyName and then + a case insensitive match. + + Name of the property. + A matching property if found. + + + + Gets a property by property name. + + The name of the property to get. + Type property name string comparison. + A matching property if found. + + + + Specifies missing member handling options for the . + + + + + Ignore a missing member and do not attempt to deserialize it. + + + + + Throw a when a missing member is encountered during deserialization. + + + + + Specifies null value handling options for the . + + + + + Include null values when serializing and deserializing objects. + + + + + Ignore null values when serializing and deserializing objects. + + + + + Specifies reference loop handling options for the . + + + + + Throw a when a loop is encountered. + + + + + Ignore loop references and do not serialize. + + + + + Serialize loop references. + + + + + An in-memory representation of a JSON Schema. + + + + + Initializes a new instance of the class. + + + + + Reads a from the specified . + + The containing the JSON Schema to read. + The object representing the JSON Schema. + + + + Reads a from the specified . + + The containing the JSON Schema to read. + The to use when resolving schema references. + The object representing the JSON Schema. + + + + Load a from a string that contains schema JSON. + + A that contains JSON. + A populated from the string that contains JSON. + + + + Parses the specified json. + + The json. + The resolver. + A populated from the string that contains JSON. + + + + Writes this schema to a . + + A into which this method will write. + + + + Writes this schema to a using the specified . + + A into which this method will write. + The resolver used. + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Gets or sets the id. + + + + + Gets or sets the title. + + + + + Gets or sets whether the object is optional. + + + + + Gets or sets whether the object is read only. + + + + + Gets or sets whether the object is visible to users. + + + + + Gets or sets whether the object is transient. + + + + + Gets or sets the description of the object. + + + + + Gets or sets the types of values allowed by the object. + + The type. + + + + Gets or sets the pattern. + + The pattern. + + + + Gets or sets the minimum length. + + The minimum length. + + + + Gets or sets the maximum length. + + The maximum length. + + + + Gets or sets the maximum decimals. + + The maximum decimals. + + + + Gets or sets the minimum. + + The minimum. + + + + Gets or sets the maximum. + + The maximum. + + + + Gets or sets the minimum number of items. + + The minimum number of items. + + + + Gets or sets the maximum number of items. + + The maximum number of items. + + + + Gets or sets the of items. + + The of items. + + + + Gets or sets the of properties. + + The of properties. + + + + Gets or sets the of additional properties. + + The of additional properties. + + + + Gets or sets a value indicating whether additional properties are allowed. + + + true if additional properties are allowed; otherwise, false. + + + + + Gets or sets the required property if this property is present. + + The required property if this property is present. + + + + Gets or sets the identity. + + The identity. + + + + Gets or sets the a collection of valid enum values allowed. + + A collection of valid enum values allowed. + + + + Gets or sets a collection of options. + + A collection of options. + + + + Gets or sets disallowed types. + + The disallow types. + + + + Gets or sets the default value. + + The default value. + + + + Gets or sets the extend . + + The extended . + + + + Gets or sets the format. + + The format. + + + + Generates a from a specified . + + + + + Generate a from the specified type. + + The type to generate a from. + A generated from the specified type. + + + + Generate a from the specified type. + + The type to generate a from. + The used to resolve schema references. + A generated from the specified type. + + + + Generate a from the specified type. + + The type to generate a from. + Specify whether the generated root will be nullable. + A generated from the specified type. + + + + Generate a from the specified type. + + The type to generate a from. + The used to resolve schema references. + Specify whether the generated root will be nullable. + A generated from the specified type. + + + + Gets or sets how undefined schemas are handled by the serializer. + + + + + Gets or sets the contract resolver. + + The contract resolver. + + + + The value types allowed by the . + + + + + No type specified. + + + + + String type. + + + + + Float type. + + + + + Integer type. + + + + + Boolean type. + + + + + Object type. + + + + + Array type. + + + + + Null type. + + + + + Any type. + + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Gets or sets the object member serialization. + + The member object serialization. + + + + Gets the object's properties. + + The object's properties. + + + + Gets or sets the parametrized constructor used to create the object. + + The parametrized constructor. + + + + When applied to a method, specifies that the method is called when an error occurs serializing an object. + + + + + Get and set values for a using reflection. + + + + + Initializes a new instance of the class. + + The member info. + + + + Sets the value. + + The target to set the value on. + The value to set on the target. + + + + Gets the value. + + The target to get the value from. + The value. + + + + Specifies type name handling options for the . + + + + + Do not include the .NET type name when serializing types. + + + + + Include the .NET type name when serializing into a JSON object structure. + + + + + Include the .NET type name when serializing into a JSON array structure. + + + + + Always include the .NET type name when serializing. + + + + + Converts the value to the specified type. + + The type to convert the value to. + The value to convert. + The converted type. + + + + Converts the value to the specified type. + + The type to convert the value to. + The value to convert. + The culture to use when converting. + The converted type. + + + + Converts the value to the specified type. + + The value to convert. + The culture to use when converting. + The type to convert the value to. + The converted type. + + + + Converts the value to the specified type. + + The type to convert the value to. + The value to convert. + The converted value if the conversion was successful or the default value of T if it failed. + + true if initialValue was converted successfully; otherwise, false. + + + + + Converts the value to the specified type. + + The type to convert the value to. + The value to convert. + The culture to use when converting. + The converted value if the conversion was successful or the default value of T if it failed. + + true if initialValue was converted successfully; otherwise, false. + + + + + Converts the value to the specified type. + + The value to convert. + The culture to use when converting. + The type to convert the value to. + The converted value if the conversion was successful or the default value of T if it failed. + + true if initialValue was converted successfully; otherwise, false. + + + + + Converts the value to the specified type. If the value is unable to be converted, the + value is checked whether it assignable to the specified type. + + The type to convert or cast the value to. + The value to convert. + The converted type. If conversion was unsuccessful, the initial value is returned if assignable to the target type + + + + Converts the value to the specified type. If the value is unable to be converted, the + value is checked whether it assignable to the specified type. + + The type to convert or cast the value to. + The value to convert. + The culture to use when converting. + The converted type. If conversion was unsuccessful, the initial value is returned if assignable to the target type + + + + Converts the value to the specified type. If the value is unable to be converted, the + value is checked whether it assignable to the specified type. + + The value to convert. + The culture to use when converting. + The type to convert or cast the value to. + + The converted type. If conversion was unsuccessful, the initial value + is returned if assignable to the target type. + + + + + Converts the value to the specified type. If the value is unable to be converted, the + value is checked whether it assignable to the specified type. + + The type to convert the value to. + The value to convert. + The converted value if the conversion was successful or the default value of T if it failed. + + true if initialValue was converted successfully or is assignable; otherwise, false. + + + + + Converts the value to the specified type. If the value is unable to be converted, the + value is checked whether it assignable to the specified type. + + The type to convert the value to. + The value to convert. + The culture to use when converting. + The converted value if the conversion was successful or the default value of T if it failed. + + true if initialValue was converted successfully or is assignable; otherwise, false. + + + + + Converts the value to the specified type. If the value is unable to be converted, the + value is checked whether it assignable to the specified type. + + The value to convert. + The culture to use when converting. + The type to convert the value to. + The converted value if the conversion was successful or the default value of T if it failed. + + true if initialValue was converted successfully or is assignable; otherwise, false. + + + + + Parses the specified enum member name, returning it's value. + + Name of the enum member. + + + + + Parses the specified enum member name, returning it's value. + + Name of the enum member. + If set to true ignore case. + + + + + Gets a dictionary of the names and values of an Enum type. + + + + + + Gets a dictionary of the names and values of an Enum type. + + + + + + Gets a dictionary of the names and values of an Enum type. + + The enum type to get names and values for. + + + + + Gets the maximum valid value of an Enum type. Flags enums are ORed. + + The type of the returned value. Must be assignable from the enum's underlying value type. + The enum type to get the maximum value for. + + + + + Specifies the type of Json token. + + + + + This is returned by the if a method has not been called. + + + + + An object start token. + + + + + An array start token. + + + + + A constructor start token. + + + + + An object property name. + + + + + A comment. + + + + + Raw JSON. + + + + + An interger. + + + + + A float. + + + + + A string. + + + + + A boolean. + + + + + A null token. + + + + + An undefined token. + + + + + An object end token. + + + + + An array end token. + + + + + A constructor end token. + + + + + A Date. + + + + + Byte data. + + + + + Specifies the state of the . + + + + + An exception has been thrown, which has left the in an invalid state. + You may call the method to put the in the Closed state. + Any other method calls results in an being thrown. + + + + + The method has been called. + + + + + An object is being written. + + + + + A array is being written. + + + + + A constructor is being written. + + + + + A property is being written. + + + + + A write method has not been called. + + + + + Specifies formatting options for the . + + + + + No special formatting is applied. This is the default. + + + + + Causes child objects to be indented according to the and settings. + + + + + Builds a string. Unlike StringBuilder this class lets you reuse it's internal buffer. + + + + + Determines whether the collection is null or empty. + + The collection. + + true if the collection is null or empty; otherwise, false. + + + + + Determines whether the collection is null or empty. + + The collection. + + true if the collection is null or empty; otherwise, false. + + + + + Determines whether the collection is null, empty or its contents are uninitialized values. + + The list. + + true if the collection is null or empty or its contents are uninitialized values; otherwise, false. + + + + + Makes a slice of the specified list in between the start and end indexes. + + The list. + The start index. + The end index. + A slice of the list. + + + + Makes a slice of the specified list in between the start and end indexes, + getting every so many items based upon the step. + + The list. + The start index. + The end index. + The step. + A slice of the list. + + + + Group the collection using a function which returns the key. + + The source collection to group. + The key selector. + A Dictionary with each key relating to a list of objects in a list grouped under it. + + + + Adds the elements of the specified collection to the specified generic IList. + + The list to add to. + The collection of elements to add. + + + + Gets the type of the typed collection's items. + + The type. + The type of the typed collection's items. + + + + Tests whether the list's items are their unitialized value. + + The list. + Whether the list's items are their unitialized value + + + + Gets the member's underlying type. + + The member. + The underlying type of the member. + + + + Determines whether the member is an indexed property. + + The member. + + true if the member is an indexed property; otherwise, false. + + + + + Determines whether the property is an indexed property. + + The property. + + true if the property is an indexed property; otherwise, false. + + + + + Gets the member's value on the object. + + The member. + The target object. + The member's value on the object. + + + + Sets the member's value on the target object. + + The member. + The target. + The value. + + + + Determines whether the specified MemberInfo can be read. + + The MemberInfo to determine whether can be read. + + true if the specified MemberInfo can be read; otherwise, false. + + + + + Determines whether the specified MemberInfo can be set. + + The MemberInfo to determine whether can be set. + + true if the specified MemberInfo can be set; otherwise, false. + + + + + Determines whether the string contains white space. + + The string to test for white space. + + true if the string contains white space; otherwise, false. + + + + + Determines whether the string is all white space. Empty string will return false. + + The string to test whether it is all white space. + + true if the string is all white space; otherwise, false. + + + + + Ensures the target string ends with the specified string. + + The target. + The value. + The target string with the value string at the end. + + + + Perform an action if the string is not null or empty. + + The value. + The action to perform. + + + + Indents the specified string. + + The string to indent. + The number of characters to indent by. + + + + + Indents the specified string. + + The string to indent. + The number of characters to indent by. + The indent character. + + + + + Numbers the lines. + + The string to number. + + + + + Nulls an empty string. + + The string. + Null if the string was null, otherwise the string unchanged. + + + diff --git a/bin/Newtonsoft.Json.dll b/bin/Newtonsoft.Json.dll index 3b14448..177d9b5 100644 Binary files a/bin/Newtonsoft.Json.dll and b/bin/Newtonsoft.Json.dll differ diff --git a/bin/Newtonsoft.Json.pdb b/bin/Newtonsoft.Json.pdb index a8b8b8f..892546a 100644 Binary files a/bin/Newtonsoft.Json.pdb and b/bin/Newtonsoft.Json.pdb differ -- cgit v1.1 From 2313d14acbf0f23d5d041ade03fa1fe030223f51 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 11 Mar 2010 23:33:55 +0000 Subject: minor: add some more documentation for IHttpServer.AddHTTPHandler() to tell the caller that the best match for an incoming request URI is invoked --- OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 6 ++---- OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs | 6 +++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 214f936..9a6ef77 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -202,16 +202,14 @@ namespace OpenSim.Framework.Servers.HttpServer if (!m_pollHandlers.ContainsKey(methodName)) { m_pollHandlers.Add(methodName,args); - pollHandlerResult = true; - + pollHandlerResult = true; } } if (pollHandlerResult) return AddHTTPHandler(methodName, handler); - return false; - + return false; } // Note that the agent string is provided simply to differentiate diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs index 5ee2045..65b1eb5 100644 --- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs @@ -47,7 +47,7 @@ namespace OpenSim.Framework.Servers.HttpServer bool AddAgentHandler(string agent, IHttpAgentHandler handler); /// - /// Add a handler for an HTTP request + /// Add a handler for an HTTP request. /// /// /// This handler can actually be invoked either as @@ -66,6 +66,10 @@ namespace OpenSim.Framework.Servers.HttpServer /// or /// /// http://localhost:9000/object/ + /// + /// In addition, the handler invoked by the HTTP server for any request is the one when best matches the request + /// URI. So if a handler for "/myapp/" is registered and a request for "/myapp/page" is received, then + /// the "/myapp/" handler is invoked if no "/myapp/page" handler exists. /// /// /// -- cgit v1.1 From ed3288a8db33be13e9e278d47cc00b3666d9d262 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 12 Mar 2010 10:16:21 -0800 Subject: Bug fix: "last location" login. --- OpenSim/Services/PresenceService/PresenceService.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenSim/Services/PresenceService/PresenceService.cs b/OpenSim/Services/PresenceService/PresenceService.cs index 304538a..ea8d673 100644 --- a/OpenSim/Services/PresenceService/PresenceService.cs +++ b/OpenSim/Services/PresenceService/PresenceService.cs @@ -72,6 +72,10 @@ namespace OpenSim.Services.PresenceService data.Data["HomeRegionID"] = d[0].Data["HomeRegionID"]; data.Data["HomePosition"] = d[0].Data["HomePosition"]; data.Data["HomeLookAt"] = d[0].Data["HomeLookAt"]; + data.Data["Position"] = d[0].Data["Position"]; + data.Data["LookAt"] = d[0].Data["LookAt"]; + + data.RegionID = d[0].RegionID; } else { -- cgit v1.1 From 8b1e33eb2d253daddb760c90526f1a3de95c17d0 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Fri, 12 Mar 2010 10:31:43 -0800 Subject: Fixed SimianGrid.ini to use GridCommon.ini(.example) --- bin/config-include/SimianGrid.ini | 55 +++++++++++++++------------------------ 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/bin/config-include/SimianGrid.ini b/bin/config-include/SimianGrid.ini index af33860..58dcae9 100644 --- a/bin/config-include/SimianGrid.ini +++ b/bin/config-include/SimianGrid.ini @@ -1,3 +1,24 @@ +;; +;; Please don't change this file. +;; All optional settings are in GridCommon.ini.example, +;; which you can copy and change. +;; + +;; +;; In GridCommon.ini, these are the URLs you would use if SimianGrid is +;; installed at http://www.mygrid.com/Grid/ +;; +; AssetServerURI = "http://www.mygrid.com/Grid/?id=" +; InventoryServerURI = "http://www.mygrid.com/Grid/" +; AvatarServerURI = "http://www.mygrid.com/Grid/" +; PresenceServerURI = "http://www.mygrid.com/Grid/" +; UserAccountServerURI = "http://www.mygrid.com/Grid/" +; AuthenticationServerURI = "http://www.mygrid.com/Grid/" +; FriendsServerURI = "http://www.mygrid.com/Grid/" + +[Includes] + Include-Common = "config-include/GridCommon.ini" + [Modules] GridServices = "OpenSim.Services.Connectors.dll:SimianGridServiceConnector" PresenceServices = "OpenSim.Services.Connectors.dll:SimianPresenceServiceConnector" @@ -25,7 +46,6 @@ [GridService] LocalServiceModule = "OpenSim.Services.GridService.dll:GridService" StorageProvider = "OpenSim.Data.Null.dll:NullRegionData" - GridServerURI = "http://localhost/Grid/" [LibraryService] LocalServiceModule = "OpenSim.Services.InventoryService.dll:LibraryService" @@ -35,36 +55,3 @@ [AssetService] DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll" AssetLoaderArgs = "assets/AssetSets.xml" - AssetServerURI = "http://localhost/Grid/?id=" - -[InventoryService] - InventoryServerURI = "http://localhost/Grid/" - -[AvatarService] - AvatarServerURI = "http://localhost/Grid/" - -[PresenceService] - PresenceServerURI = "http://localhost/Grid/" - -[UserAccountService] - UserAccountServerURI = "http://localhost/Grid/" - -[AuthenticationService] - AuthenticationServerURI = "http://localhost/Grid/" - -[FriendsService] - FriendsServerURI = "http://localhost/Grid/" - -[AssetCache] - CacheDirectory = ./assetcache - LogLevel = 0 - HitRateDisplay = 100 - MemoryCacheEnabled = false - ; How long {in hours} to keep assets cached in memory, .5 == 30 minutes - MemoryCacheTimeout = 2 - ; How long {in hours} to keep assets cached on disk, .5 == 30 minutes - ; Specify 0 if you do not want your disk cache to expire - FileCacheTimeout = 0 - ; How often {in hours} should the disk be checked for expired filed - ; Specify 0 to disable expiration checking - FileCleanupTimer = 0 ;roughly every 10 minutes -- cgit v1.1 From f2de50bb14bd8215ea98c79c79aabe1e6b4f2780 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Mar 2010 19:31:14 +0000 Subject: Fix tests broken in 88771aeed3d45e60a18aa9a810eeb37b8e5def12 Adds MockUserAccountService and connects it up Stops services being carried over between tests since this leads to hard to find bugs Improves information and error reporting when loading plugins --- .../LocalUserAccountServiceConnector.cs | 18 ++++----- .../Scenes/Tests/SceneObjectBasicTests.cs | 13 ++----- OpenSim/Server/Base/ServerUtils.cs | 40 +++++++++---------- OpenSim/Services/Interfaces/IUserAccountService.cs | 20 ++++++---- .../Tests/Common/Mock/MockUserAccountService.cs | 45 ++++++++++++++++++++++ OpenSim/Tests/Common/Mock/TestScene.cs | 4 +- OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs | 34 ++++++++++++---- 7 files changed, 120 insertions(+), 54 deletions(-) create mode 100644 OpenSim/Tests/Common/Mock/MockUserAccountService.cs diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs index ce0ca40..30ebb21 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs @@ -73,33 +73,31 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts IConfig userConfig = source.Configs["UserAccountService"]; if (userConfig == null) { - m_log.Error("[USER CONNECTOR]: UserAccountService missing from OpenSim.ini"); + m_log.Error("[LOCAL USER ACCOUNT SERVICE CONNECTOR]: UserAccountService missing from OpenSim.ini"); return; } - string serviceDll = userConfig.GetString("LocalServiceModule", - String.Empty); + string serviceDll = userConfig.GetString("LocalServiceModule", String.Empty); if (serviceDll == String.Empty) { - m_log.Error("[USER CONNECTOR]: No LocalServiceModule named in section UserService"); + m_log.Error("[LOCAL USER ACCOUNT SERVICE CONNECTOR]: No LocalServiceModule named in section UserService"); return; } Object[] args = new Object[] { source }; - m_UserService = - ServerUtils.LoadPlugin(serviceDll, - args); + m_UserService = ServerUtils.LoadPlugin(serviceDll, args); if (m_UserService == null) { - m_log.Error("[USER CONNECTOR]: Can't load user account service"); + m_log.ErrorFormat( + "[LOCAL USER ACCOUNT SERVICE CONNECTOR]: Cannot load user account service specified as {0}", serviceDll); return; } m_Enabled = true; m_Cache = new UserAccountCache(); - m_log.Info("[USER CONNECTOR]: Local user connector enabled"); + m_log.Info("[LOCAL USER ACCOUNT SERVICE CONNECTOR]: Local user connector enabled"); } } } @@ -134,6 +132,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts { if (!m_Enabled) return; + + m_log.InfoFormat("[LOCAL USER ACCOUNT SERVICE CONNECTOR]: Enabled local user accounts for region {0}", scene.RegionInfo.RegionName); } #endregion diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs index b50d4ca..78f2ae3 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs @@ -86,6 +86,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests public void TestDeleteSceneObjectAsync() { TestHelper.InMethod(); + //log4net.Config.XmlConfigurator.Configure(); UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001"); @@ -97,15 +98,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene); - try - { - IClientAPI client = SceneSetupHelpers.AddRootAgent(scene, agentId); - scene.DeRezObject(client, part.LocalId, UUID.Zero, DeRezAction.Delete, UUID.Zero); - } - catch (Exception e) - { - Console.WriteLine("Exception: " + e.StackTrace); - } + IClientAPI client = SceneSetupHelpers.AddRootAgent(scene, agentId); + scene.DeRezObject(client, part.LocalId, UUID.Zero, DeRezAction.Delete, UUID.Zero); + SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); Assert.That(retrievedPart, Is.Not.Null); diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs index 9c54410..a399672 100644 --- a/OpenSim/Server/Base/ServerUtils.cs +++ b/OpenSim/Server/Base/ServerUtils.cs @@ -57,6 +57,12 @@ namespace OpenSim.Server.Base return ret; } + /// + /// Load a plugin from a dll with the given class or interface + /// + /// + /// The arguments which control which constructor is invoked on the plugin + /// public static T LoadPlugin(string dllName, Object[] args) where T:class { string[] parts = dllName.Split(new char[] {':'}); @@ -71,6 +77,13 @@ namespace OpenSim.Server.Base return LoadPlugin(dllName, className, args); } + /// + /// Load a plugin from a dll with the given class or interface + /// + /// + /// + /// The arguments which control which constructor is invoked on the plugin + /// public static T LoadPlugin(string dllName, string className, Object[] args) where T:class { string interfaceName = typeof(T).ToString(); @@ -83,28 +96,15 @@ namespace OpenSim.Server.Base { if (pluginType.IsPublic) { - if (className != String.Empty && - pluginType.ToString() != - pluginType.Namespace + "." + className) + if (className != String.Empty + && pluginType.ToString() != pluginType.Namespace + "." + className) continue; - Type typeInterface = - pluginType.GetInterface(interfaceName, true); + + Type typeInterface = pluginType.GetInterface(interfaceName, true); + if (typeInterface != null) { - T plug = null; - try - { - plug = (T)Activator.CreateInstance(pluginType, - args); - } - catch (Exception e) - { - if (!(e is System.MissingMethodException)) - m_log.ErrorFormat("Error loading plugin from {0}, exception {1}", dllName, e.InnerException); - return null; - } - - return plug; + return (T)Activator.CreateInstance(pluginType, args); } } } @@ -113,7 +113,7 @@ namespace OpenSim.Server.Base } catch (Exception e) { - m_log.ErrorFormat("Error loading plugin from {0}, exception {1}", dllName, e); + m_log.Error(string.Format("Error loading plugin from {0}", dllName), e); return null; } } diff --git a/OpenSim/Services/Interfaces/IUserAccountService.cs b/OpenSim/Services/Interfaces/IUserAccountService.cs index 3dacf53..a45bf8c 100644 --- a/OpenSim/Services/Interfaces/IUserAccountService.cs +++ b/OpenSim/Services/Interfaces/IUserAccountService.cs @@ -140,14 +140,20 @@ namespace OpenSim.Services.Interfaces UserAccount GetUserAccount(UUID scopeID, UUID userID); UserAccount GetUserAccount(UUID scopeID, string FirstName, string LastName); UserAccount GetUserAccount(UUID scopeID, string Email); - // Returns the list of avatars that matches both the search - // criterion and the scope ID passed - // + + /// + /// Returns the list of avatars that matches both the search criterion and the scope ID passed + /// + /// + /// + /// List GetUserAccounts(UUID scopeID, string query); - // Store the data given, wich replaces the sotred data, therefore - // must be complete. - // + /// + /// Store the data given, wich replaces the sotred data, therefore must be complete. + /// + /// + /// bool StoreUserAccount(UserAccount data); } -} +} \ No newline at end of file diff --git a/OpenSim/Tests/Common/Mock/MockUserAccountService.cs b/OpenSim/Tests/Common/Mock/MockUserAccountService.cs new file mode 100644 index 0000000..f5d758a --- /dev/null +++ b/OpenSim/Tests/Common/Mock/MockUserAccountService.cs @@ -0,0 +1,45 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System.Collections.Generic; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Tests.Common.Mock +{ + public class MockUserAccountService : IUserAccountService + { + public MockUserAccountService(IConfigSource config) {} + + public UserAccount GetUserAccount(UUID scopeID, UUID userID) { return new UserAccount(); } + public UserAccount GetUserAccount(UUID scopeID, string FirstName, string LastName) { return new UserAccount(); } + public UserAccount GetUserAccount(UUID scopeID, string Email) { return new UserAccount(); } + public List GetUserAccounts(UUID scopeID, string query) { return new List(); } + public bool StoreUserAccount(UserAccount data) { return true; } + } +} \ No newline at end of file diff --git a/OpenSim/Tests/Common/Mock/TestScene.cs b/OpenSim/Tests/Common/Mock/TestScene.cs index 076cb7a..01f2c14 100644 --- a/OpenSim/Tests/Common/Mock/TestScene.cs +++ b/OpenSim/Tests/Common/Mock/TestScene.cs @@ -65,6 +65,6 @@ namespace OpenSim.Tests.Common.Mock public AsyncSceneObjectGroupDeleter SceneObjectGroupDeleter { get { return m_asyncSceneObjectDeleter; } - } + } } -} +} \ No newline at end of file diff --git a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs index 9e718f6..ab3e7cb 100644 --- a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs +++ b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs @@ -128,7 +128,7 @@ namespace OpenSim.Tests.Common.Setup /// Starts real inventory and asset services, as opposed to mock ones, if true /// public static TestScene SetupScene( - string name, UUID id, uint x, uint y, String realServices) + string name, UUID id, uint x, uint y, String realServices) { bool newScene = false; @@ -179,15 +179,16 @@ namespace OpenSim.Tests.Common.Setup StartAssetService(testScene, true); else StartAssetService(testScene, false); + if (realServices.Contains("inventory")) StartInventoryService(testScene, true); else StartInventoryService(testScene, false); + if (realServices.Contains("grid")) StartGridService(testScene, true); - if (realServices.Contains("useraccounts")) - StartUserAccountService(testScene, true); - + + StartUserAccountService(testScene, realServices.Contains("useraccounts")); } // If not, make sure the shared module gets references to this new scene else @@ -196,9 +197,13 @@ namespace OpenSim.Tests.Common.Setup m_assetService.RegionLoaded(testScene); m_inventoryService.AddRegion(testScene); m_inventoryService.RegionLoaded(testScene); + m_userAccountService.AddRegion(testScene); + m_userAccountService.RegionLoaded(testScene); } + m_inventoryService.PostInitialise(); m_assetService.PostInitialise(); + m_userAccountService.PostInitialise(); testScene.SetModuleInterfaces(); @@ -209,6 +214,11 @@ namespace OpenSim.Tests.Common.Setup physicsPluginManager.LoadPluginsFromAssembly("Physics/OpenSim.Region.Physics.BasicPhysicsPlugin.dll"); testScene.PhysicsScene = physicsPluginManager.GetPhysicsScene("basicphysics", "ZeroMesher", new IniConfigSource(), "test"); + + m_assetService = null; + m_inventoryService = null; + m_gridService = null; + m_userAccountService = null; return testScene; } @@ -273,6 +283,11 @@ namespace OpenSim.Tests.Common.Setup //testScene.AddRegionModule(m_gridService.Name, m_gridService); } + /// + /// Start a user account service, whether real or mock + /// + /// + /// Starts a real service if true, a mock service if not private static void StartUserAccountService(Scene testScene, bool real) { IConfigSource config = new IniConfigSource(); @@ -280,8 +295,14 @@ namespace OpenSim.Tests.Common.Setup config.AddConfig("UserAccountService"); config.Configs["Modules"].Set("UserAccountServices", "LocalUserAccountServicesConnector"); config.Configs["UserAccountService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); + if (real) - config.Configs["UserAccountService"].Set("LocalServiceModule", "OpenSim.Services.UserAccountService.dll:UserAccountService"); + config.Configs["UserAccountService"].Set( + "LocalServiceModule", "OpenSim.Services.UserAccountService.dll:UserAccountService"); + else + config.Configs["UserAccountService"].Set( + "LocalServiceModule", "OpenSim.Tests.Common.dll:MockUserAccountService"); + if (m_userAccountService == null) { ISharedRegionModule userAccountService = new LocalUserAccountServicesConnector(); @@ -292,10 +313,9 @@ namespace OpenSim.Tests.Common.Setup // config.Configs["GridService"].Set("LocalServiceModule", "OpenSim.Tests.Common.dll:TestGridService"); m_userAccountService.AddRegion(testScene); m_userAccountService.RegionLoaded(testScene); - //testScene.AddRegionModule(m_gridService.Name, m_gridService); + testScene.AddRegionModule(m_userAccountService.Name, m_userAccountService); } - /// /// Setup modules for a scene using their default settings. /// -- cgit v1.1 From aad17e751383069b799c6a78a3ac4e0ca1020a4d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Mar 2010 20:29:17 +0000 Subject: Simplify database setup and remove migration problems by moving all sqlite config-include settings to a separate file for standalone Update information in StandaloneCommon.ini.example to reflect this Remove ISharedRegionModule interfaces from all SimianGrid connector classes temporarily since this stopped standalone from working (due to absence of AssetURI settings, etc.). Solution here may be to create separate region module connectors as done by local/grid/hypergrid so that loading can be controlled via include files Or otherwise work out how to stop these modules from being loaded for all OpenSim invocations --- .../SimianGrid/SimianAssetServiceConnector.cs | 2 +- .../SimianAuthenticationServiceConnector.cs | 2 +- .../SimianGrid/SimianAvatarServiceConnector.cs | 2 +- .../SimianGrid/SimianFriendsServiceConnector.cs | 2 +- .../SimianGrid/SimianGridServiceConnector.cs | 2 +- .../SimianGrid/SimianInventoryServiceConnector.cs | 2 +- .../SimianGrid/SimianPresenceServiceConnector.cs | 2 +- .../Connectors/SimianGrid/SimianProfiles.cs | 2 +- .../SimianUserAccountServiceConnector.cs | 2 +- .../Tests/Common/Mock/MockUserAccountService.cs | 1 + OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs | 3 +++ bin/config-include/Standalone.ini | 4 ---- bin/config-include/StandaloneCommon.ini.example | 23 +++++++++++++--------- bin/config-include/storage/SQLiteStandalone.ini | 16 +++++++++++++++ 14 files changed, 43 insertions(+), 22 deletions(-) create mode 100644 bin/config-include/storage/SQLiteStandalone.ini diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs index 9fb7723..201bc70 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs @@ -46,7 +46,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// Connects to the SimianGrid asset service /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianAssetServiceConnector : IAssetService, ISharedRegionModule + public class SimianAssetServiceConnector : IAssetService { private static readonly ILog m_log = LogManager.GetLogger( diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs index ec66341..25e04d7 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs @@ -44,7 +44,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// Connects authentication/authorization to the SimianGrid backend /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianAuthenticationServiceConnector : IAuthenticationService, ISharedRegionModule + public class SimianAuthenticationServiceConnector : IAuthenticationService { private static readonly ILog m_log = LogManager.GetLogger( diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs index 220f143..08403b9 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs @@ -48,7 +48,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// Connects avatar appearance data to the SimianGrid backend /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianAvatarServiceConnector : IAvatarService, ISharedRegionModule + public class SimianAvatarServiceConnector : IAvatarService { private static readonly ILog m_log = LogManager.GetLogger( diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs index 3952a8c..856381d 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs @@ -47,7 +47,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// Stores and retrieves friend lists from the SimianGrid backend /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianFriendsServiceConnector : IFriendsService, ISharedRegionModule + public class SimianFriendsServiceConnector : IFriendsService { private static readonly ILog m_log = LogManager.GetLogger( diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs index 16819d1..c375076 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs @@ -51,7 +51,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// backend /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianGridServiceConnector : IGridService, ISharedRegionModule + public class SimianGridServiceConnector : IGridService { private static readonly ILog m_log = LogManager.GetLogger( diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs index c812899..9879295 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs @@ -61,7 +61,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// Connects avatar inventories to the SimianGrid backend /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianInventoryServiceConnector : IInventoryService, ISharedRegionModule + public class SimianInventoryServiceConnector : IInventoryService { private static readonly ILog m_log = LogManager.GetLogger( diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs index 65de1c5..45d1824 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs @@ -51,7 +51,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// message routing) to the SimianGrid backend /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianPresenceServiceConnector : IPresenceService, ISharedRegionModule + public class SimianPresenceServiceConnector : IPresenceService { private static readonly ILog m_log = LogManager.GetLogger( diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs index 1e19982..32f17ae 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs @@ -60,7 +60,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// backend /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianProfiles : INonSharedRegionModule + public class SimianProfiles { private static readonly ILog m_log = LogManager.GetLogger( diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs index 14097d0..708ced3 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs @@ -47,7 +47,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// users) to the SimianGrid backend /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianUserAccountServiceConnector : IUserAccountService, ISharedRegionModule + public class SimianUserAccountServiceConnector : IUserAccountService { private static readonly ILog m_log = LogManager.GetLogger( diff --git a/OpenSim/Tests/Common/Mock/MockUserAccountService.cs b/OpenSim/Tests/Common/Mock/MockUserAccountService.cs index f5d758a..0769c7a 100644 --- a/OpenSim/Tests/Common/Mock/MockUserAccountService.cs +++ b/OpenSim/Tests/Common/Mock/MockUserAccountService.cs @@ -34,6 +34,7 @@ namespace OpenSim.Tests.Common.Mock { public class MockUserAccountService : IUserAccountService { + public MockUserAccountService(IConfigSource config) {} public UserAccount GetUserAccount(UUID scopeID, UUID userID) { return new UserAccount(); } diff --git a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs index ab3e7cb..864e2aa 100644 --- a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs +++ b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs @@ -215,6 +215,9 @@ namespace OpenSim.Tests.Common.Setup testScene.PhysicsScene = physicsPluginManager.GetPhysicsScene("basicphysics", "ZeroMesher", new IniConfigSource(), "test"); + // It's really not a good idea to use static variables as they carry over between tests, leading to + // problems that are extremely hard to debug. Really, these static fields need to be eliminated - + // tests using multiple regions that need to share modules need to find another solution. m_assetService = null; m_inventoryService = null; m_gridService = null; diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini index 3011370..54e11af 100644 --- a/bin/config-include/Standalone.ini +++ b/bin/config-include/Standalone.ini @@ -32,14 +32,12 @@ [AvatarService] LocalServiceModule = "OpenSim.Services.AvatarService.dll:AvatarService" - ConnectionString = "URI=file:avatars.db,version=3" [AuthorizationService] LocalServiceModule = "OpenSim.Services.AuthorizationService.dll:AuthorizationService" [AuthenticationService] LocalServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" - ConnectionString = "URI=file:auth.db,version=3" [GridService] LocalServiceModule = "OpenSim.Services.GridService.dll:GridService" @@ -52,7 +50,6 @@ [UserAccountService] LocalServiceModule = "OpenSim.Services.UserAccountService.dll:UserAccountService" - ConnectionString = "URI=file:userprofiles.db,version=3" ;; These are for creating new accounts AuthenticationService = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" @@ -62,7 +59,6 @@ [FriendsService] LocalServiceModule = "OpenSim.Services.FriendsService.dll" - ConnectionString = "URI=file:friends.db,version=3" [Friends] Connector = "OpenSim.Services.FriendsService.dll" diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 8e21a8c..f89c67a 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -1,19 +1,24 @@ +; This is the main configuration file for standalone OpenSim instances + [DatabaseService] ; - ;### Choose the DB + ; ### Choose the DB ; - ;--- For SQLite - StorageProvider = "OpenSim.Data.SQLite.dll" - ;--- For MySql + + ; SQLite + ; Uncomment this line if you want to use sqlite storage + Include-Storage = "config-include/storage/SQLiteStandalone.ini"; + + ; For MySql. + ; Uncomment these lines if you want to use mysql storage + ; Change the connection string to your db details ;StorageProvider = "OpenSim.Data.MySQL.dll" ;ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;" [AssetService] - DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll" AssetLoaderArgs = "assets/AssetSets.xml" - [Modules] ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists. ;; Copy the config .example file into your own .ini file and change configs there @@ -35,10 +40,10 @@ [GridService] ;; For in-memory region storage (default) - StorageProvider = "OpenSim.Data.Null.dll:NullRegionData" + StorageProvider = "OpenSim.Data.Null.dll:NullRegionData" ;;--- For MySql region storage (alternative) - ;StorageProvider = "OpenSim.Data.MySQL.dll:MySqlRegionData" - ;ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;" + ;StorageProvider = "OpenSim.Data.MySQL.dll:MySqlRegionData" + ;; Next, we can specify properties of regions, including default and fallback regions ;; The syntax is: Region_ = "" ;; where can be DefaultRegion, FallbackRegion, NoDirectLogin, Persistent, LockedOut diff --git a/bin/config-include/storage/SQLiteStandalone.ini b/bin/config-include/storage/SQLiteStandalone.ini new file mode 100644 index 0000000..1ce0357 --- /dev/null +++ b/bin/config-include/storage/SQLiteStandalone.ini @@ -0,0 +1,16 @@ +; These are the initialization settings for running OpenSim Standalone with an SQLite database + +[DatabaseService] + StorageProvider = "OpenSim.Data.SQLite.dll" + +[AvatarService] + ConnectionString = "URI=file:avatars.db,version=3" + +[AuthenticationService] + ConnectionString = "URI=file:auth.db,version=3" + +[UserAccountService] + ConnectionString = "URI=file:userprofiles.db,version=3" + +[FriendsService] + ConnectionString = "URI=file:friends.db,version=3" -- cgit v1.1 From 0b5141d45bcd409544e909aedabc3e58e6a86a13 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Fri, 12 Mar 2010 13:16:44 -0800 Subject: Fixed SimianGrid connectors to gracefully exit if the required config sections are missing --- .../SimianGrid/SimianAssetServiceConnector.cs | 12 ++++---- .../SimianAuthenticationServiceConnector.cs | 10 +++---- .../SimianGrid/SimianAvatarServiceConnector.cs | 10 +++---- .../SimianGrid/SimianFriendsServiceConnector.cs | 10 +++---- .../SimianGrid/SimianGridServiceConnector.cs | 10 +++---- .../SimianGrid/SimianInventoryServiceConnector.cs | 10 +++---- .../SimianGrid/SimianPresenceServiceConnector.cs | 32 +++++++++++++--------- .../Connectors/SimianGrid/SimianProfiles.cs | 12 ++++---- .../SimianUserAccountServiceConnector.cs | 13 +++++---- 9 files changed, 63 insertions(+), 56 deletions(-) diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs index 201bc70..89aa911 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs @@ -46,7 +46,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// Connects to the SimianGrid asset service /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianAssetServiceConnector : IAssetService + public class SimianAssetServiceConnector : IAssetService, ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger( @@ -73,9 +73,9 @@ namespace OpenSim.Services.Connectors.SimianGrid public SimianAssetServiceConnector() { } public string Name { get { return "SimianAssetServiceConnector"; } } - public void AddRegion(Scene scene) { scene.RegisterModuleInterface(this); } - public void RemoveRegion(Scene scene) { scene.UnregisterModuleInterface(this); } - + public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface(this); } } + public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface(this); } } + #endregion ISharedRegionModule public SimianAssetServiceConnector(IConfigSource source) @@ -88,8 +88,8 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig gridConfig = source.Configs["AssetService"]; if (gridConfig == null) { - m_log.Error("[ASSET CONNECTOR]: AssetService missing from OpenSim.ini"); - throw new Exception("Asset connector init error"); + m_log.Info("[ASSET CONNECTOR]: AssetService missing from OpenSim.ini, skipping SimianAssetServiceConnector"); + return; } string serviceUrl = gridConfig.GetString("AssetServerURI"); diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs index 25e04d7..55aca36 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs @@ -44,7 +44,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// Connects authentication/authorization to the SimianGrid backend /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianAuthenticationServiceConnector : IAuthenticationService + public class SimianAuthenticationServiceConnector : IAuthenticationService, ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger( @@ -61,8 +61,8 @@ namespace OpenSim.Services.Connectors.SimianGrid public SimianAuthenticationServiceConnector() { } public string Name { get { return "SimianAuthenticationServiceConnector"; } } - public void AddRegion(Scene scene) { scene.RegisterModuleInterface(this); } - public void RemoveRegion(Scene scene) { scene.UnregisterModuleInterface(this); } + public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface(this); } } + public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface(this); } } #endregion ISharedRegionModule @@ -76,8 +76,8 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig assetConfig = source.Configs["AuthenticationService"]; if (assetConfig == null) { - m_log.Error("[AUTH CONNECTOR]: AuthenticationService missing from OpenSim.ini"); - throw new Exception("Authentication connector init error"); + m_log.Info("[AUTH CONNECTOR]: AuthenticationService missing from OpenSim.ini, skipping SimianAuthenticationServiceConnector"); + return; } string serviceURI = assetConfig.GetString("AuthenticationServerURI"); diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs index 08403b9..b5cef0c 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs @@ -48,7 +48,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// Connects avatar appearance data to the SimianGrid backend /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianAvatarServiceConnector : IAvatarService + public class SimianAvatarServiceConnector : IAvatarService, ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger( @@ -66,8 +66,8 @@ namespace OpenSim.Services.Connectors.SimianGrid public SimianAvatarServiceConnector() { } public string Name { get { return "SimianAvatarServiceConnector"; } } - public void AddRegion(Scene scene) { scene.RegisterModuleInterface(this); } - public void RemoveRegion(Scene scene) { scene.UnregisterModuleInterface(this); } + public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface(this); } } + public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface(this); } } #endregion ISharedRegionModule @@ -81,8 +81,8 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig gridConfig = source.Configs["AvatarService"]; if (gridConfig == null) { - m_log.Error("[AVATAR CONNECTOR]: AvatarService missing from OpenSim.ini"); - throw new Exception("Avatar connector init error"); + m_log.Info("[AVATAR CONNECTOR]: AvatarService missing from OpenSim.ini, skipping SimianAvatarServiceConnector"); + return; } string serviceUrl = gridConfig.GetString("AvatarServerURI"); diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs index 856381d..a569e91 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs @@ -47,7 +47,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// Stores and retrieves friend lists from the SimianGrid backend /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianFriendsServiceConnector : IFriendsService + public class SimianFriendsServiceConnector : IFriendsService, ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger( @@ -64,8 +64,8 @@ namespace OpenSim.Services.Connectors.SimianGrid public SimianFriendsServiceConnector() { } public string Name { get { return "SimianFriendsServiceConnector"; } } - public void AddRegion(Scene scene) { scene.RegisterModuleInterface(this); } - public void RemoveRegion(Scene scene) { scene.UnregisterModuleInterface(this); } + public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface(this); } } + public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface(this); } } #endregion ISharedRegionModule @@ -79,8 +79,8 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig assetConfig = source.Configs["FriendsService"]; if (assetConfig == null) { - m_log.Error("[FRIENDS CONNECTOR]: FriendsService missing from OpenSim.ini"); - throw new Exception("Friends connector init error"); + m_log.Info("[FRIENDS CONNECTOR]: FriendsService missing from OpenSim.ini, skipping SimianFriendsServiceConnector"); + return; } string serviceURI = assetConfig.GetString("FriendsServerURI"); diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs index c375076..2e600f0 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs @@ -51,7 +51,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// backend /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianGridServiceConnector : IGridService + public class SimianGridServiceConnector : IGridService, ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger( @@ -68,8 +68,8 @@ namespace OpenSim.Services.Connectors.SimianGrid public SimianGridServiceConnector() { } public string Name { get { return "SimianGridServiceConnector"; } } - public void AddRegion(Scene scene) { scene.RegisterModuleInterface(this); } - public void RemoveRegion(Scene scene) { scene.UnregisterModuleInterface(this); } + public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface(this); } } + public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface(this); } } #endregion ISharedRegionModule @@ -83,8 +83,8 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig gridConfig = source.Configs["GridService"]; if (gridConfig == null) { - m_log.Error("[GRID CONNECTOR]: GridService missing from OpenSim.ini"); - throw new Exception("Grid connector init error"); + m_log.Info("[GRID CONNECTOR]: GridService missing from OpenSim.ini, skipping SimianGridServiceConnector"); + return; } string serviceUrl = gridConfig.GetString("GridServerURI"); diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs index 9879295..a50ecbc 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs @@ -61,7 +61,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// Connects avatar inventories to the SimianGrid backend /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianInventoryServiceConnector : IInventoryService + public class SimianInventoryServiceConnector : IInventoryService, ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger( @@ -80,8 +80,8 @@ namespace OpenSim.Services.Connectors.SimianGrid public SimianInventoryServiceConnector() { } public string Name { get { return "SimianInventoryServiceConnector"; } } - public void AddRegion(Scene scene) { scene.RegisterModuleInterface(this); } - public void RemoveRegion(Scene scene) { scene.UnregisterModuleInterface(this); } + public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface(this); } } + public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface(this); } } #endregion ISharedRegionModule @@ -95,8 +95,8 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig gridConfig = source.Configs["InventoryService"]; if (gridConfig == null) { - m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini"); - throw new Exception("Inventory connector init error"); + m_log.Info("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini, skipping SimianInventoryServiceConnector"); + return; } string serviceUrl = gridConfig.GetString("InventoryServerURI"); diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs index 45d1824..542093f 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs @@ -51,7 +51,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// message routing) to the SimianGrid backend /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianPresenceServiceConnector : IPresenceService + public class SimianPresenceServiceConnector : IPresenceService, ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger( @@ -70,23 +70,29 @@ namespace OpenSim.Services.Connectors.SimianGrid public string Name { get { return "SimianPresenceServiceConnector"; } } public void AddRegion(Scene scene) { - scene.RegisterModuleInterface(this); + if (!String.IsNullOrEmpty(m_serverUrl)) + { + scene.RegisterModuleInterface(this); - scene.EventManager.OnMakeRootAgent += MakeRootAgentHandler; - scene.EventManager.OnNewClient += NewClientHandler; - scene.EventManager.OnSignificantClientMovement += SignificantClientMovementHandler; + scene.EventManager.OnMakeRootAgent += MakeRootAgentHandler; + scene.EventManager.OnNewClient += NewClientHandler; + scene.EventManager.OnSignificantClientMovement += SignificantClientMovementHandler; - LogoutRegionAgents(scene.RegionInfo.RegionID); + LogoutRegionAgents(scene.RegionInfo.RegionID); + } } public void RemoveRegion(Scene scene) { - scene.UnregisterModuleInterface(this); + if (!String.IsNullOrEmpty(m_serverUrl)) + { + scene.UnregisterModuleInterface(this); - scene.EventManager.OnMakeRootAgent -= MakeRootAgentHandler; - scene.EventManager.OnNewClient -= NewClientHandler; - scene.EventManager.OnSignificantClientMovement -= SignificantClientMovementHandler; + scene.EventManager.OnMakeRootAgent -= MakeRootAgentHandler; + scene.EventManager.OnNewClient -= NewClientHandler; + scene.EventManager.OnSignificantClientMovement -= SignificantClientMovementHandler; - LogoutRegionAgents(scene.RegionInfo.RegionID); + LogoutRegionAgents(scene.RegionInfo.RegionID); + } } #endregion ISharedRegionModule @@ -101,8 +107,8 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig gridConfig = source.Configs["PresenceService"]; if (gridConfig == null) { - m_log.Error("[PRESENCE CONNECTOR]: PresenceService missing from OpenSim.ini"); - throw new Exception("Presence connector init error"); + m_log.Info("[PRESENCE CONNECTOR]: PresenceService missing from OpenSim.ini, skipping SimianPresenceServiceConnector"); + return; } string serviceUrl = gridConfig.GetString("PresenceServerURI"); diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs index 32f17ae..b3b171c 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs @@ -60,7 +60,7 @@ namespace OpenSim.Services.Connectors.SimianGrid /// backend /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianProfiles + public class SimianProfiles : INonSharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger( @@ -69,15 +69,15 @@ namespace OpenSim.Services.Connectors.SimianGrid private string m_serverUrl = String.Empty; #region INonSharedRegionModule - + public Type ReplaceableInterface { get { return null; } } public void RegionLoaded(Scene scene) { } public void Close() { } public SimianProfiles() { } public string Name { get { return "SimianProfiles"; } } - public void AddRegion(Scene scene) { CheckEstateManager(scene); scene.EventManager.OnClientConnect += ClientConnectHandler; } - public void RemoveRegion(Scene scene) { scene.EventManager.OnClientConnect -= ClientConnectHandler; } + public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { CheckEstateManager(scene); scene.EventManager.OnClientConnect += ClientConnectHandler; } } + public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.EventManager.OnClientConnect -= ClientConnectHandler; } } #endregion INonSharedRegionModule @@ -91,8 +91,8 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig gridConfig = source.Configs["UserAccountService"]; if (gridConfig == null) { - m_log.Error("[PROFILES]: UserAccountService missing from OpenSim.ini"); - throw new Exception("Profiles init error"); + m_log.Error("[PROFILES]: UserAccountService missing from OpenSim.ini, skipping SimianProfiles"); + return; } string serviceUrl = gridConfig.GetString("UserAccountServerURI"); diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs index 708ced3..855b213 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs @@ -47,14 +47,14 @@ namespace OpenSim.Services.Connectors.SimianGrid /// users) to the SimianGrid backend /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianUserAccountServiceConnector : IUserAccountService + public class SimianUserAccountServiceConnector : IUserAccountService, ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); private string m_serverUrl = String.Empty; - private ExpiringCache m_accountCache = new ExpiringCache(); + private ExpiringCache m_accountCache; #region ISharedRegionModule @@ -65,8 +65,8 @@ namespace OpenSim.Services.Connectors.SimianGrid public SimianUserAccountServiceConnector() { } public string Name { get { return "SimianUserAccountServiceConnector"; } } - public void AddRegion(Scene scene) { scene.RegisterModuleInterface(this); } - public void RemoveRegion(Scene scene) { scene.UnregisterModuleInterface(this); } + public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface(this); } } + public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface(this); } } #endregion ISharedRegionModule @@ -80,8 +80,8 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig assetConfig = source.Configs["UserAccountService"]; if (assetConfig == null) { - m_log.Error("[ACCOUNT CONNECTOR]: UserAccountService missing from OpenSim.ini"); - throw new Exception("User account connector init error"); + m_log.Error("[ACCOUNT CONNECTOR]: UserAccountService missing from OpenSim.ini, skipping SimianUserAccountServiceConnector"); + return; } string serviceURI = assetConfig.GetString("UserAccountServerURI"); @@ -91,6 +91,7 @@ namespace OpenSim.Services.Connectors.SimianGrid throw new Exception("User account connector init error"); } + m_accountCache = new ExpiringCache(); m_serverUrl = serviceURI; } -- cgit v1.1 From 9e3cdc4da5483ce0187c7774fa274e99845da232 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Fri, 12 Mar 2010 13:28:16 -0800 Subject: Fixing the previous patch to work correctly with standalone mode --- .../Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs | 8 ++++---- .../Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs | 8 ++++---- .../Connectors/SimianGrid/SimianAvatarServiceConnector.cs | 8 ++++---- .../Connectors/SimianGrid/SimianFriendsServiceConnector.cs | 8 ++++---- .../Services/Connectors/SimianGrid/SimianGridServiceConnector.cs | 8 ++++---- .../Connectors/SimianGrid/SimianInventoryServiceConnector.cs | 8 ++++---- .../Connectors/SimianGrid/SimianPresenceServiceConnector.cs | 8 ++++---- OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs | 8 ++++---- .../Connectors/SimianGrid/SimianUserAccountServiceConnector.cs | 8 ++++---- 9 files changed, 36 insertions(+), 36 deletions(-) diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs index 89aa911..3f00534 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs @@ -88,15 +88,15 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig gridConfig = source.Configs["AssetService"]; if (gridConfig == null) { - m_log.Info("[ASSET CONNECTOR]: AssetService missing from OpenSim.ini, skipping SimianAssetServiceConnector"); - return; + m_log.Error("[ASSET CONNECTOR]: AssetService missing from OpenSim.ini"); + throw new Exception("Asset connector init error"); } string serviceUrl = gridConfig.GetString("AssetServerURI"); if (String.IsNullOrEmpty(serviceUrl)) { - m_log.Error("[ASSET CONNECTOR]: No AssetServerURI in section AssetService"); - throw new Exception("Asset connector init error"); + m_log.Info("[ASSET CONNECTOR]: No AssetServerURI in section AssetService, skipping SimianAssetServiceConnector"); + return; } if (!serviceUrl.EndsWith("/")) diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs index 55aca36..0876efb 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs @@ -76,15 +76,15 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig assetConfig = source.Configs["AuthenticationService"]; if (assetConfig == null) { - m_log.Info("[AUTH CONNECTOR]: AuthenticationService missing from OpenSim.ini, skipping SimianAuthenticationServiceConnector"); - return; + m_log.Error("[AUTH CONNECTOR]: AuthenticationService missing from OpenSim.ini"); + throw new Exception("Authentication connector init error"); } string serviceURI = assetConfig.GetString("AuthenticationServerURI"); if (String.IsNullOrEmpty(serviceURI)) { - m_log.Error("[AUTH CONNECTOR]: No Server URI named in section AuthenticationService"); - throw new Exception("Authentication connector init error"); + m_log.Info("[AUTH CONNECTOR]: No Server URI named in section AuthenticationService, skipping SimianAuthenticationServiceConnector"); + return; } m_serverUrl = serviceURI; diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs index b5cef0c..697bb43 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs @@ -81,15 +81,15 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig gridConfig = source.Configs["AvatarService"]; if (gridConfig == null) { - m_log.Info("[AVATAR CONNECTOR]: AvatarService missing from OpenSim.ini, skipping SimianAvatarServiceConnector"); - return; + m_log.Error("[AVATAR CONNECTOR]: AvatarService missing from OpenSim.ini"); + throw new Exception("Avatar connector init error"); } string serviceUrl = gridConfig.GetString("AvatarServerURI"); if (String.IsNullOrEmpty(serviceUrl)) { - m_log.Error("[AVATAR CONNECTOR]: No AvatarServerURI in section AvatarService"); - throw new Exception("Avatar connector init error"); + m_log.Info("[AVATAR CONNECTOR]: No AvatarServerURI in section AvatarService, skipping SimianAvatarServiceConnector"); + return; } if (!serviceUrl.EndsWith("/")) diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs index a569e91..abb98a3 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs @@ -79,15 +79,15 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig assetConfig = source.Configs["FriendsService"]; if (assetConfig == null) { - m_log.Info("[FRIENDS CONNECTOR]: FriendsService missing from OpenSim.ini, skipping SimianFriendsServiceConnector"); - return; + m_log.Error("[FRIENDS CONNECTOR]: FriendsService missing from OpenSim.ini"); + throw new Exception("Friends connector init error"); } string serviceURI = assetConfig.GetString("FriendsServerURI"); if (String.IsNullOrEmpty(serviceURI)) { - m_log.Error("[FRIENDS CONNECTOR]: No Server URI named in section FriendsService"); - throw new Exception("Friends connector init error"); + m_log.Info("[FRIENDS CONNECTOR]: No Server URI named in section FriendsService, skipping SimianFriendsServiceConnector"); + return; } m_serverUrl = serviceURI; diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs index 2e600f0..ef943ec 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs @@ -83,15 +83,15 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig gridConfig = source.Configs["GridService"]; if (gridConfig == null) { - m_log.Info("[GRID CONNECTOR]: GridService missing from OpenSim.ini, skipping SimianGridServiceConnector"); - return; + m_log.Error("[GRID CONNECTOR]: GridService missing from OpenSim.ini"); + throw new Exception("Grid connector init error"); } string serviceUrl = gridConfig.GetString("GridServerURI"); if (String.IsNullOrEmpty(serviceUrl)) { - m_log.Error("[GRID CONNECTOR]: No Server URI named in section GridService"); - throw new Exception("Grid connector init error"); + m_log.Info("[GRID CONNECTOR]: No Server URI named in section GridService, skipping SimianGridServiceConnector"); + return; } m_serverUrl = serviceUrl; diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs index a50ecbc..a41e493 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs @@ -95,15 +95,15 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig gridConfig = source.Configs["InventoryService"]; if (gridConfig == null) { - m_log.Info("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini, skipping SimianInventoryServiceConnector"); - return; + m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini"); + throw new Exception("Inventory connector init error"); } string serviceUrl = gridConfig.GetString("InventoryServerURI"); if (String.IsNullOrEmpty(serviceUrl)) { - m_log.Error("[INVENTORY CONNECTOR]: No Server URI named in section InventoryService"); - throw new Exception("Inventory connector init error"); + m_log.Info("[INVENTORY CONNECTOR]: No Server URI named in section InventoryService, skipping SimianInventoryServiceConnector"); + return; } // FIXME: Get the user server URL too diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs index 542093f..fa387ba 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs @@ -107,15 +107,15 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig gridConfig = source.Configs["PresenceService"]; if (gridConfig == null) { - m_log.Info("[PRESENCE CONNECTOR]: PresenceService missing from OpenSim.ini, skipping SimianPresenceServiceConnector"); - return; + m_log.Error("[PRESENCE CONNECTOR]: PresenceService missing from OpenSim.ini"); + throw new Exception("Presence connector init error"); } string serviceUrl = gridConfig.GetString("PresenceServerURI"); if (String.IsNullOrEmpty(serviceUrl)) { - m_log.Error("[PRESENCE CONNECTOR]: No PresenceServerURI in section PresenceService"); - throw new Exception("Presence connector init error"); + m_log.Info("[PRESENCE CONNECTOR]: No PresenceServerURI in section PresenceService, skipping SimianPresenceServiceConnector"); + return; } m_serverUrl = serviceUrl; diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs index b3b171c..3c93725 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs @@ -91,15 +91,15 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig gridConfig = source.Configs["UserAccountService"]; if (gridConfig == null) { - m_log.Error("[PROFILES]: UserAccountService missing from OpenSim.ini, skipping SimianProfiles"); - return; + m_log.Error("[PROFILES]: UserAccountService missing from OpenSim.ini"); + throw new Exception("Profiles init error"); } string serviceUrl = gridConfig.GetString("UserAccountServerURI"); if (String.IsNullOrEmpty(serviceUrl)) { - m_log.Error("[PROFILES]: No UserAccountServerURI in section UserAccountService"); - throw new Exception("Profiles init error"); + m_log.Info("[PROFILES]: No UserAccountServerURI in section UserAccountService, skipping SimianProfiles"); + return; } if (!serviceUrl.EndsWith("/")) diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs index 855b213..3a35d9a 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs @@ -80,15 +80,15 @@ namespace OpenSim.Services.Connectors.SimianGrid IConfig assetConfig = source.Configs["UserAccountService"]; if (assetConfig == null) { - m_log.Error("[ACCOUNT CONNECTOR]: UserAccountService missing from OpenSim.ini, skipping SimianUserAccountServiceConnector"); - return; + m_log.Error("[ACCOUNT CONNECTOR]: UserAccountService missing from OpenSim.ini"); + throw new Exception("User account connector init error"); } string serviceURI = assetConfig.GetString("UserAccountServerURI"); if (String.IsNullOrEmpty(serviceURI)) { - m_log.Error("[ACCOUNT CONNECTOR]: No UserAccountServerURI in section UserAccountService"); - throw new Exception("User account connector init error"); + m_log.Info("[ACCOUNT CONNECTOR]: No UserAccountServerURI in section UserAccountService, skipping SimianUserAccountServiceConnector"); + return; } m_accountCache = new ExpiringCache(); -- cgit v1.1 From 19b4770fe7620b184060b57fe5fa4418c5010c14 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Mar 2010 22:18:48 +0000 Subject: start laoding griduser local connector, though it isn't invoked by anything yet --- .../Resources/CoreModulePlugin.addin.xml | 3 ++ bin/config-include/Standalone.ini | 40 ++++++++++++---------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml index 0195c03..aaa318c 100644 --- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml +++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml @@ -56,6 +56,9 @@ + + + diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini index 54e11af..92c2154 100644 --- a/bin/config-include/Standalone.ini +++ b/bin/config-include/Standalone.ini @@ -5,17 +5,18 @@ ;; [Modules] - AssetServices = "LocalAssetServicesConnector" - InventoryServices = "LocalInventoryServicesConnector" - NeighbourServices = "LocalNeighbourServicesConnector" - AuthenticationServices = "LocalAuthenticationServicesConnector" - GridServices = "LocalGridServicesConnector" - PresenceServices = "LocalPresenceServicesConnector" - UserAccountServices = "LocalUserAccountServicesConnector" - SimulationServices = "LocalSimulationConnectorModule" - AvatarServices = "LocalAvatarServicesConnector" - EntityTransferModule = "BasicEntityTransferModule" - InventoryAccessModule = "BasicInventoryAccessModule" + AssetServices = "LocalAssetServicesConnector" + InventoryServices = "LocalInventoryServicesConnector" + NeighbourServices = "LocalNeighbourServicesConnector" + AuthenticationServices = "LocalAuthenticationServicesConnector" + GridServices = "LocalGridServicesConnector" + PresenceServices = "LocalPresenceServicesConnector" + UserAccountServices = "LocalUserAccountServicesConnector" + GridUserServices = "LocalGridUserServicesConnector" + SimulationServices = "LocalSimulationConnectorModule" + AvatarServices = "LocalAvatarServicesConnector" + EntityTransferModule = "BasicEntityTransferModule" + InventoryAccessModule = "BasicInventoryAccessModule" LibraryModule = true LLLoginServiceInConnector = true @@ -57,6 +58,9 @@ GridService = "OpenSim.Services.GridService.dll:GridService" InventoryService = "OpenSim.Services.InventoryService.dll:InventoryService" +[GridUserService] + LocalServiceModule = "OpenSim.Services.UserAccountService.dll:GridUserService" + [FriendsService] LocalServiceModule = "OpenSim.Services.FriendsService.dll" @@ -64,14 +68,14 @@ Connector = "OpenSim.Services.FriendsService.dll" [LoginService] - LocalServiceModule = "OpenSim.Services.LLLoginService.dll:LLLoginService" - UserAccountService = "OpenSim.Services.UserAccountService.dll:UserAccountService" + LocalServiceModule = "OpenSim.Services.LLLoginService.dll:LLLoginService" + UserAccountService = "OpenSim.Services.UserAccountService.dll:UserAccountService" AuthenticationService = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" - InventoryService = "OpenSim.Services.InventoryService.dll:InventoryService" - PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService" - GridService = "OpenSim.Services.GridService.dll:GridService" - AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService" - FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService" + InventoryService = "OpenSim.Services.InventoryService.dll:InventoryService" + PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService" + GridService = "OpenSim.Services.GridService.dll:GridService" + AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService" + FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService" WelcomeMessage = "Welcome, Avatar!" -- cgit v1.1 From 3036aba875187923b4e4d8481d46334e53393107 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Fri, 12 Mar 2010 14:28:31 -0800 Subject: * Added a better check to the SimianGrid connectors to test if they are enabled or not. This method should work equally well with standalone or robust mode * Applying #4602 from Misterblu to add collision detection to BulletDotNET --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 1 + .../BulletDotNETPlugin/BulletDotNETCharacter.cs | 33 +- .../Physics/BulletDotNETPlugin/BulletDotNETPrim.cs | 102 +- .../BulletDotNETPlugin/BulletDotNETScene.cs | 99 +- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 4 +- .../SimianGrid/SimianAssetServiceConnector.cs | 31 +- .../SimianAuthenticationServiceConnector.cs | 27 +- .../SimianGrid/SimianAvatarServiceConnector.cs | 31 +- .../SimianGrid/SimianFriendsServiceConnector.cs | 27 +- .../Services/Connectors/SimianGrid/SimianGrid.cs | 16 + .../SimianGrid/SimianGridServiceConnector.cs | 27 +- .../SimianGrid/SimianInventoryServiceConnector.cs | 41 +- .../SimianGrid/SimianPresenceServiceConnector.cs | 27 +- .../Connectors/SimianGrid/SimianProfiles.cs | 31 +- .../SimianUserAccountServiceConnector.cs | 29 +- bin/BulletDotNET.dll | Bin 58880 -> 58880 bytes bin/Newtonsoft.Json.XML | 11654 +++++++++---------- bin/libbulletnet.dll | Bin 360448 -> 369664 bytes 18 files changed, 6190 insertions(+), 5990 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 8967252..a2b98b9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2044,6 +2044,7 @@ namespace OpenSim.Region.Framework.Scenes { m_lastColliders.Remove(localID); } + if (m_parentGroup == null) return; if (m_parentGroup.IsDeleted) diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs index 6a54705..ac4e2b9 100644 --- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs +++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs @@ -108,12 +108,11 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin private bool[] m_colliderarr = new bool[11]; private bool[] m_colliderGroundarr = new bool[11]; - - private BulletDotNETScene m_parent_scene; public int m_eventsubscription = 0; - // private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); + private CollisionEventUpdate CollisionEventsThisFrame = null; + private int m_requestedUpdateFrequency = 0; public BulletDotNETCharacter(string avName, BulletDotNETScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor) { @@ -212,7 +211,8 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin m_mass = Mass; Body = new btRigidBody(m_mass, m_bodyMotionState, Shell); - Body.setUserPointer(new IntPtr((int)Body.Handle)); + // this is used for self identification. User localID instead of body handle + Body.setUserPointer(new IntPtr((int)m_localID)); if (ClosestCastResult != null) ClosestCastResult.Dispose(); @@ -717,6 +717,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin public override void SubscribeEvents(int ms) { m_eventsubscription = ms; + m_requestedUpdateFrequency = ms; m_parent_scene.addCollisionEventReporting(this); } @@ -724,6 +725,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin { m_parent_scene.remCollisionEventReporting(this); m_eventsubscription = 0; + m_requestedUpdateFrequency = 0; } public override bool SubscribedEvents() @@ -733,6 +735,29 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin return false; } + public void AddCollision(uint collideWith, ContactPoint contact) + { + if (CollisionEventsThisFrame == null) + { + CollisionEventsThisFrame = new CollisionEventUpdate(); + } + CollisionEventsThisFrame.addCollider(collideWith, contact); + } + + public void SendCollisions() + { + if (m_eventsubscription >= m_requestedUpdateFrequency) + { + if (CollisionEventsThisFrame != null) + { + base.SendCollisionUpdate(CollisionEventsThisFrame); + } + CollisionEventsThisFrame = new CollisionEventUpdate(); + m_eventsubscription = 0; + } + return; + } + internal void Dispose() { if (Body.isInWorld()) diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs index 920ed96..dc3229a 100644 --- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs +++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs @@ -154,7 +154,8 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin private Vector3 _target_velocity; public int m_eventsubscription; - // private CollisionEventUpdate CollisionEventsThisFrame = null; + private int m_requestedUpdateFrequency = 0; + private CollisionEventUpdate CollisionEventsThisFrame = null; public volatile bool childPrim; @@ -595,6 +596,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin public override void SubscribeEvents(int ms) { m_eventsubscription = ms; + m_requestedUpdateFrequency = ms; _parent_scene.addCollisionEventReporting(this); } @@ -602,6 +604,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin { _parent_scene.remCollisionEventReporting(this); m_eventsubscription = 0; + m_requestedUpdateFrequency = 0; } public override bool SubscribedEvents() @@ -611,7 +614,28 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin #endregion + public void AddCollision(uint collideWith, ContactPoint contact) + { + if (CollisionEventsThisFrame == null) + { + CollisionEventsThisFrame = new CollisionEventUpdate(); + } + CollisionEventsThisFrame.addCollider(collideWith, contact); + } + public void SendCollisions() + { + if (m_eventsubscription >= m_requestedUpdateFrequency) + { + if (CollisionEventsThisFrame != null) + { + base.SendCollisionUpdate(CollisionEventsThisFrame); + } + CollisionEventsThisFrame = null; + // m_eventsubscription = 0; + } + return; + } internal void Dispose() { @@ -759,7 +783,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin { if (m_taintadd) { - m_log.Debug("[PHYSICS]: TaintAdd"); + // m_log.Debug("[PHYSICS]: TaintAdd"); changeadd(timestep); } @@ -771,7 +795,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin SetBody(Mass); else SetBody(0); - m_log.Debug("[PHYSICS]: GEOM_DOESNT_EXSIT"); + // m_log.Debug("[PHYSICS]: GEOM_DOESNT_EXSIT"); } if (prim_geom.Handle == IntPtr.Zero) @@ -782,31 +806,31 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin SetBody(Mass); else SetBody(0); - m_log.Debug("[PHYSICS]: GEOM_DOESNT_EXSIT"); + // m_log.Debug("[PHYSICS]: GEOM_DOESNT_EXSIT"); } if (!_position.ApproxEquals(m_taintposition, 0f)) { - m_log.Debug("[PHYSICS]: TaintMove"); + // m_log.Debug("[PHYSICS]: TaintMove"); changemove(timestep); } if (m_taintrot != _orientation) { - m_log.Debug("[PHYSICS]: TaintRotate"); + // m_log.Debug("[PHYSICS]: TaintRotate"); rotate(timestep); } // if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent)) { - m_log.Debug("[PHYSICS]: TaintPhysics"); + // m_log.Debug("[PHYSICS]: TaintPhysics"); changePhysicsStatus(timestep); } // if (!_size.ApproxEquals(m_taintsize, 0f)) { - m_log.Debug("[PHYSICS]: TaintSize"); + // m_log.Debug("[PHYSICS]: TaintSize"); changesize(timestep); } @@ -814,43 +838,43 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin if (m_taintshape) { - m_log.Debug("[PHYSICS]: TaintShape"); + // m_log.Debug("[PHYSICS]: TaintShape"); changeshape(timestep); } // if (m_taintforce) { - m_log.Debug("[PHYSICS]: TaintForce"); + // m_log.Debug("[PHYSICS]: TaintForce"); changeAddForce(timestep); } if (m_taintaddangularforce) { - m_log.Debug("[PHYSICS]: TaintAngularForce"); + // m_log.Debug("[PHYSICS]: TaintAngularForce"); changeAddAngularForce(timestep); } if (!m_taintTorque.ApproxEquals(Vector3.Zero, 0.001f)) { - m_log.Debug("[PHYSICS]: TaintTorque"); + // m_log.Debug("[PHYSICS]: TaintTorque"); changeSetTorque(timestep); } if (m_taintdisable) { - m_log.Debug("[PHYSICS]: TaintDisable"); + // m_log.Debug("[PHYSICS]: TaintDisable"); changedisable(timestep); } if (m_taintselected != m_isSelected) { - m_log.Debug("[PHYSICS]: TaintSelected"); + // m_log.Debug("[PHYSICS]: TaintSelected"); changeSelectedStatus(timestep); } if (!m_taintVelocity.ApproxEquals(Vector3.Zero, 0.001f)) { - m_log.Debug("[PHYSICS]: TaintVelocity"); + // m_log.Debug("[PHYSICS]: TaintVelocity"); changevelocity(timestep); } if (m_taintparent != _parent) { - m_log.Debug("[PHYSICS]: TaintLink"); + // m_log.Debug("[PHYSICS]: TaintLink"); changelink(timestep); } if (m_taintCollidesWater != m_collidesWater) @@ -859,7 +883,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin } if (!m_angularlock.ApproxEquals(m_taintAngularLock, 0)) { - m_log.Debug("[PHYSICS]: TaintAngularLock"); + // m_log.Debug("[PHYSICS]: TaintAngularLock"); changeAngularLock(timestep); } if (m_taintremove) @@ -917,7 +941,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin private void changemove(float timestep) { - m_log.Debug("[PHYSICS]: _________ChangeMove"); + // m_log.Debug("[PHYSICS]: _________ChangeMove"); if (!m_isphysical) { tempTransform2 = Body.getWorldTransform(); @@ -977,7 +1001,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin private void rotate(float timestep) { - m_log.Debug("[PHYSICS]: _________ChangeRotate"); + // m_log.Debug("[PHYSICS]: _________ChangeRotate"); tempTransform2 = Body.getWorldTransform(); tempOrientation2 = new btQuaternion(_orientation.X, _orientation.Y, _orientation.Z, _orientation.W); tempTransform2.setRotation(tempOrientation2); @@ -1000,7 +1024,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin //Body = null; // TODO: dispose parts that make up body } - m_log.Debug("[PHYSICS]: _________ChangePhysics"); + // m_log.Debug("[PHYSICS]: _________ChangePhysics"); ProcessGeomCreation(); @@ -1092,7 +1116,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin // TODO: dispose parts that make up body } - m_log.Debug("[PHYSICS]: _________ChangeSize"); + // m_log.Debug("[PHYSICS]: _________ChangeSize"); SetCollisionShape(null); // Construction of new prim ProcessGeomCreation(); @@ -1297,13 +1321,13 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin // TODO: throw new NotImplementedException(); if (m_taintselected) { - Body.setCollisionFlags((int)ContactFlags.CF_NO_CONTACT_RESPONSE); + // Body.setCollisionFlags((int)ContactFlags.CF_NO_CONTACT_RESPONSE); disableBodySoft(); } else { - Body.setCollisionFlags(0 | (int)ContactFlags.CF_CUSTOM_MATERIAL_CALLBACK); + // Body.setCollisionFlags(0 | (int)ContactFlags.CF_CUSTOM_MATERIAL_CALLBACK); enableBodySoft(); } m_isSelected = m_taintselected; @@ -1605,6 +1629,11 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin enableBodySoft(); } */ + if (!Body.isActive()) + { + Body.clearForces(); + enableBodySoft(); + } // 35x10 = 350n times the mass per second applied maximum. float nmax = 35f * m_mass; @@ -1632,6 +1661,12 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin Body.applyCentralImpulse(tempAddForce); } } + else + { + // if no forces on the prim, make sure everything is zero + Body.clearForces(); + enableBodySoft(); + } } else { @@ -1985,7 +2020,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin public void CreateGeom(IntPtr m_targetSpace, IMesh p_mesh) { - m_log.Debug("[PHYSICS]: _________CreateGeom"); + // m_log.Debug("[PHYSICS]: _________CreateGeom"); if (p_mesh != null) { //_mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); @@ -2042,7 +2077,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin // TODO: Set Collision Body Mesh // This sleeper is there to moderate how long it takes between // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object - m_log.Debug("_________SetMesh"); + // m_log.Debug("_________SetMesh"); Thread.Sleep(10); //Kill Body so that mesh can re-make the geom @@ -2159,7 +2194,14 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin // Body = new btRigidBody(mass, tempMotionState1, prim_geom); //else - Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1); + // Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1); + if (Body == null) + { + Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1); + // add localID so we can later map bullet object back to OpenSim object + Body.setUserPointer(new IntPtr((int)m_localID)); + } + if (prim_geom is btGImpactMeshShape) { @@ -2250,7 +2292,13 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin // Body = new btRigidBody(mass, tempMotionState1, prim_geom); //else - Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1); + // Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1); + if (Body == null) + { + Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1); + // each body has the localID stored into it so we can identify collision objects + Body.setUserPointer(new IntPtr((int)m_localID)); + } if (prim_geom is btGImpactMeshShape) { diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs index 9e048ab..85e34c1 100644 --- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs +++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs @@ -47,7 +47,9 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin // private string m_sceneIdentifier = string.Empty; private List m_characters = new List(); + private Dictionary m_charactersLocalID = new Dictionary(); private List m_prims = new List(); + private Dictionary m_primsLocalID = new Dictionary(); private List m_activePrims = new List(); private List m_taintedActors = new List(); private btDiscreteDynamicsWorld m_world; @@ -134,7 +136,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_world = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration); m_world.setGravity(m_gravity); - //EnableCollisionInterface(); + EnableCollisionInterface(); } @@ -145,7 +147,16 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin avCapRadius, avStandupTensor, avDensity, avHeightFudgeFactor, avMovementDivisorWalk, avMovementDivisorRun); - m_characters.Add(chr); + try + { + m_characters.Add(chr); + m_charactersLocalID.Add(chr.m_localID, chr); + } + catch + { + // noop if it's already there + m_log.Debug("[PHYSICS] BulletDotNet: adding duplicate avatar localID"); + } AddPhysicsActorTaint(chr); return chr; } @@ -154,6 +165,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin { BulletDotNETCharacter chr = (BulletDotNETCharacter) actor; + m_charactersLocalID.Remove(chr.m_localID); m_characters.Remove(chr); m_world.removeRigidBody(chr.Body); m_world.removeCollisionObject(chr.Body); @@ -279,7 +291,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin prim.Move(timeStep); } } - float steps = m_world.stepSimulation(timeStep * 1000, 10, WorldTimeComp); + float steps = m_world.stepSimulation(timeStep, 10, WorldTimeComp); foreach (BulletDotNETCharacter chr in m_characters) { @@ -296,20 +308,67 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin } if (m_CollisionInterface != null) { - List collisions = m_CollisionInterface.GetContactList(); - lock (collisions) + List primsWithCollisions = new List(); + List charactersWithCollisions = new List(); + + // get the collisions that happened this tick + List collisions = m_CollisionInterface.GetContactList(); + // passed back the localID of the prim so we can associate the prim + foreach (BulletDotNET.ContactAddedCallbackHandler.ContactInfo ci in collisions) { - foreach (int pvalue in collisions) - { - System.Console.Write(string.Format("{0} ", pvalue)); - } + // ContactPoint = { contactPoint, contactNormal, penetrationDepth } + ContactPoint contact = new ContactPoint(new Vector3(ci.pX, ci.pY, ci.pZ), + new Vector3(ci.nX, ci.nY, ci.nZ), ci.depth); + + ProcessContact(ci.contact, ci.contactWith, contact, ref primsWithCollisions, ref charactersWithCollisions); + ProcessContact(ci.contactWith, ci.contact, contact, ref primsWithCollisions, ref charactersWithCollisions); + } m_CollisionInterface.Clear(); - + // for those prims and characters that had collisions cause collision events + foreach (BulletDotNETPrim bdnp in primsWithCollisions) + { + bdnp.SendCollisions(); + } + foreach (BulletDotNETCharacter bdnc in charactersWithCollisions) + { + bdnc.SendCollisions(); + } } return steps; } + private void ProcessContact(uint cont, uint contWith, ContactPoint contact, + ref List primsWithCollisions, + ref List charactersWithCollisions) + { + BulletDotNETPrim bdnp; + // collisions with a normal prim? + if (m_primsLocalID.TryGetValue(cont, out bdnp)) + { + // Added collision event to the prim. This creates a pile of events + // that will be sent to any subscribed listeners. + bdnp.AddCollision(contWith, contact); + if (!primsWithCollisions.Contains(bdnp)) + { + primsWithCollisions.Add(bdnp); + } + } + else + { + BulletDotNETCharacter bdnc; + // if not a prim, maybe it's one of the characters + if (m_charactersLocalID.TryGetValue(cont, out bdnc)) + { + bdnc.AddCollision(contWith, contact); + if (!charactersWithCollisions.Contains(bdnc)) + { + charactersWithCollisions.Add(bdnc); + } + } + } + } + public override void GetResults() { @@ -387,6 +446,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin m_terrainTransform = new btTransform(QuatIdentity, m_terrainPosition); m_terrainMotionState = new btDefaultMotionState(m_terrainTransform); TerrainBody = new btRigidBody(0, m_terrainMotionState, m_terrainShape); + TerrainBody.setUserPointer((IntPtr)0); m_world.addRigidBody(TerrainBody); @@ -459,6 +519,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin { lock (m_prims) { + m_primsLocalID.Clear(); foreach (BulletDotNETPrim prim in m_prims) { if (prim.Body != null) @@ -513,6 +574,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin m_world.removeRigidBody(body); } remActivePrim(prm); + m_primsLocalID.Remove(prm.m_localID); m_prims.Remove(prm); } @@ -686,9 +748,18 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin { if (!m_prims.Contains(pPrim)) { - m_prims.Add(pPrim); + try + { + m_prims.Add(pPrim); + m_primsLocalID.Add(pPrim.m_localID, pPrim); + } + catch + { + // noop if it's already there + m_log.Debug("[PHYSICS] BulletDotNet: adding duplicate prim localID"); + } m_world.addRigidBody(pPrim.Body); - m_log.Debug("ADDED"); + // m_log.Debug("[PHYSICS] added prim to scene"); } } } @@ -696,8 +767,8 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin { if (m_CollisionInterface == null) { - m_CollisionInterface = new ContactAddedCallbackHandler(); - m_world.SetCollisionAddedCallback(m_CollisionInterface); + m_CollisionInterface = new ContactAddedCallbackHandler(m_world); + // m_world.SetCollisionAddedCallback(m_CollisionInterface); } } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 03736d1..0720b5e 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -1575,11 +1575,11 @@ Console.WriteLine(" JointCreateFixed"); { //Console.WriteLine("Move " + m_primName); if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 - /* // NON-'VEHICLES' are dealt with here if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f)) { d.Vector3 avel2 = d.BodyGetAngularVel(Body); + /* if (m_angularlock.X == 1) avel2.X = 0; if (m_angularlock.Y == 1) @@ -1587,8 +1587,8 @@ Console.WriteLine(" JointCreateFixed"); if (m_angularlock.Z == 1) avel2.Z = 0; d.BodySetAngularVel(Body, avel2.X, avel2.Y, avel2.Z); + */ } - */ //float PID_P = 900.0f; float m_mass = CalculateMass(); diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs index 3f00534..7cb075e 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs @@ -85,24 +85,27 @@ namespace OpenSim.Services.Connectors.SimianGrid public void Initialise(IConfigSource source) { - IConfig gridConfig = source.Configs["AssetService"]; - if (gridConfig == null) + if (Simian.IsSimianEnabled(source, "AssetServices")) { - m_log.Error("[ASSET CONNECTOR]: AssetService missing from OpenSim.ini"); - throw new Exception("Asset connector init error"); - } + IConfig gridConfig = source.Configs["AssetService"]; + if (gridConfig == null) + { + m_log.Error("[ASSET CONNECTOR]: AssetService missing from OpenSim.ini"); + throw new Exception("Asset connector init error"); + } - string serviceUrl = gridConfig.GetString("AssetServerURI"); - if (String.IsNullOrEmpty(serviceUrl)) - { - m_log.Info("[ASSET CONNECTOR]: No AssetServerURI in section AssetService, skipping SimianAssetServiceConnector"); - return; - } + string serviceUrl = gridConfig.GetString("AssetServerURI"); + if (String.IsNullOrEmpty(serviceUrl)) + { + m_log.Error("[ASSET CONNECTOR]: No AssetServerURI in section AssetService"); + throw new Exception("Asset connector init error"); + } - if (!serviceUrl.EndsWith("/")) - serviceUrl = serviceUrl + '/'; + if (!serviceUrl.EndsWith("/")) + serviceUrl = serviceUrl + '/'; - m_serverUrl = serviceUrl; + m_serverUrl = serviceUrl; + } } #region IAssetService diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs index 0876efb..6317b87 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs @@ -73,21 +73,24 @@ namespace OpenSim.Services.Connectors.SimianGrid public void Initialise(IConfigSource source) { - IConfig assetConfig = source.Configs["AuthenticationService"]; - if (assetConfig == null) + if (Simian.IsSimianEnabled(source, "AuthenticationServices")) { - m_log.Error("[AUTH CONNECTOR]: AuthenticationService missing from OpenSim.ini"); - throw new Exception("Authentication connector init error"); - } + IConfig assetConfig = source.Configs["AuthenticationService"]; + if (assetConfig == null) + { + m_log.Error("[AUTH CONNECTOR]: AuthenticationService missing from OpenSim.ini"); + throw new Exception("Authentication connector init error"); + } - string serviceURI = assetConfig.GetString("AuthenticationServerURI"); - if (String.IsNullOrEmpty(serviceURI)) - { - m_log.Info("[AUTH CONNECTOR]: No Server URI named in section AuthenticationService, skipping SimianAuthenticationServiceConnector"); - return; - } + string serviceURI = assetConfig.GetString("AuthenticationServerURI"); + if (String.IsNullOrEmpty(serviceURI)) + { + m_log.Error("[AUTH CONNECTOR]: No Server URI named in section AuthenticationService"); + throw new Exception("Authentication connector init error"); + } - m_serverUrl = serviceURI; + m_serverUrl = serviceURI; + } } public string Authenticate(UUID principalID, string password, int lifetime) diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs index 697bb43..a18cb22 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs @@ -78,24 +78,27 @@ namespace OpenSim.Services.Connectors.SimianGrid public void Initialise(IConfigSource source) { - IConfig gridConfig = source.Configs["AvatarService"]; - if (gridConfig == null) + if (Simian.IsSimianEnabled(source, "AvatarServices")) { - m_log.Error("[AVATAR CONNECTOR]: AvatarService missing from OpenSim.ini"); - throw new Exception("Avatar connector init error"); - } + IConfig gridConfig = source.Configs["AvatarService"]; + if (gridConfig == null) + { + m_log.Error("[AVATAR CONNECTOR]: AvatarService missing from OpenSim.ini"); + throw new Exception("Avatar connector init error"); + } - string serviceUrl = gridConfig.GetString("AvatarServerURI"); - if (String.IsNullOrEmpty(serviceUrl)) - { - m_log.Info("[AVATAR CONNECTOR]: No AvatarServerURI in section AvatarService, skipping SimianAvatarServiceConnector"); - return; - } + string serviceUrl = gridConfig.GetString("AvatarServerURI"); + if (String.IsNullOrEmpty(serviceUrl)) + { + m_log.Error("[AVATAR CONNECTOR]: No AvatarServerURI in section AvatarService"); + throw new Exception("Avatar connector init error"); + } - if (!serviceUrl.EndsWith("/")) - serviceUrl = serviceUrl + '/'; + if (!serviceUrl.EndsWith("/")) + serviceUrl = serviceUrl + '/'; - m_serverUrl = serviceUrl; + m_serverUrl = serviceUrl; + } } #region IAvatarService diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs index abb98a3..b3ecc7e 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs @@ -76,21 +76,24 @@ namespace OpenSim.Services.Connectors.SimianGrid public void Initialise(IConfigSource source) { - IConfig assetConfig = source.Configs["FriendsService"]; - if (assetConfig == null) + if (Simian.IsSimianEnabled(source, "FriendsServices")) { - m_log.Error("[FRIENDS CONNECTOR]: FriendsService missing from OpenSim.ini"); - throw new Exception("Friends connector init error"); - } + IConfig assetConfig = source.Configs["FriendsService"]; + if (assetConfig == null) + { + m_log.Error("[FRIENDS CONNECTOR]: FriendsService missing from OpenSim.ini"); + throw new Exception("Friends connector init error"); + } - string serviceURI = assetConfig.GetString("FriendsServerURI"); - if (String.IsNullOrEmpty(serviceURI)) - { - m_log.Info("[FRIENDS CONNECTOR]: No Server URI named in section FriendsService, skipping SimianFriendsServiceConnector"); - return; - } + string serviceURI = assetConfig.GetString("FriendsServerURI"); + if (String.IsNullOrEmpty(serviceURI)) + { + m_log.Error("[FRIENDS CONNECTOR]: No Server URI named in section FriendsService"); + throw new Exception("Friends connector init error"); + } - m_serverUrl = serviceURI; + m_serverUrl = serviceURI; + } } #region IFriendsService diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs index 41ed2f1..c3de98e 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs @@ -25,7 +25,23 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using Mono.Addins; +using Nini.Config; [assembly: Addin("SimianGrid", "1.0")] [assembly: AddinDependency("OpenSim", "0.5")] + +public static class Simian +{ + public static bool IsSimianEnabled(IConfigSource config, string moduleName) + { + if (config.Configs["Modules"] != null) + { + string module = config.Configs["Modules"].GetString("AuthenticationServices"); + return !String.IsNullOrEmpty(module) && module.Contains("Simian"); + } + + return false; + } +} \ No newline at end of file diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs index ef943ec..eebdf14 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs @@ -80,21 +80,24 @@ namespace OpenSim.Services.Connectors.SimianGrid public void Initialise(IConfigSource source) { - IConfig gridConfig = source.Configs["GridService"]; - if (gridConfig == null) + if (Simian.IsSimianEnabled(source, "GridServices")) { - m_log.Error("[GRID CONNECTOR]: GridService missing from OpenSim.ini"); - throw new Exception("Grid connector init error"); - } + IConfig gridConfig = source.Configs["GridService"]; + if (gridConfig == null) + { + m_log.Error("[GRID CONNECTOR]: GridService missing from OpenSim.ini"); + throw new Exception("Grid connector init error"); + } - string serviceUrl = gridConfig.GetString("GridServerURI"); - if (String.IsNullOrEmpty(serviceUrl)) - { - m_log.Info("[GRID CONNECTOR]: No Server URI named in section GridService, skipping SimianGridServiceConnector"); - return; - } + string serviceUrl = gridConfig.GetString("GridServerURI"); + if (String.IsNullOrEmpty(serviceUrl)) + { + m_log.Error("[GRID CONNECTOR]: No Server URI named in section GridService"); + throw new Exception("Grid connector init error"); + } - m_serverUrl = serviceUrl; + m_serverUrl = serviceUrl; + } } #region IGridService diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs index a41e493..891782f 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs @@ -92,23 +92,38 @@ namespace OpenSim.Services.Connectors.SimianGrid public void Initialise(IConfigSource source) { - IConfig gridConfig = source.Configs["InventoryService"]; - if (gridConfig == null) + if (Simian.IsSimianEnabled(source, "InventoryServices")) { - m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini"); - throw new Exception("Inventory connector init error"); - } + IConfig gridConfig = source.Configs["InventoryService"]; + if (gridConfig == null) + { + m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini"); + throw new Exception("Inventory connector init error"); + } - string serviceUrl = gridConfig.GetString("InventoryServerURI"); - if (String.IsNullOrEmpty(serviceUrl)) - { - m_log.Info("[INVENTORY CONNECTOR]: No Server URI named in section InventoryService, skipping SimianInventoryServiceConnector"); - return; - } + string serviceUrl = gridConfig.GetString("InventoryServerURI"); + if (String.IsNullOrEmpty(serviceUrl)) + { + m_log.Error("[INVENTORY CONNECTOR]: No Server URI named in section InventoryService"); + throw new Exception("Inventory connector init error"); + } - // FIXME: Get the user server URL too + m_serverUrl = serviceUrl; - m_serverUrl = serviceUrl; + gridConfig = source.Configs["UserAccountService"]; + if (gridConfig != null) + { + serviceUrl = gridConfig.GetString("UserAccountServerURI"); + if (!String.IsNullOrEmpty(serviceUrl)) + m_userServerUrl = serviceUrl; + else + m_log.Info("[INVENTORY CONNECTOR]: No Server URI named in section UserAccountService"); + } + else + { + m_log.Warn("[INVENTORY CONNECTOR]: UserAccountService missing from OpenSim.ini"); + } + } } /// diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs index fa387ba..1b5edf4 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs @@ -104,21 +104,24 @@ namespace OpenSim.Services.Connectors.SimianGrid public void Initialise(IConfigSource source) { - IConfig gridConfig = source.Configs["PresenceService"]; - if (gridConfig == null) + if (Simian.IsSimianEnabled(source, "PresenceServices")) { - m_log.Error("[PRESENCE CONNECTOR]: PresenceService missing from OpenSim.ini"); - throw new Exception("Presence connector init error"); - } + IConfig gridConfig = source.Configs["PresenceService"]; + if (gridConfig == null) + { + m_log.Error("[PRESENCE CONNECTOR]: PresenceService missing from OpenSim.ini"); + throw new Exception("Presence connector init error"); + } - string serviceUrl = gridConfig.GetString("PresenceServerURI"); - if (String.IsNullOrEmpty(serviceUrl)) - { - m_log.Info("[PRESENCE CONNECTOR]: No PresenceServerURI in section PresenceService, skipping SimianPresenceServiceConnector"); - return; - } + string serviceUrl = gridConfig.GetString("PresenceServerURI"); + if (String.IsNullOrEmpty(serviceUrl)) + { + m_log.Error("[PRESENCE CONNECTOR]: No PresenceServerURI in section PresenceService"); + throw new Exception("Presence connector init error"); + } - m_serverUrl = serviceUrl; + m_serverUrl = serviceUrl; + } } #region IPresenceService diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs index 3c93725..9c226fb 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs @@ -88,24 +88,27 @@ namespace OpenSim.Services.Connectors.SimianGrid public void Initialise(IConfigSource source) { - IConfig gridConfig = source.Configs["UserAccountService"]; - if (gridConfig == null) + if (Simian.IsSimianEnabled(source, "UserAccountServices")) { - m_log.Error("[PROFILES]: UserAccountService missing from OpenSim.ini"); - throw new Exception("Profiles init error"); - } + IConfig gridConfig = source.Configs["UserAccountService"]; + if (gridConfig == null) + { + m_log.Error("[PROFILES]: UserAccountService missing from OpenSim.ini"); + throw new Exception("Profiles init error"); + } - string serviceUrl = gridConfig.GetString("UserAccountServerURI"); - if (String.IsNullOrEmpty(serviceUrl)) - { - m_log.Info("[PROFILES]: No UserAccountServerURI in section UserAccountService, skipping SimianProfiles"); - return; - } + string serviceUrl = gridConfig.GetString("UserAccountServerURI"); + if (String.IsNullOrEmpty(serviceUrl)) + { + m_log.Error("[PROFILES]: No UserAccountServerURI in section UserAccountService"); + throw new Exception("Profiles init error"); + } - if (!serviceUrl.EndsWith("/")) - serviceUrl = serviceUrl + '/'; + if (!serviceUrl.EndsWith("/")) + serviceUrl = serviceUrl + '/'; - m_serverUrl = serviceUrl; + m_serverUrl = serviceUrl; + } } private void ClientConnectHandler(IClientCore clientCore) diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs index 3a35d9a..bb0ac57 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs @@ -77,22 +77,25 @@ namespace OpenSim.Services.Connectors.SimianGrid public void Initialise(IConfigSource source) { - IConfig assetConfig = source.Configs["UserAccountService"]; - if (assetConfig == null) + if (Simian.IsSimianEnabled(source, "UserAccountServices")) { - m_log.Error("[ACCOUNT CONNECTOR]: UserAccountService missing from OpenSim.ini"); - throw new Exception("User account connector init error"); - } + IConfig assetConfig = source.Configs["UserAccountService"]; + if (assetConfig == null) + { + m_log.Error("[ACCOUNT CONNECTOR]: UserAccountService missing from OpenSim.ini"); + throw new Exception("User account connector init error"); + } - string serviceURI = assetConfig.GetString("UserAccountServerURI"); - if (String.IsNullOrEmpty(serviceURI)) - { - m_log.Info("[ACCOUNT CONNECTOR]: No UserAccountServerURI in section UserAccountService, skipping SimianUserAccountServiceConnector"); - return; - } + string serviceURI = assetConfig.GetString("UserAccountServerURI"); + if (String.IsNullOrEmpty(serviceURI)) + { + m_log.Error("[ACCOUNT CONNECTOR]: No UserAccountServerURI in section UserAccountService, skipping SimianUserAccountServiceConnector"); + throw new Exception("User account connector init error"); + } - m_accountCache = new ExpiringCache(); - m_serverUrl = serviceURI; + m_accountCache = new ExpiringCache(); + m_serverUrl = serviceURI; + } } public UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName) diff --git a/bin/BulletDotNET.dll b/bin/BulletDotNET.dll index 8abe03a..40c4348 100644 Binary files a/bin/BulletDotNET.dll and b/bin/BulletDotNET.dll differ diff --git a/bin/Newtonsoft.Json.XML b/bin/Newtonsoft.Json.XML index 5af3593..1a1e56c 100644 --- a/bin/Newtonsoft.Json.XML +++ b/bin/Newtonsoft.Json.XML @@ -1,5827 +1,5827 @@ - - - - Newtonsoft.Json.Net20 - - - - - Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. - - - - - Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. - - - - - Initializes a new instance of the class with the specified . - - - - - Reads the next JSON token from the stream. - - true if the next token was read successfully; false if there are no more tokens to read. - - - - Reads the next JSON token from the stream as a . - - A or a null reference if the next JSON token is null. - - - - Skips the children of the current token. - - - - - Sets the current token. - - The new token. - - - - Sets the current token and value. - - The new token. - The value. - - - - Sets the state based on current token type. - - - - - Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - - - - - Releases unmanaged and - optionally - managed resources - - true to release both managed and unmanaged resources; false to release only unmanaged resources. - - - - Changes the to Closed. - - - - - Gets the current reader state. - - The current reader state. - - - - Gets the quotation mark character used to enclose the value of a string. - - - - - Gets the type of the current Json token. - - - - - Gets the text value of the current Json token. - - - - - Gets The Common Language Runtime (CLR) type for the current Json token. - - - - - Gets the depth of the current token in the JSON document. - - The depth of the current token in the JSON document. - - - - Specifies the state of the reader. - - - - - The Read method has not been called. - - - - - The end of the file has been reached successfully. - - - - - Reader is at a property. - - - - - Reader is at the start of an object. - - - - - Reader is in an object. - - - - - Reader is at the start of an array. - - - - - Reader is in an array. - - - - - The Close method has been called. - - - - - Reader has just read a value. - - - - - Reader is at the start of a constructor. - - - - - Reader in a constructor. - - - - - An error occurred that prevents the read operation from continuing. - - - - - The end of the file has been reached successfully. - - - - - Initializes a new instance of the class. - - The stream. - - - - Initializes a new instance of the class. - - The stream. - if set to true the root object will be read as a JSON array. - The used when reading values from BSON. - - - - Reads the next JSON token from the stream as a . - - - A or a null reference if the next JSON token is null. - - - - - Reads the next JSON token from the stream. - - - true if the next token was read successfully; false if there are no more tokens to read. - - - - - Gets or sets a value indicating whether the root object will be read as a JSON array. - - - true if the root object will be read as a JSON array; otherwise, false. - - - - - Gets or sets the used when reading values from BSON. - - The used when reading values from BSON. - - - - Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. - - - - - Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. - - - - - Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. - - - - - Creates an instance of the JsonWriter class. - - - - - Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. - - - - - Closes this stream and the underlying stream. - - - - - Writes the beginning of a Json object. - - - - - Writes the end of a Json object. - - - - - Writes the beginning of a Json array. - - - - - Writes the end of an array. - - - - - Writes the start of a constructor with the given name. - - The name of the constructor. - - - - Writes the end constructor. - - - - - Writes the property name of a name/value pair on a Json object. - - The name of the property. - - - - Writes the end of the current Json object or array. - - - - - Writes the current token. - - The to read the token from. - - - - Writes the specified end token. - - The end token to write. - - - - Writes indent characters. - - - - - Writes the JSON value delimiter. - - - - - Writes an indent space. - - - - - Writes a null value. - - - - - Writes an undefined value. - - - - - Writes raw JSON without changing the writer's state. - - The raw JSON to write. - - - - Writes raw JSON where a value is expected and updates the writer's state. - - The raw JSON to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - An error will raised if the value cannot be written as a single JSON token. - - The value to write. - - - - Writes out a comment /*...*/ containing the specified text. - - Text to place inside the comment. - - - - Writes out the given white space. - - The string of white space characters. - - - - Gets the top. - - The top. - - - - Gets the state of the writer. - - - - - Indicates how the output is formatted. - - - - - Initializes a new instance of the class writing to the given . - - The container being written to. - - - - Initializes a new instance of the class. - - - - - Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. - - - - - Closes this stream and the underlying stream. - - - - - Writes the beginning of a Json object. - - - - - Writes the beginning of a Json array. - - - - - Writes the start of a constructor with the given name. - - The name of the constructor. - - - - Writes the end. - - The token. - - - - Writes the property name of a name/value pair on a Json object. - - The name of the property. - - - - Writes a null value. - - - - - Writes an undefined value. - - - - - Writes raw JSON. - - The raw JSON to write. - - - - Writes out a comment /*...*/ containing the specified text. - - Text to place inside the comment. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Gets the token being writen. - - The token being writen. - - - - Initializes a new instance of the class. - - The stream. - - - - Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. - - - - - Writes the end. - - The token. - - - - Writes out a comment /*...*/ containing the specified text. - - Text to place inside the comment. - - - - Writes the start of a constructor with the given name. - - The name of the constructor. - - - - Writes raw JSON. - - The raw JSON to write. - - - - Writes raw JSON where a value is expected and updates the writer's state. - - The raw JSON to write. - - - - Specifies how constructors are used when initializing objects during deserialization by the . - - - - - First attempt to use the public default constructor then fall back to single paramatized constructor. - - - - - Allow Json.NET to use a non-public default constructor. - - - - - Converts a binary value to and from a base 64 string value. - - - - - Converts an object to and from JSON. - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Create a custom object - - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The calling serializer. - The object value. - - - - Creates an object which will then be populated by the serializer. - - Type of the object. - - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Converts a to and from JSON. - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified value type. - - Type of the value. - - true if this instance can convert the specified value type; otherwise, false. - - - - - Converts a to and from JSON. - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified value type. - - Type of the value. - - true if this instance can convert the specified value type; otherwise, false. - - - - - Provides a base class for converting a to and from JSON. - - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Converts an to and from its name string value. - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Represents a view of a . - - - - - Initializes a new instance of the class. - - The name. - Type of the property. - - - - When overridden in a derived class, returns whether resetting an object changes its value. - - - true if resetting the component changes its value; otherwise, false. - - The component to test for reset capability. - - - - - When overridden in a derived class, gets the current value of the property on a component. - - - The value of a property for a given component. - - The component with the property for which to retrieve the value. - - - - - When overridden in a derived class, resets the value for this property of the component to the default value. - - The component with the property value that is to be reset to the default value. - - - - - When overridden in a derived class, sets the value of the component to a different value. - - The component with the property value that is to be set. - The new value. - - - - - When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted. - - - true if the property should be persisted; otherwise, false. - - The component with the property to be examined for persistence. - - - - - When overridden in a derived class, gets the type of the component this property is bound to. - - - A that represents the type of component this property is bound to. When the or methods are invoked, the object specified might be an instance of this type. - - - - - When overridden in a derived class, gets a value indicating whether this property is read-only. - - - true if the property is read-only; otherwise, false. - - - - - When overridden in a derived class, gets the type of the property. - - - A that represents the type of the property. - - - - - Gets the hash code for the name of the member. - - - - The hash code for the name of the member. - - - - - Represents a view of a . - - - - - Initializes a new instance of the class. - - The value. - - - - Returns the properties for this instance of a component. - - - A that represents the properties for this component instance. - - - - - Returns the properties for this instance of a component using the attribute array as a filter. - - An array of type that is used as a filter. - - A that represents the filtered properties for this component instance. - - - - - Returns a collection of custom attributes for this instance of a component. - - - An containing the attributes for this object. - - - - - Returns the class name of this instance of a component. - - - The class name of the object, or null if the class does not have a name. - - - - - Returns the name of this instance of a component. - - - The name of the object, or null if the object does not have a name. - - - - - Returns a type converter for this instance of a component. - - - A that is the converter for this object, or null if there is no for this object. - - - - - Returns the default event for this instance of a component. - - - An that represents the default event for this object, or null if this object does not have events. - - - - - Returns the default property for this instance of a component. - - - A that represents the default property for this object, or null if this object does not have properties. - - - - - Returns an editor of the specified type for this instance of a component. - - A that represents the editor for this object. - - An of the specified type that is the editor for this object, or null if the editor cannot be found. - - - - - Returns the events for this instance of a component using the specified attribute array as a filter. - - An array of type that is used as a filter. - - An that represents the filtered events for this component instance. - - - - - Returns the events for this instance of a component. - - - An that represents the events for this component instance. - - - - - Returns an object that contains the property described by the specified property descriptor. - - A that represents the property whose owner is to be found. - - An that represents the owner of the specified property. - - - - - Represents a raw JSON string. - - - - - Represents a value in JSON (string, integer, date, etc). - - - - - Represents an abstract JSON token. - - - - - Represents a collection of objects. - - The type of token - - - - Gets the with the specified key. - - - - - - Provides an interface to enable a class to return line and position information. - - - - - Gets a value indicating whether the class can return line information. - - - true if LineNumber and LinePosition can be provided; otherwise, false. - - - - - Gets the current line number. - - The current line number or 0 if no line information is available (for example, HasLineInfo returns false). - - - - Gets the current line position. - - The current line position or 0 if no line information is available (for example, HasLineInfo returns false). - - - - Compares the values of two tokens, including the values of all descendant tokens. - - The first to compare. - The second to compare. - true if the tokens are equal; otherwise false. - - - - Adds the specified content immediately after this token. - - A content object that contains simple content or a collection of content objects to be added after this token. - - - - Adds the specified content immediately before this token. - - A content object that contains simple content or a collection of content objects to be added before this token. - - - - Returns a collection of the ancestor tokens of this token. - - A collection of the ancestor tokens of this token. - - - - Returns a collection of the sibling tokens after this token, in document order. - - A collection of the sibling tokens after this tokens, in document order. - - - - Returns a collection of the sibling tokens before this token, in document order. - - A collection of the sibling tokens before this token, in document order. - - - - Gets the with the specified key converted to the specified type. - - The type to convert the token to. - The token key. - The converted token value. - - - - Returns a collection of the child tokens of this token, in document order. - - An of containing the child tokens of this , in document order. - - - - Returns a collection of the child tokens of this token, in document order, filtered by the specified type. - - The type to filter the child tokens on. - A containing the child tokens of this , in document order. - - - - Returns a collection of the child values of this token, in document order. - - The type to convert the values to. - A containing the child values of this , in document order. - - - - Removes this token from its parent. - - - - - Replaces this token with the specified token. - - The value. - - - - Writes this token to a . - - A into which this method will write. - A collection of which will be used when writing the token. - - - - Returns the indented JSON for this token. - - - The indented JSON for this token. - - - - - Returns the JSON for this token using the given formatting and converters. - - Indicates how the output is formatted. - A collection of which will be used when writing the token. - The JSON for this token using the given formatting and converters. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Creates an for this token. - - An that can be used to read this token and its descendants. - - - - Creates a from an object. - - The object that will be used to create . - A with the value of the specified object - - - - Creates a from an object using the specified . - - The object that will be used to create . - The that will be used when reading the object. - A with the value of the specified object - - - - Creates a from a . - - An positioned at the token to read into this . - - An that contains the token and its descendant tokens - that were read from the reader. The runtime type of the token is determined - by the token type of the first token encountered in the reader. - - - - - Selects the token that matches the object path. - - - The object path from the current to the - to be returned. This must be a string of property names or array indexes separated - by periods, such as Tables[0].DefaultView[0].Price in C# or - Tables(0).DefaultView(0).Price in Visual Basic. - - The that matches the object path or a null reference if no matching token is found. - - - - Selects the token that matches the object path. - - - The object path from the current to the - to be returned. This must be a string of property names or array indexes separated - by periods, such as Tables[0].DefaultView[0].Price in C# or - Tables(0).DefaultView(0).Price in Visual Basic. - - A flag to indicate whether an error should be thrown if no token is found. - The that matches the object path. - - - - Gets a comparer that can compare two tokens for value equality. - - A that can compare two nodes for value equality. - - - - Gets or sets the parent. - - The parent. - - - - Gets the root of this . - - The root of this . - - - - Gets the node type for this . - - The type. - - - - Gets a value indicating whether this token has childen tokens. - - - true if this token has child values; otherwise, false. - - - - - Gets the next sibling token of this node. - - The that contains the next sibling token. - - - - Gets the previous sibling token of this node. - - The that contains the previous sibling token. - - - - Gets the with the specified key. - - The with the specified key. - - - - Get the first child token of this token. - - A containing the first child token of the . - - - - Get the last child token of this token. - - A containing the last child token of the . - - - - Initializes a new instance of the class from another object. - - A object to copy from. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Creates a comment with the given value. - - The value. - A comment with the given value. - - - - Creates a string with the given value. - - The value. - A string with the given value. - - - - Writes this token to a . - - A into which this method will write. - A collection of which will be used when writing the token. - - - - Indicates whether the current object is equal to another object of the same type. - - - true if the current object is equal to the parameter; otherwise, false. - - An object to compare with this object. - - - - Determines whether the specified is equal to the current . - - The to compare with the current . - - true if the specified is equal to the current ; otherwise, false. - - - The parameter is null. - - - - - Serves as a hash function for a particular type. - - - A hash code for the current . - - - - - Gets a value indicating whether this token has childen tokens. - - - true if this token has child values; otherwise, false. - - - - - Gets the node type for this . - - The type. - - - - Gets or sets the underlying token value. - - The underlying token value. - - - - Initializes a new instance of the class from another object. - - A object to copy from. - - - - Initializes a new instance of the class. - - The raw json. - - - - Creates an instance of with the content of the reader's current token. - - The reader. - An instance of with the content of the reader's current token. - - - - Indicating whether a property is required. - - - - - The property is not required. The default state. - - - - - The property must be defined in JSON but can be a null value. - - - - - The property must be defined in JSON and cannot be a null value. - - - - - Used to resolve references when serializing and deserializing JSON by the . - - - - - Resolves a reference to its object. - - The reference to resolve. - The object that - - - - Gets the reference for the sepecified object. - - The object to get a reference for. - The reference to the object. - - - - Determines whether the specified object is referenced. - - The object to test for a reference. - - true if the specified object is referenced; otherwise, false. - - - - - Adds a reference to the specified object. - - The reference. - The object to reference. - - - - Specifies reference handling options for the . - - - - - Do not preserve references when serializing types. - - - - - Preserve references when serializing into a JSON object structure. - - - - - Preserve references when serializing into a JSON array structure. - - - - - Preserve references when serializing. - - - - - Instructs the how to serialize the collection. - - - - - Instructs the how to serialize the object. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with the specified container Id. - - The container Id. - - - - Gets or sets the id. - - The id. - - - - Gets or sets the title. - - The title. - - - - Gets or sets the description. - - The description. - - - - Gets or sets a value that indicates whether to preserve object reference data. - - - true to keep object reference; otherwise, false. The default is false. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with a flag indicating whether the array can contain null items - - A flag indicating whether the array can contain null items. - - - - Initializes a new instance of the class with the specified container Id. - - The container Id. - - - - Gets or sets a value indicating whether null items are allowed in the collection. - - true if null items are allowed in the collection; otherwise, false. - - - - Specifies default value handling options for the . - - - - - Include null values when serializing and deserializing objects. - - - - - Ignore null values when serializing and deserializing objects. - - - - - Instructs the to use the specified when serializing the member or class. - - - - - Initializes a new instance of the class. - - Type of the converter. - - - - Gets the type of the converter. - - The type of the converter. - - - - Instructs the how to serialize the object. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with the specified member serialization. - - The member serialization. - - - - Initializes a new instance of the class with the specified container Id. - - The container Id. - - - - Gets or sets the member serialization. - - The member serialization. - - - - Specifies the settings on a object. - - - - - Initializes a new instance of the class. - - - - - Gets or sets how reference loops (e.g. a class referencing itself) is handled. - - Reference loop handling. - - - - Gets or sets how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. - - Missing member handling. - - - - Gets or sets how objects are created during deserialization. - - The object creation handling. - - - - Gets or sets how null values are handled during serialization and deserialization. - - Null value handling. - - - - Gets or sets how null default are handled during serialization and deserialization. - - The default value handling. - - - - Gets or sets a collection that will be used during serialization. - - The converters. - - - - Gets or sets how object references are preserved by the serializer. - - The preserve references handling. - - - - Gets or sets how type name writing and reading is handled by the serializer. - - The type name handling. - - - - Gets or sets how constructors are used during deserialization. - - The constructor handling. - - - - Gets or sets the contract resolver used by the serializer when - serializing .NET objects to JSON and vice versa. - - The contract resolver. - - - - Gets or sets the used by the serializer when resolving references. - - The reference resolver. - - - - Gets or sets the used by the serializer when resolving type names. - - The binder. - - - - Gets or sets the error handler called during serialization and deserialization. - - The error handler called during serialization and deserialization. - - - - Gets or sets the used by the serializer when invoking serialization callback methods. - - The context. - - - - Represents a reader that provides validation. - - - - - Initializes a new instance of the class that - validates the content returned from the given . - - The to read from while validating. - - - - Reads the next JSON token from the stream as a . - - - A or a null reference if the next JSON token is null. - - - - - Reads the next JSON token from the stream. - - - true if the next token was read successfully; false if there are no more tokens to read. - - - - - Sets an event handler for receiving schema validation errors. - - - - - Gets the text value of the current Json token. - - - - - - Gets the depth of the current token in the JSON document. - - The depth of the current token in the JSON document. - - - - Gets the quotation mark character used to enclose the value of a string. - - - - - - Gets the type of the current Json token. - - - - - - Gets The Common Language Runtime (CLR) type for the current Json token. - - - - - - Gets or sets the schema. - - The schema. - - - - Gets the used to construct this . - - The specified in the constructor. - - - - Compares tokens to determine whether they are equal. - - - - - Determines whether the specified objects are equal. - - The first object of type to compare. - The second object of type to compare. - - true if the specified objects are equal; otherwise, false. - - - - - Returns a hash code for the specified object. - - The for which a hash code is to be returned. - A hash code for the specified object. - The type of is a reference type and is null. - - - - Specifies the member serialization options for the . - - - - - All members are serialized by default. Members can be excluded using the . - - - - - Only members must be marked with the are serialized. - - - - - Specifies how object creation is handled by the . - - - - - Reuse existing objects, create new objects when needed. - - - - - Only reuse existing objects. - - - - - Always create new objects. - - - - - Converts a to and from the ISO 8601 date format (e.g. 2008-04-12T12:53Z). - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The calling serializer. - The object value. - - - - Gets or sets the date time styles used when converting a date to and from JSON. - - The date time styles used when converting a date to and from JSON. - - - - Gets or sets the date time format used when converting a date to and from JSON. - - The date time format used when converting a date to and from JSON. - - - - Gets or sets the culture used when converting a date to and from JSON. - - The culture used when converting a date to and from JSON. - - - - Converts a to and from a JavaScript date constructor (e.g. new Date(52231943)). - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The calling serializer. - The object value. - - - - Specifies whether a DateTime object represents a local time, a Coordinated Universal Time (UTC), or is not specified as either local time or UTC. - - - - - The time represented is local time. - - - - - The time represented is UTC. - - - - - The time represented is not specified as either local time or Coordinated Universal Time (UTC). - - - - - Preserves the DateTimeKind field of a date when a DateTime object is converted to a string and the string is then converted back to a DateTime object. - - - - - Converts an to and from JSON. - - - - - Writes the JSON representation of the object. - - The to write to. - The calling serializer. - The value. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The calling serializer. - The object value. - - - - Checks if the attributeName is a namespace attribute. - - Attribute name to test. - The attribute name prefix if it has one, otherwise an empty string. - True if attribute name is for a namespace attribute, otherwise false. - - - - Determines whether this instance can convert the specified value type. - - Type of the value. - - true if this instance can convert the specified value type; otherwise, false. - - - - - Gets or sets the name of the root element to insert when deserializing to XML if the JSON structure has produces multiple root elements. - - The name of the deserialize root element. - - - - Converts a object to and from JSON. - - - - - Writes the JSON representation of the object. - - The to write to. - The calling serializer. - The value. - - - - Determines whether this instance can convert the specified value type. - - Type of the value. - - true if this instance can convert the specified value type; otherwise, false. - - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The calling serializer. - The object value. - - - - Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. - - - - - Initializes a new instance of the class with the specified . - - The TextReader containing the XML data to read. - - - - Reads the next JSON token from the stream. - - - true if the next token was read successfully; false if there are no more tokens to read. - - - - - Reads the next JSON token from the stream as a . - - - A or a null reference if the next JSON token is null. - - - - - Changes the state to closed. - - - - - Gets a value indicating whether the class can return line information. - - - true if LineNumber and LinePosition can be provided; otherwise, false. - - - - - Gets the current line number. - - - The current line number or 0 if no line information is available (for example, HasLineInfo returns false). - - - - - Gets the current line position. - - - The current line position or 0 if no line information is available (for example, HasLineInfo returns false). - - - - - Instructs the to always serialize the member with the specified name. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with the specified name. - - Name of the property. - - - - Gets or sets the null value handling used when serializing this property. - - The null value handling. - - - - Gets or sets the default value handling used when serializing this property. - - The default value handling. - - - - Gets or sets the reference loop handling used when serializing this property. - - The reference loop handling. - - - - Gets or sets the object creation handling used when deserializing this property. - - The object creation handling. - - - - Gets or sets whether this property's value is serialized as a reference. - - Whether this property's value is serialized as a reference. - - - - Gets or sets the name of the property. - - The name of the property. - - - - Gets or sets a value indicating whether this property is required. - - - A value indicating whether this property is required. - - - - - Instructs the not to serialize the public field or public read/write property value. - - - - - Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. - - - - - Creates an instance of the JsonWriter class using the specified . - - The TextWriter to write to. - - - - Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. - - - - - Closes this stream and the underlying stream. - - - - - Writes the beginning of a Json object. - - - - - Writes the beginning of a Json array. - - - - - Writes the start of a constructor with the given name. - - The name of the constructor. - - - - Writes the specified end token. - - The end token to write. - - - - Writes the property name of a name/value pair on a Json object. - - The name of the property. - - - - Writes indent characters. - - - - - Writes the JSON value delimiter. - - - - - Writes an indent space. - - - - - Writes a null value. - - - - - Writes an undefined value. - - - - - Writes raw JSON. - - The raw JSON to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes out a comment /*...*/ containing the specified text. - - Text to place inside the comment. - - - - Writes out the given white space. - - The string of white space characters. - - - - Gets or sets how many IndentChars to write for each level in the hierarchy when is set to Formatting.Indented. - - - - - Gets or sets which character to use to quote attribute values. - - - - - Gets or sets which character to use for indenting when is set to Formatting.Indented. - - - - - Gets or sets a value indicating whether object names will be surrounded with quotes. - - - - - The exception thrown when an error occurs while reading Json text. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class - with a specified error message. - - The error message that explains the reason for the exception. - - - - Initializes a new instance of the class - with a specified error message and a reference to the inner exception that is the cause of this exception. - - The error message that explains the reason for the exception. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - The exception thrown when an error occurs while reading Json text. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class - with a specified error message. - - The error message that explains the reason for the exception. - - - - Initializes a new instance of the class - with a specified error message and a reference to the inner exception that is the cause of this exception. - - The error message that explains the reason for the exception. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Gets the line number indicating where the error occurred. - - The line number indicating where the error occurred. - - - - Gets the line position indicating where the error occurred. - - The line position indicating where the error occurred. - - - - Represents a collection of . - - - - - Provides methods for converting between common language runtime types and JSON types. - - - - - Represents JavaScript's boolean value true as a string. This field is read-only. - - - - - Represents JavaScript's boolean value false as a string. This field is read-only. - - - - - Represents JavaScript's null as a string. This field is read-only. - - - - - Represents JavaScript's undefined as a string. This field is read-only. - - - - - Represents JavaScript's positive infinity as a string. This field is read-only. - - - - - Represents JavaScript's negative infinity as a string. This field is read-only. - - - - - Represents JavaScript's NaN as a string. This field is read-only. - - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - The string delimiter character. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Serializes the specified object to a JSON string. - - The object to serialize. - A JSON string representation of the object. - - - - Serializes the specified object to a JSON string. - - The object to serialize. - Indicates how the output is formatted. - - A JSON string representation of the object. - - - - - Serializes the specified object to a JSON string using a collection of . - - The object to serialize. - A collection converters used while serializing. - A JSON string representation of the object. - - - - Serializes the specified object to a JSON string using a collection of . - - The object to serialize. - Indicates how the output is formatted. - A collection converters used while serializing. - A JSON string representation of the object. - - - - Serializes the specified object to a JSON string using a collection of . - - The object to serialize. - Indicates how the output is formatted. - The used to serialize the object. - If this is null, default serialization settings will be is used. - - A JSON string representation of the object. - - - - - Deserializes the specified object to a Json object. - - The object to deserialize. - The deserialized object from the Json string. - - - - Deserializes the specified object to a Json object. - - The object to deserialize. - The of object being deserialized. - The deserialized object from the Json string. - - - - Deserializes the specified object to a Json object. - - The type of the object to deserialize. - The object to deserialize. - The deserialized object from the Json string. - - - - Deserializes the specified JSON to the given anonymous type. - - - The anonymous type to deserialize to. This can't be specified - traditionally and must be infered from the anonymous type passed - as a parameter. - - The object to deserialize. - The anonymous type object. - The deserialized anonymous type from the JSON string. - - - - Deserializes the JSON string to the specified type. - - The type of the object to deserialize. - The object to deserialize. - Converters to use while deserializing. - The deserialized object from the JSON string. - - - - Deserializes the JSON string to the specified type. - - The type of the object to deserialize. - The object to deserialize. - - The used to deserialize the object. - If this is null, default serialization settings will be is used. - - The deserialized object from the JSON string. - - - - Deserializes the JSON string to the specified type. - - The object to deserialize. - The type of the object to deserialize. - Converters to use while deserializing. - The deserialized object from the JSON string. - - - - Deserializes the JSON string to the specified type. - - The JSON to deserialize. - The type of the object to deserialize. - - The used to deserialize the object. - If this is null, default serialization settings will be is used. - - The deserialized object from the JSON string. - - - - Populates the object with values from the JSON string. - - The JSON to populate values from. - The target object to populate values onto. - - - - Populates the object with values from the JSON string. - - The JSON to populate values from. - The target object to populate values onto. - - The used to deserialize the object. - If this is null, default serialization settings will be is used. - - - - - Serializes the XML node to a JSON string. - - The node to serialize. - A JSON string of the XmlNode. - - - - Deserializes the XmlNode from a JSON string. - - The JSON string. - The deserialized XmlNode - - - - Deserializes the XmlNode from a JSON string nested in a root elment. - - The JSON string. - The name of the root element to append when deserializing. - The deserialized XmlNode - - - - The exception thrown when an error occurs during Json serialization or deserialization. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class - with a specified error message. - - The error message that explains the reason for the exception. - - - - Initializes a new instance of the class - with a specified error message and a reference to the inner exception that is the cause of this exception. - - The error message that explains the reason for the exception. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Serializes and deserializes objects into and from the JSON format. - The enables you to control how objects are encoded into JSON. - - - - - Initializes a new instance of the class. - - - - - Creates a new instance using the specified . - - The settings to be applied to the . - A new instance using the specified . - - - - Populates the JSON values onto the target object. - - The that contains the JSON structure to reader values from. - The target object to populate values onto. - - - - Populates the JSON values onto the target object. - - The that contains the JSON structure to reader values from. - The target object to populate values onto. - - - - Deserializes the Json structure contained by the specified . - - The that contains the JSON structure to deserialize. - The being deserialized. - - - - Deserializes the Json structure contained by the specified - into an instance of the specified type. - - The containing the object. - The of object being deserialized. - The instance of being deserialized. - - - - Deserializes the Json structure contained by the specified - into an instance of the specified type. - - The containing the object. - The type of the object to deserialize. - The instance of being deserialized. - - - - Deserializes the Json structure contained by the specified - into an instance of the specified type. - - The containing the object. - The of object being deserialized. - The instance of being deserialized. - - - - Serializes the specified and writes the Json structure - to a Stream using the specified . - - The used to write the Json structure. - The to serialize. - - - - Serializes the specified and writes the Json structure - to a Stream using the specified . - - The used to write the Json structure. - The to serialize. - - - - Occurs when the errors during serialization and deserialization. - - - - - Gets or sets the used by the serializer when resolving references. - - - - - Gets or sets the used by the serializer when resolving type names. - - - - - Gets or sets how type name writing and reading is handled by the serializer. - - - - - Gets or sets how object references are preserved by the serializer. - - - - - Get or set how reference loops (e.g. a class referencing itself) is handled. - - - - - Get or set how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. - - - - - Get or set how null values are handled during serialization and deserialization. - - - - - Get or set how null default are handled during serialization and deserialization. - - - - - Gets or sets how objects are created during deserialization. - - The object creation handling. - - - - Gets or sets how constructors are used during deserialization. - - The constructor handling. - - - - Gets a collection that will be used during serialization. - - Collection that will be used during serialization. - - - - Gets or sets the contract resolver used by the serializer when - serializing .NET objects to JSON and vice versa. - - - - - Gets or sets the used by the serializer when invoking serialization callback methods. - - The context. - - - - Contains the LINQ to JSON extension methods. - - - - - Returns a collection of tokens that contains the ancestors of every token in the source collection. - - The type of the objects in source, constrained to . - An of that contains the source collection. - An of that contains the ancestors of every node in the source collection. - - - - Returns a collection of tokens that contains the descendants of every token in the source collection. - - The type of the objects in source, constrained to . - An of that contains the source collection. - An of that contains the descendants of every node in the source collection. - - - - Returns a collection of child properties of every object in the source collection. - - An of that contains the source collection. - An of that contains the properties of every object in the source collection. - - - - Returns a collection of child values of every object in the source collection with the given key. - - An of that contains the source collection. - The token key. - An of that contains the values of every node in the source collection with the given key. - - - - Returns a collection of child values of every object in the source collection. - - An of that contains the source collection. - An of that contains the values of every node in the source collection. - - - - Returns a collection of converted child values of every object in the source collection with the given key. - - The type to convert the values to. - An of that contains the source collection. - The token key. - An that contains the converted values of every node in the source collection with the given key. - - - - Returns a collection of converted child values of every object in the source collection. - - The type to convert the values to. - An of that contains the source collection. - An that contains the converted values of every node in the source collection. - - - - Converts the value. - - The type to convert the value to. - A cast as a of . - A converted value. - - - - Converts the value. - - The source collection type. - The type to convert the value to. - A cast as a of . - A converted value. - - - - Returns a collection of child tokens of every array in the source collection. - - The source collection type. - An of that contains the source collection. - An of that contains the values of every node in the source collection. - - - - Returns a collection of converted child tokens of every array in the source collection. - - An of that contains the source collection. - The type to convert the values to. - The source collection type. - An that contains the converted values of every node in the source collection. - - - - Returns the input typed as . - - An of that contains the source collection. - The input typed as . - - - - Returns the input typed as . - - The source collection type. - An of that contains the source collection. - The input typed as . - - - - Represents a JSON constructor. - - - - - Represents a token that can contain other tokens. - - - - - Raises the event. - - The instance containing the event data. - - - - Raises the event. - - The instance containing the event data. - - - - Returns a collection of the child tokens of this token, in document order. - - - An of containing the child tokens of this , in document order. - - - - - Returns a collection of the child values of this token, in document order. - - The type to convert the values to. - - A containing the child values of this , in document order. - - - - - Returns a collection of the descendant tokens for this token in document order. - - An containing the descendant tokens of the . - - - - Adds the specified content as children of this . - - The content to be added. - - - - Adds the specified content as the first children of this . - - The content to be added. - - - - Creates an that can be used to add tokens to the . - - An that is ready to have content written to it. - - - - Replaces the children nodes of this token with the specified content. - - The content. - - - - Removes the child nodes from this token. - - - - - Occurs when the list changes or an item in the list changes. - - - - - Occurs before an item is added to the collection. - - - - - Gets a value indicating whether this token has childen tokens. - - - true if this token has child values; otherwise, false. - - - - - Get the first child token of this token. - - - A containing the first child token of the . - - - - - Get the last child token of this token. - - - A containing the last child token of the . - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class from another object. - - A object to copy from. - - - - Initializes a new instance of the class with the specified name and content. - - The constructor name. - The contents of the constructor. - - - - Initializes a new instance of the class with the specified name and content. - - The constructor name. - The contents of the constructor. - - - - Initializes a new instance of the class with the specified name. - - The constructor name. - - - - Writes this token to a . - - A into which this method will write. - A collection of which will be used when writing the token. - - - - Loads an from a . - - A that will be read for the content of the . - A that contains the JSON that was read from the specified . - - - - Gets or sets the name of this constructor. - - The constructor name. - - - - Gets the node type for this . - - The type. - - - - Gets the with the specified key. - - The with the specified key. - - - - Represents a collection of objects. - - The type of token - - - - An empty collection of objects. - - - - - Initializes a new instance of the struct. - - The enumerable. - - - - Returns an enumerator that iterates through the collection. - - - A that can be used to iterate through the collection. - - - - - Returns an enumerator that iterates through a collection. - - - An object that can be used to iterate through the collection. - - - - - Determines whether the specified is equal to this instance. - - The to compare with this instance. - - true if the specified is equal to this instance; otherwise, false. - - - - - Returns a hash code for this instance. - - - A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - - - - - Gets the with the specified key. - - - - - - Represents a JSON object. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class from another object. - - A object to copy from. - - - - Initializes a new instance of the class with the specified content. - - The contents of the object. - - - - Initializes a new instance of the class with the specified content. - - The contents of the object. - - - - Gets an of this object's properties. - - An of this object's properties. - - - - Gets a the specified name. - - The property name. - A with the specified name or null. - - - - Gets an of this object's property values. - - An of this object's property values. - - - - Loads an from a . - - A that will be read for the content of the . - A that contains the JSON that was read from the specified . - - - - Load a from a string that contains JSON. - - A that contains JSON. - A populated from the string that contains JSON. - - - - Creates a from an object. - - The object that will be used to create . - A with the values of the specified object - - - - Creates a from an object. - - The object that will be used to create . - The that will be used to read the object. - A with the values of the specified object - - - - Writes this token to a . - - A into which this method will write. - A collection of which will be used when writing the token. - - - - Adds the specified property name. - - Name of the property. - The value. - - - - Removes the property with the specified name. - - Name of the property. - true if item was successfully removed; otherwise, false. - - - - Tries the get value. - - Name of the property. - The value. - true if a value was successfully retrieved; otherwise, false. - - - - Returns an enumerator that iterates through the collection. - - - A that can be used to iterate through the collection. - - - - - Raises the event with the provided arguments. - - Name of the property. - - - - Occurs when a property value changes. - - - - - Gets the node type for this . - - The type. - - - - Gets the with the specified key. - - The with the specified key. - - - - Gets or sets the with the specified property name. - - - - - - Gets the number of elements contained in the . - - - The number of elements contained in the . - - - - Represents a JSON array. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class from another object. - - A object to copy from. - - - - Initializes a new instance of the class with the specified content. - - The contents of the array. - - - - Initializes a new instance of the class with the specified content. - - The contents of the array. - - - - Loads an from a . - - A that will be read for the content of the . - A that contains the JSON that was read from the specified . - - - - Load a from a string that contains JSON. - - A that contains JSON. - A populated from the string that contains JSON. - - - - Creates a from an object. - - The object that will be used to create . - A with the values of the specified object - - - - Creates a from an object. - - The object that will be used to create . - The that will be used to read the object. - A with the values of the specified object - - - - Writes this token to a . - - A into which this method will write. - A collection of which will be used when writing the token. - - - - Determines the index of a specific item in the . - - The object to locate in the . - - The index of if found in the list; otherwise, -1. - - - - - Inserts an item to the at the specified index. - - The zero-based index at which should be inserted. - The object to insert into the . - - is not a valid index in the . - The is read-only. - - - - Removes the item at the specified index. - - The zero-based index of the item to remove. - - is not a valid index in the . - The is read-only. - - - - Adds an item to the . - - The object to add to the . - The is read-only. - - - - Removes all items from the . - - The is read-only. - - - - Determines whether the contains a specific value. - - The object to locate in the . - - true if is found in the ; otherwise, false. - - - - - Removes the first occurrence of a specific object from the . - - The object to remove from the . - - true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . - - The is read-only. - - - - Gets the node type for this . - - The type. - - - - Gets the with the specified key. - - The with the specified key. - - - - Gets or sets the at the specified index. - - - - - - Gets the number of elements contained in the . - - - The number of elements contained in the . - - - - Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. - - - - - Initializes a new instance of the class. - - The token to read from. - - - - Reads the next JSON token from the stream as a . - - - A or a null reference if the next JSON token is null. - - - - - Reads the next JSON token from the stream. - - - true if the next token was read successfully; false if there are no more tokens to read. - - - - - Represents a JSON property. - - - - - Initializes a new instance of the class from another object. - - A object to copy from. - - - - Returns a collection of the child tokens of this token, in document order. - - - An of containing the child tokens of this , in document order. - - - - - Initializes a new instance of the class. - - The property name. - The property content. - - - - Initializes a new instance of the class. - - The property name. - The property content. - - - - Writes this token to a . - - A into which this method will write. - A collection of which will be used when writing the token. - - - - Loads an from a . - - A that will be read for the content of the . - A that contains the JSON that was read from the specified . - - - - Gets the property name. - - The property name. - - - - Gets or sets the property value. - - The property value. - - - - Gets the node type for this . - - The type. - - - - Specifies the type of token. - - - - - No token type has been set. - - - - - A JSON object. - - - - - A JSON array. - - - - - A JSON constructor. - - - - - A JSON object property. - - - - - A comment. - - - - - An integer value. - - - - - A float value. - - - - - A string value. - - - - - A boolean value. - - - - - A null value. - - - - - An undefined value. - - - - - A date value. - - - - - A raw JSON value. - - - - - A collection of bytes value. - - - - - Contains the JSON schema extension methods. - - - - - Determines whether the is valid. - - The source to test. - The schema to test with. - - true if the specified is valid; otherwise, false. - - - - - Validates the specified . - - The source to test. - The schema to test with. - - - - Validates the specified . - - The source to test. - The schema to test with. - The validation event handler. - - - - Returns detailed information about the schema exception. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class - with a specified error message. - - The error message that explains the reason for the exception. - - - - Initializes a new instance of the class - with a specified error message and a reference to the inner exception that is the cause of this exception. - - The error message that explains the reason for the exception. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Gets the line number indicating where the error occurred. - - The line number indicating where the error occurred. - - - - Gets the line position indicating where the error occurred. - - The line position indicating where the error occurred. - - - - Resolves from an id. - - - - - Initializes a new instance of the class. - - - - - Gets a for the specified id. - - The id. - A for the specified id. - - - - Gets or sets the loaded schemas. - - The loaded schemas. - - - - Specifies undefined schema Id handling options for the . - - - - - Do not infer a schema Id. - - - - - Use the .NET type name as the schema Id. - - - - - Use the assembly qualified .NET type name as the schema Id. - - - - - Returns detailed information related to the . - - - - - Gets the associated with the validation event. - - The JsonSchemaException associated with the validation event. - - - - Gets the text description corresponding to the validation event. - - The text description. - - - - Represents the callback method that will handle JSON schema validation events and the . - - - - - Resolves member mappings for a type, camel casing property names. - - - - - Used by to resolves a for a given . - - - - - Used by to resolves a for a given . - - - - - Resolves the contract for a given type. - - The type to resolve a contract for. - The contract for a given type. - - - - Initializes a new instance of the class. - - - - - Resolves the contract for a given type. - - The type to resolve a contract for. - The contract for a given type. - - - - Gets the serializable members for the type. - - The type to get serializable members for. - The serializable members for the type. - - - - Creates a for the given type. - - Type of the object. - A for the given type. - - - - Resolves the default for the contract. - - Type of the object. - - - - - Creates a for the given type. - - Type of the object. - A for the given type. - - - - Creates a for the given type. - - Type of the object. - A for the given type. - - - - Creates a for the given type. - - Type of the object. - A for the given type. - - - - Creates a for the given type. - - Type of the object. - A for the given type. - - - - Creates properties for the given . - - The contract to create properties for. - Properties for the given . - - - - Creates the used by the serializer to get and set values from a member. - - The member. - The used by the serializer to get and set values from a member. - - - - Creates a for the given . - - The member's declaring types . - The member to create a for. - A created for the given . - - - - Resolves the name of the property. - - Name of the property. - Name of the property. - - - - Gets or sets the default members search flags. - - The default members search flags. - - - - Resolves the name of the property. - - Name of the property. - The property name camel cased. - - - - The default serialization binder used when resolving and loading classes from type names. - - - - - When overridden in a derived class, controls the binding of a serialized object to a type. - - Specifies the name of the serialized object. - Specifies the name of the serialized object. - - The type of the object the formatter creates a new instance of. - - - - - Get and set values for a using dynamic methods. - - - - - Provides methods to get and set values. - - - - - Sets the value. - - The target to set the value on. - The value to set on the target. - - - - Gets the value. - - The target to get the value from. - The value. - - - - Initializes a new instance of the class. - - The member info. - - - - Sets the value. - - The target to set the value on. - The value to set on the target. - - - - Gets the value. - - The target to get the value from. - The value. - - - - Provides information surrounding an error. - - - - - Gets or sets the error. - - The error. - - - - Gets the original object that caused the error. - - The original object that caused the error. - - - - Gets the member that caused the error. - - The member that caused the error. - - - - Gets or sets a value indicating whether this is handled. - - true if handled; otherwise, false. - - - - Provides data for the Error event. - - - - - Initializes a new instance of the class. - - The current object. - The error context. - - - - Gets the current object the error event is being raised against. - - The current object the error event is being raised against. - - - - Gets the error context. - - The error context. - - - - Contract details for a used by the . - - - - - Contract details for a used by the . - - - - - Gets the underlying type for the contract. - - The underlying type for the contract. - - - - Gets or sets the type created during deserialization. - - The type created during deserialization. - - - - Gets or sets whether this type contract is serialized as a reference. - - Whether this type contract is serialized as a reference. - - - - Gets or sets the default for this contract. - - The converter. - - - - Gets or sets the method called immediately after deserialization of the object. - - The method called immediately after deserialization of the object. - - - - Gets or sets the method called during deserialization of the object. - - The method called during deserialization of the object. - - - - Gets or sets the method called after serialization of the object graph. - - The method called after serialization of the object graph. - - - - Gets or sets the method called before serialization of the object. - - The method called before serialization of the object. - - - - Gets or sets the default creator. - - The default creator. - - - - Gets or sets a value indicating whether [default creator non public]. - - true if the default object creator is non-public; otherwise, false. - - - - Gets or sets the method called when an error is thrown during the serialization of the object. - - The method called when an error is thrown during the serialization of the object. - - - - Initializes a new instance of the class. - - The underlying type for the contract. - - - - Contract details for a used by the . - - - - - Initializes a new instance of the class. - - The underlying type for the contract. - - - - Contract details for a used by the . - - - - - Initializes a new instance of the class. - - The underlying type for the contract. - - - - Contract details for a used by the . - - - - - Initializes a new instance of the class. - - The underlying type for the contract. - - - - Maps a JSON property to a .NET member. - - - - - Gets the name of the property. - - The name of the property. - - - - Gets the that will get and set the during serialization. - - The that will get and set the during serialization. - - - - Gets or sets the type of the property. - - The type of the property. - - - - Gets or sets the for the property. - If set this converter takes presidence over the contract converter for the property type. - - The converter. - - - - Gets a value indicating whether this is ignored. - - true if ignored; otherwise, false. - - - - Gets a value indicating whether this is readable. - - true if readable; otherwise, false. - - - - Gets a value indicating whether this is writable. - - true if writable; otherwise, false. - - - - Gets the member converter. - - The member converter. - - - - Gets the default value. - - The default value. - - - - Gets a value indicating whether this is required. - - A value indicating whether this is required. - - - - Gets a value indicating whether this property preserves object references. - - - true if this instance is reference; otherwise, false. - - - - - Gets the property null value handling. - - The null value handling. - - - - Gets the property default value handling. - - The default value handling. - - - - Gets the property reference loop handling. - - The reference loop handling. - - - - Gets the property object creation handling. - - The object creation handling. - - - - A collection of objects. - - - - - Initializes a new instance of the class. - - The contract. - - - - When implemented in a derived class, extracts the key from the specified element. - - The element from which to extract the key. - The key for the specified element. - - - - Adds a object. - - The property to add to the collection. - - - - Gets the closest matching object. - First attempts to get an exact case match of propertyName and then - a case insensitive match. - - Name of the property. - A matching property if found. - - - - Gets a property by property name. - - The name of the property to get. - Type property name string comparison. - A matching property if found. - - - - Specifies missing member handling options for the . - - - - - Ignore a missing member and do not attempt to deserialize it. - - - - - Throw a when a missing member is encountered during deserialization. - - - - - Specifies null value handling options for the . - - - - - Include null values when serializing and deserializing objects. - - - - - Ignore null values when serializing and deserializing objects. - - - - - Specifies reference loop handling options for the . - - - - - Throw a when a loop is encountered. - - - - - Ignore loop references and do not serialize. - - - - - Serialize loop references. - - - - - An in-memory representation of a JSON Schema. - - - - - Initializes a new instance of the class. - - - - - Reads a from the specified . - - The containing the JSON Schema to read. - The object representing the JSON Schema. - - - - Reads a from the specified . - - The containing the JSON Schema to read. - The to use when resolving schema references. - The object representing the JSON Schema. - - - - Load a from a string that contains schema JSON. - - A that contains JSON. - A populated from the string that contains JSON. - - - - Parses the specified json. - - The json. - The resolver. - A populated from the string that contains JSON. - - - - Writes this schema to a . - - A into which this method will write. - - - - Writes this schema to a using the specified . - - A into which this method will write. - The resolver used. - - - - Returns a that represents the current . - - - A that represents the current . - - - - - Gets or sets the id. - - - - - Gets or sets the title. - - - - - Gets or sets whether the object is optional. - - - - - Gets or sets whether the object is read only. - - - - - Gets or sets whether the object is visible to users. - - - - - Gets or sets whether the object is transient. - - - - - Gets or sets the description of the object. - - - - - Gets or sets the types of values allowed by the object. - - The type. - - - - Gets or sets the pattern. - - The pattern. - - - - Gets or sets the minimum length. - - The minimum length. - - - - Gets or sets the maximum length. - - The maximum length. - - - - Gets or sets the maximum decimals. - - The maximum decimals. - - - - Gets or sets the minimum. - - The minimum. - - - - Gets or sets the maximum. - - The maximum. - - - - Gets or sets the minimum number of items. - - The minimum number of items. - - - - Gets or sets the maximum number of items. - - The maximum number of items. - - - - Gets or sets the of items. - - The of items. - - - - Gets or sets the of properties. - - The of properties. - - - - Gets or sets the of additional properties. - - The of additional properties. - - - - Gets or sets a value indicating whether additional properties are allowed. - - - true if additional properties are allowed; otherwise, false. - - - - - Gets or sets the required property if this property is present. - - The required property if this property is present. - - - - Gets or sets the identity. - - The identity. - - - - Gets or sets the a collection of valid enum values allowed. - - A collection of valid enum values allowed. - - - - Gets or sets a collection of options. - - A collection of options. - - - - Gets or sets disallowed types. - - The disallow types. - - - - Gets or sets the default value. - - The default value. - - - - Gets or sets the extend . - - The extended . - - - - Gets or sets the format. - - The format. - - - - Generates a from a specified . - - - - - Generate a from the specified type. - - The type to generate a from. - A generated from the specified type. - - - - Generate a from the specified type. - - The type to generate a from. - The used to resolve schema references. - A generated from the specified type. - - - - Generate a from the specified type. - - The type to generate a from. - Specify whether the generated root will be nullable. - A generated from the specified type. - - - - Generate a from the specified type. - - The type to generate a from. - The used to resolve schema references. - Specify whether the generated root will be nullable. - A generated from the specified type. - - - - Gets or sets how undefined schemas are handled by the serializer. - - - - - Gets or sets the contract resolver. - - The contract resolver. - - - - The value types allowed by the . - - - - - No type specified. - - - - - String type. - - - - - Float type. - - - - - Integer type. - - - - - Boolean type. - - - - - Object type. - - - - - Array type. - - - - - Null type. - - - - - Any type. - - - - - Contract details for a used by the . - - - - - Initializes a new instance of the class. - - The underlying type for the contract. - - - - Gets or sets the object member serialization. - - The member object serialization. - - - - Gets the object's properties. - - The object's properties. - - - - Gets or sets the parametrized constructor used to create the object. - - The parametrized constructor. - - - - When applied to a method, specifies that the method is called when an error occurs serializing an object. - - - - - Get and set values for a using reflection. - - - - - Initializes a new instance of the class. - - The member info. - - - - Sets the value. - - The target to set the value on. - The value to set on the target. - - - - Gets the value. - - The target to get the value from. - The value. - - - - Specifies type name handling options for the . - - - - - Do not include the .NET type name when serializing types. - - - - - Include the .NET type name when serializing into a JSON object structure. - - - - - Include the .NET type name when serializing into a JSON array structure. - - - - - Always include the .NET type name when serializing. - - - - - Converts the value to the specified type. - - The type to convert the value to. - The value to convert. - The converted type. - - - - Converts the value to the specified type. - - The type to convert the value to. - The value to convert. - The culture to use when converting. - The converted type. - - - - Converts the value to the specified type. - - The value to convert. - The culture to use when converting. - The type to convert the value to. - The converted type. - - - - Converts the value to the specified type. - - The type to convert the value to. - The value to convert. - The converted value if the conversion was successful or the default value of T if it failed. - - true if initialValue was converted successfully; otherwise, false. - - - - - Converts the value to the specified type. - - The type to convert the value to. - The value to convert. - The culture to use when converting. - The converted value if the conversion was successful or the default value of T if it failed. - - true if initialValue was converted successfully; otherwise, false. - - - - - Converts the value to the specified type. - - The value to convert. - The culture to use when converting. - The type to convert the value to. - The converted value if the conversion was successful or the default value of T if it failed. - - true if initialValue was converted successfully; otherwise, false. - - - - - Converts the value to the specified type. If the value is unable to be converted, the - value is checked whether it assignable to the specified type. - - The type to convert or cast the value to. - The value to convert. - The converted type. If conversion was unsuccessful, the initial value is returned if assignable to the target type - - - - Converts the value to the specified type. If the value is unable to be converted, the - value is checked whether it assignable to the specified type. - - The type to convert or cast the value to. - The value to convert. - The culture to use when converting. - The converted type. If conversion was unsuccessful, the initial value is returned if assignable to the target type - - - - Converts the value to the specified type. If the value is unable to be converted, the - value is checked whether it assignable to the specified type. - - The value to convert. - The culture to use when converting. - The type to convert or cast the value to. - - The converted type. If conversion was unsuccessful, the initial value - is returned if assignable to the target type. - - - - - Converts the value to the specified type. If the value is unable to be converted, the - value is checked whether it assignable to the specified type. - - The type to convert the value to. - The value to convert. - The converted value if the conversion was successful or the default value of T if it failed. - - true if initialValue was converted successfully or is assignable; otherwise, false. - - - - - Converts the value to the specified type. If the value is unable to be converted, the - value is checked whether it assignable to the specified type. - - The type to convert the value to. - The value to convert. - The culture to use when converting. - The converted value if the conversion was successful or the default value of T if it failed. - - true if initialValue was converted successfully or is assignable; otherwise, false. - - - - - Converts the value to the specified type. If the value is unable to be converted, the - value is checked whether it assignable to the specified type. - - The value to convert. - The culture to use when converting. - The type to convert the value to. - The converted value if the conversion was successful or the default value of T if it failed. - - true if initialValue was converted successfully or is assignable; otherwise, false. - - - - - Parses the specified enum member name, returning it's value. - - Name of the enum member. - - - - - Parses the specified enum member name, returning it's value. - - Name of the enum member. - If set to true ignore case. - - - - - Gets a dictionary of the names and values of an Enum type. - - - - - - Gets a dictionary of the names and values of an Enum type. - - - - - - Gets a dictionary of the names and values of an Enum type. - - The enum type to get names and values for. - - - - - Gets the maximum valid value of an Enum type. Flags enums are ORed. - - The type of the returned value. Must be assignable from the enum's underlying value type. - The enum type to get the maximum value for. - - - - - Specifies the type of Json token. - - - - - This is returned by the if a method has not been called. - - - - - An object start token. - - - - - An array start token. - - - - - A constructor start token. - - - - - An object property name. - - - - - A comment. - - - - - Raw JSON. - - - - - An interger. - - - - - A float. - - - - - A string. - - - - - A boolean. - - - - - A null token. - - - - - An undefined token. - - - - - An object end token. - - - - - An array end token. - - - - - A constructor end token. - - - - - A Date. - - - - - Byte data. - - - - - Specifies the state of the . - - - - - An exception has been thrown, which has left the in an invalid state. - You may call the method to put the in the Closed state. - Any other method calls results in an being thrown. - - - - - The method has been called. - - - - - An object is being written. - - - - - A array is being written. - - - - - A constructor is being written. - - - - - A property is being written. - - - - - A write method has not been called. - - - - - Specifies formatting options for the . - - - - - No special formatting is applied. This is the default. - - - - - Causes child objects to be indented according to the and settings. - - - - - Builds a string. Unlike StringBuilder this class lets you reuse it's internal buffer. - - - - - Determines whether the collection is null or empty. - - The collection. - - true if the collection is null or empty; otherwise, false. - - - - - Determines whether the collection is null or empty. - - The collection. - - true if the collection is null or empty; otherwise, false. - - - - - Determines whether the collection is null, empty or its contents are uninitialized values. - - The list. - - true if the collection is null or empty or its contents are uninitialized values; otherwise, false. - - - - - Makes a slice of the specified list in between the start and end indexes. - - The list. - The start index. - The end index. - A slice of the list. - - - - Makes a slice of the specified list in between the start and end indexes, - getting every so many items based upon the step. - - The list. - The start index. - The end index. - The step. - A slice of the list. - - - - Group the collection using a function which returns the key. - - The source collection to group. - The key selector. - A Dictionary with each key relating to a list of objects in a list grouped under it. - - - - Adds the elements of the specified collection to the specified generic IList. - - The list to add to. - The collection of elements to add. - - - - Gets the type of the typed collection's items. - - The type. - The type of the typed collection's items. - - - - Tests whether the list's items are their unitialized value. - - The list. - Whether the list's items are their unitialized value - - - - Gets the member's underlying type. - - The member. - The underlying type of the member. - - - - Determines whether the member is an indexed property. - - The member. - - true if the member is an indexed property; otherwise, false. - - - - - Determines whether the property is an indexed property. - - The property. - - true if the property is an indexed property; otherwise, false. - - - - - Gets the member's value on the object. - - The member. - The target object. - The member's value on the object. - - - - Sets the member's value on the target object. - - The member. - The target. - The value. - - - - Determines whether the specified MemberInfo can be read. - - The MemberInfo to determine whether can be read. - - true if the specified MemberInfo can be read; otherwise, false. - - - - - Determines whether the specified MemberInfo can be set. - - The MemberInfo to determine whether can be set. - - true if the specified MemberInfo can be set; otherwise, false. - - - - - Determines whether the string contains white space. - - The string to test for white space. - - true if the string contains white space; otherwise, false. - - - - - Determines whether the string is all white space. Empty string will return false. - - The string to test whether it is all white space. - - true if the string is all white space; otherwise, false. - - - - - Ensures the target string ends with the specified string. - - The target. - The value. - The target string with the value string at the end. - - - - Perform an action if the string is not null or empty. - - The value. - The action to perform. - - - - Indents the specified string. - - The string to indent. - The number of characters to indent by. - - - - - Indents the specified string. - - The string to indent. - The number of characters to indent by. - The indent character. - - - - - Numbers the lines. - - The string to number. - - - - - Nulls an empty string. - - The string. - Null if the string was null, otherwise the string unchanged. - - - + + + + Newtonsoft.Json.Net20 + + + + + Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. + + + + + Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. + + + + + Initializes a new instance of the class with the specified . + + + + + Reads the next JSON token from the stream. + + true if the next token was read successfully; false if there are no more tokens to read. + + + + Reads the next JSON token from the stream as a . + + A or a null reference if the next JSON token is null. + + + + Skips the children of the current token. + + + + + Sets the current token. + + The new token. + + + + Sets the current token and value. + + The new token. + The value. + + + + Sets the state based on current token type. + + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Releases unmanaged and - optionally - managed resources + + true to release both managed and unmanaged resources; false to release only unmanaged resources. + + + + Changes the to Closed. + + + + + Gets the current reader state. + + The current reader state. + + + + Gets the quotation mark character used to enclose the value of a string. + + + + + Gets the type of the current Json token. + + + + + Gets the text value of the current Json token. + + + + + Gets The Common Language Runtime (CLR) type for the current Json token. + + + + + Gets the depth of the current token in the JSON document. + + The depth of the current token in the JSON document. + + + + Specifies the state of the reader. + + + + + The Read method has not been called. + + + + + The end of the file has been reached successfully. + + + + + Reader is at a property. + + + + + Reader is at the start of an object. + + + + + Reader is in an object. + + + + + Reader is at the start of an array. + + + + + Reader is in an array. + + + + + The Close method has been called. + + + + + Reader has just read a value. + + + + + Reader is at the start of a constructor. + + + + + Reader in a constructor. + + + + + An error occurred that prevents the read operation from continuing. + + + + + The end of the file has been reached successfully. + + + + + Initializes a new instance of the class. + + The stream. + + + + Initializes a new instance of the class. + + The stream. + if set to true the root object will be read as a JSON array. + The used when reading values from BSON. + + + + Reads the next JSON token from the stream as a . + + + A or a null reference if the next JSON token is null. + + + + + Reads the next JSON token from the stream. + + + true if the next token was read successfully; false if there are no more tokens to read. + + + + + Gets or sets a value indicating whether the root object will be read as a JSON array. + + + true if the root object will be read as a JSON array; otherwise, false. + + + + + Gets or sets the used when reading values from BSON. + + The used when reading values from BSON. + + + + Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. + + + + + Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. + + + + + Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. + + + + + Creates an instance of the JsonWriter class. + + + + + Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + + + + + Closes this stream and the underlying stream. + + + + + Writes the beginning of a Json object. + + + + + Writes the end of a Json object. + + + + + Writes the beginning of a Json array. + + + + + Writes the end of an array. + + + + + Writes the start of a constructor with the given name. + + The name of the constructor. + + + + Writes the end constructor. + + + + + Writes the property name of a name/value pair on a Json object. + + The name of the property. + + + + Writes the end of the current Json object or array. + + + + + Writes the current token. + + The to read the token from. + + + + Writes the specified end token. + + The end token to write. + + + + Writes indent characters. + + + + + Writes the JSON value delimiter. + + + + + Writes an indent space. + + + + + Writes a null value. + + + + + Writes an undefined value. + + + + + Writes raw JSON without changing the writer's state. + + The raw JSON to write. + + + + Writes raw JSON where a value is expected and updates the writer's state. + + The raw JSON to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + An error will raised if the value cannot be written as a single JSON token. + + The value to write. + + + + Writes out a comment /*...*/ containing the specified text. + + Text to place inside the comment. + + + + Writes out the given white space. + + The string of white space characters. + + + + Gets the top. + + The top. + + + + Gets the state of the writer. + + + + + Indicates how the output is formatted. + + + + + Initializes a new instance of the class writing to the given . + + The container being written to. + + + + Initializes a new instance of the class. + + + + + Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + + + + + Closes this stream and the underlying stream. + + + + + Writes the beginning of a Json object. + + + + + Writes the beginning of a Json array. + + + + + Writes the start of a constructor with the given name. + + The name of the constructor. + + + + Writes the end. + + The token. + + + + Writes the property name of a name/value pair on a Json object. + + The name of the property. + + + + Writes a null value. + + + + + Writes an undefined value. + + + + + Writes raw JSON. + + The raw JSON to write. + + + + Writes out a comment /*...*/ containing the specified text. + + Text to place inside the comment. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Gets the token being writen. + + The token being writen. + + + + Initializes a new instance of the class. + + The stream. + + + + Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + + + + + Writes the end. + + The token. + + + + Writes out a comment /*...*/ containing the specified text. + + Text to place inside the comment. + + + + Writes the start of a constructor with the given name. + + The name of the constructor. + + + + Writes raw JSON. + + The raw JSON to write. + + + + Writes raw JSON where a value is expected and updates the writer's state. + + The raw JSON to write. + + + + Specifies how constructors are used when initializing objects during deserialization by the . + + + + + First attempt to use the public default constructor then fall back to single paramatized constructor. + + + + + Allow Json.NET to use a non-public default constructor. + + + + + Converts a binary value to and from a base 64 string value. + + + + + Converts an object to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Create a custom object + + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Creates an object which will then be populated by the serializer. + + Type of the object. + + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts a to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified value type. + + Type of the value. + + true if this instance can convert the specified value type; otherwise, false. + + + + + Converts a to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified value type. + + Type of the value. + + true if this instance can convert the specified value type; otherwise, false. + + + + + Provides a base class for converting a to and from JSON. + + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts an to and from its name string value. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Represents a view of a . + + + + + Initializes a new instance of the class. + + The name. + Type of the property. + + + + When overridden in a derived class, returns whether resetting an object changes its value. + + + true if resetting the component changes its value; otherwise, false. + + The component to test for reset capability. + + + + + When overridden in a derived class, gets the current value of the property on a component. + + + The value of a property for a given component. + + The component with the property for which to retrieve the value. + + + + + When overridden in a derived class, resets the value for this property of the component to the default value. + + The component with the property value that is to be reset to the default value. + + + + + When overridden in a derived class, sets the value of the component to a different value. + + The component with the property value that is to be set. + The new value. + + + + + When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted. + + + true if the property should be persisted; otherwise, false. + + The component with the property to be examined for persistence. + + + + + When overridden in a derived class, gets the type of the component this property is bound to. + + + A that represents the type of component this property is bound to. When the or methods are invoked, the object specified might be an instance of this type. + + + + + When overridden in a derived class, gets a value indicating whether this property is read-only. + + + true if the property is read-only; otherwise, false. + + + + + When overridden in a derived class, gets the type of the property. + + + A that represents the type of the property. + + + + + Gets the hash code for the name of the member. + + + + The hash code for the name of the member. + + + + + Represents a view of a . + + + + + Initializes a new instance of the class. + + The value. + + + + Returns the properties for this instance of a component. + + + A that represents the properties for this component instance. + + + + + Returns the properties for this instance of a component using the attribute array as a filter. + + An array of type that is used as a filter. + + A that represents the filtered properties for this component instance. + + + + + Returns a collection of custom attributes for this instance of a component. + + + An containing the attributes for this object. + + + + + Returns the class name of this instance of a component. + + + The class name of the object, or null if the class does not have a name. + + + + + Returns the name of this instance of a component. + + + The name of the object, or null if the object does not have a name. + + + + + Returns a type converter for this instance of a component. + + + A that is the converter for this object, or null if there is no for this object. + + + + + Returns the default event for this instance of a component. + + + An that represents the default event for this object, or null if this object does not have events. + + + + + Returns the default property for this instance of a component. + + + A that represents the default property for this object, or null if this object does not have properties. + + + + + Returns an editor of the specified type for this instance of a component. + + A that represents the editor for this object. + + An of the specified type that is the editor for this object, or null if the editor cannot be found. + + + + + Returns the events for this instance of a component using the specified attribute array as a filter. + + An array of type that is used as a filter. + + An that represents the filtered events for this component instance. + + + + + Returns the events for this instance of a component. + + + An that represents the events for this component instance. + + + + + Returns an object that contains the property described by the specified property descriptor. + + A that represents the property whose owner is to be found. + + An that represents the owner of the specified property. + + + + + Represents a raw JSON string. + + + + + Represents a value in JSON (string, integer, date, etc). + + + + + Represents an abstract JSON token. + + + + + Represents a collection of objects. + + The type of token + + + + Gets the with the specified key. + + + + + + Provides an interface to enable a class to return line and position information. + + + + + Gets a value indicating whether the class can return line information. + + + true if LineNumber and LinePosition can be provided; otherwise, false. + + + + + Gets the current line number. + + The current line number or 0 if no line information is available (for example, HasLineInfo returns false). + + + + Gets the current line position. + + The current line position or 0 if no line information is available (for example, HasLineInfo returns false). + + + + Compares the values of two tokens, including the values of all descendant tokens. + + The first to compare. + The second to compare. + true if the tokens are equal; otherwise false. + + + + Adds the specified content immediately after this token. + + A content object that contains simple content or a collection of content objects to be added after this token. + + + + Adds the specified content immediately before this token. + + A content object that contains simple content or a collection of content objects to be added before this token. + + + + Returns a collection of the ancestor tokens of this token. + + A collection of the ancestor tokens of this token. + + + + Returns a collection of the sibling tokens after this token, in document order. + + A collection of the sibling tokens after this tokens, in document order. + + + + Returns a collection of the sibling tokens before this token, in document order. + + A collection of the sibling tokens before this token, in document order. + + + + Gets the with the specified key converted to the specified type. + + The type to convert the token to. + The token key. + The converted token value. + + + + Returns a collection of the child tokens of this token, in document order. + + An of containing the child tokens of this , in document order. + + + + Returns a collection of the child tokens of this token, in document order, filtered by the specified type. + + The type to filter the child tokens on. + A containing the child tokens of this , in document order. + + + + Returns a collection of the child values of this token, in document order. + + The type to convert the values to. + A containing the child values of this , in document order. + + + + Removes this token from its parent. + + + + + Replaces this token with the specified token. + + The value. + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Returns the indented JSON for this token. + + + The indented JSON for this token. + + + + + Returns the JSON for this token using the given formatting and converters. + + Indicates how the output is formatted. + A collection of which will be used when writing the token. + The JSON for this token using the given formatting and converters. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Creates an for this token. + + An that can be used to read this token and its descendants. + + + + Creates a from an object. + + The object that will be used to create . + A with the value of the specified object + + + + Creates a from an object using the specified . + + The object that will be used to create . + The that will be used when reading the object. + A with the value of the specified object + + + + Creates a from a . + + An positioned at the token to read into this . + + An that contains the token and its descendant tokens + that were read from the reader. The runtime type of the token is determined + by the token type of the first token encountered in the reader. + + + + + Selects the token that matches the object path. + + + The object path from the current to the + to be returned. This must be a string of property names or array indexes separated + by periods, such as Tables[0].DefaultView[0].Price in C# or + Tables(0).DefaultView(0).Price in Visual Basic. + + The that matches the object path or a null reference if no matching token is found. + + + + Selects the token that matches the object path. + + + The object path from the current to the + to be returned. This must be a string of property names or array indexes separated + by periods, such as Tables[0].DefaultView[0].Price in C# or + Tables(0).DefaultView(0).Price in Visual Basic. + + A flag to indicate whether an error should be thrown if no token is found. + The that matches the object path. + + + + Gets a comparer that can compare two tokens for value equality. + + A that can compare two nodes for value equality. + + + + Gets or sets the parent. + + The parent. + + + + Gets the root of this . + + The root of this . + + + + Gets the node type for this . + + The type. + + + + Gets a value indicating whether this token has childen tokens. + + + true if this token has child values; otherwise, false. + + + + + Gets the next sibling token of this node. + + The that contains the next sibling token. + + + + Gets the previous sibling token of this node. + + The that contains the previous sibling token. + + + + Gets the with the specified key. + + The with the specified key. + + + + Get the first child token of this token. + + A containing the first child token of the . + + + + Get the last child token of this token. + + A containing the last child token of the . + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Creates a comment with the given value. + + The value. + A comment with the given value. + + + + Creates a string with the given value. + + The value. + A string with the given value. + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Indicates whether the current object is equal to another object of the same type. + + + true if the current object is equal to the parameter; otherwise, false. + + An object to compare with this object. + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + The parameter is null. + + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + Gets a value indicating whether this token has childen tokens. + + + true if this token has child values; otherwise, false. + + + + + Gets the node type for this . + + The type. + + + + Gets or sets the underlying token value. + + The underlying token value. + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class. + + The raw json. + + + + Creates an instance of with the content of the reader's current token. + + The reader. + An instance of with the content of the reader's current token. + + + + Indicating whether a property is required. + + + + + The property is not required. The default state. + + + + + The property must be defined in JSON but can be a null value. + + + + + The property must be defined in JSON and cannot be a null value. + + + + + Used to resolve references when serializing and deserializing JSON by the . + + + + + Resolves a reference to its object. + + The reference to resolve. + The object that + + + + Gets the reference for the sepecified object. + + The object to get a reference for. + The reference to the object. + + + + Determines whether the specified object is referenced. + + The object to test for a reference. + + true if the specified object is referenced; otherwise, false. + + + + + Adds a reference to the specified object. + + The reference. + The object to reference. + + + + Specifies reference handling options for the . + + + + + Do not preserve references when serializing types. + + + + + Preserve references when serializing into a JSON object structure. + + + + + Preserve references when serializing into a JSON array structure. + + + + + Preserve references when serializing. + + + + + Instructs the how to serialize the collection. + + + + + Instructs the how to serialize the object. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the specified container Id. + + The container Id. + + + + Gets or sets the id. + + The id. + + + + Gets or sets the title. + + The title. + + + + Gets or sets the description. + + The description. + + + + Gets or sets a value that indicates whether to preserve object reference data. + + + true to keep object reference; otherwise, false. The default is false. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with a flag indicating whether the array can contain null items + + A flag indicating whether the array can contain null items. + + + + Initializes a new instance of the class with the specified container Id. + + The container Id. + + + + Gets or sets a value indicating whether null items are allowed in the collection. + + true if null items are allowed in the collection; otherwise, false. + + + + Specifies default value handling options for the . + + + + + Include null values when serializing and deserializing objects. + + + + + Ignore null values when serializing and deserializing objects. + + + + + Instructs the to use the specified when serializing the member or class. + + + + + Initializes a new instance of the class. + + Type of the converter. + + + + Gets the type of the converter. + + The type of the converter. + + + + Instructs the how to serialize the object. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the specified member serialization. + + The member serialization. + + + + Initializes a new instance of the class with the specified container Id. + + The container Id. + + + + Gets or sets the member serialization. + + The member serialization. + + + + Specifies the settings on a object. + + + + + Initializes a new instance of the class. + + + + + Gets or sets how reference loops (e.g. a class referencing itself) is handled. + + Reference loop handling. + + + + Gets or sets how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. + + Missing member handling. + + + + Gets or sets how objects are created during deserialization. + + The object creation handling. + + + + Gets or sets how null values are handled during serialization and deserialization. + + Null value handling. + + + + Gets or sets how null default are handled during serialization and deserialization. + + The default value handling. + + + + Gets or sets a collection that will be used during serialization. + + The converters. + + + + Gets or sets how object references are preserved by the serializer. + + The preserve references handling. + + + + Gets or sets how type name writing and reading is handled by the serializer. + + The type name handling. + + + + Gets or sets how constructors are used during deserialization. + + The constructor handling. + + + + Gets or sets the contract resolver used by the serializer when + serializing .NET objects to JSON and vice versa. + + The contract resolver. + + + + Gets or sets the used by the serializer when resolving references. + + The reference resolver. + + + + Gets or sets the used by the serializer when resolving type names. + + The binder. + + + + Gets or sets the error handler called during serialization and deserialization. + + The error handler called during serialization and deserialization. + + + + Gets or sets the used by the serializer when invoking serialization callback methods. + + The context. + + + + Represents a reader that provides validation. + + + + + Initializes a new instance of the class that + validates the content returned from the given . + + The to read from while validating. + + + + Reads the next JSON token from the stream as a . + + + A or a null reference if the next JSON token is null. + + + + + Reads the next JSON token from the stream. + + + true if the next token was read successfully; false if there are no more tokens to read. + + + + + Sets an event handler for receiving schema validation errors. + + + + + Gets the text value of the current Json token. + + + + + + Gets the depth of the current token in the JSON document. + + The depth of the current token in the JSON document. + + + + Gets the quotation mark character used to enclose the value of a string. + + + + + + Gets the type of the current Json token. + + + + + + Gets The Common Language Runtime (CLR) type for the current Json token. + + + + + + Gets or sets the schema. + + The schema. + + + + Gets the used to construct this . + + The specified in the constructor. + + + + Compares tokens to determine whether they are equal. + + + + + Determines whether the specified objects are equal. + + The first object of type to compare. + The second object of type to compare. + + true if the specified objects are equal; otherwise, false. + + + + + Returns a hash code for the specified object. + + The for which a hash code is to be returned. + A hash code for the specified object. + The type of is a reference type and is null. + + + + Specifies the member serialization options for the . + + + + + All members are serialized by default. Members can be excluded using the . + + + + + Only members must be marked with the are serialized. + + + + + Specifies how object creation is handled by the . + + + + + Reuse existing objects, create new objects when needed. + + + + + Only reuse existing objects. + + + + + Always create new objects. + + + + + Converts a to and from the ISO 8601 date format (e.g. 2008-04-12T12:53Z). + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Gets or sets the date time styles used when converting a date to and from JSON. + + The date time styles used when converting a date to and from JSON. + + + + Gets or sets the date time format used when converting a date to and from JSON. + + The date time format used when converting a date to and from JSON. + + + + Gets or sets the culture used when converting a date to and from JSON. + + The culture used when converting a date to and from JSON. + + + + Converts a to and from a JavaScript date constructor (e.g. new Date(52231943)). + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Specifies whether a DateTime object represents a local time, a Coordinated Universal Time (UTC), or is not specified as either local time or UTC. + + + + + The time represented is local time. + + + + + The time represented is UTC. + + + + + The time represented is not specified as either local time or Coordinated Universal Time (UTC). + + + + + Preserves the DateTimeKind field of a date when a DateTime object is converted to a string and the string is then converted back to a DateTime object. + + + + + Converts an to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The calling serializer. + The value. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Checks if the attributeName is a namespace attribute. + + Attribute name to test. + The attribute name prefix if it has one, otherwise an empty string. + True if attribute name is for a namespace attribute, otherwise false. + + + + Determines whether this instance can convert the specified value type. + + Type of the value. + + true if this instance can convert the specified value type; otherwise, false. + + + + + Gets or sets the name of the root element to insert when deserializing to XML if the JSON structure has produces multiple root elements. + + The name of the deserialize root element. + + + + Converts a object to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The calling serializer. + The value. + + + + Determines whether this instance can convert the specified value type. + + Type of the value. + + true if this instance can convert the specified value type; otherwise, false. + + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The calling serializer. + The object value. + + + + Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. + + + + + Initializes a new instance of the class with the specified . + + The TextReader containing the XML data to read. + + + + Reads the next JSON token from the stream. + + + true if the next token was read successfully; false if there are no more tokens to read. + + + + + Reads the next JSON token from the stream as a . + + + A or a null reference if the next JSON token is null. + + + + + Changes the state to closed. + + + + + Gets a value indicating whether the class can return line information. + + + true if LineNumber and LinePosition can be provided; otherwise, false. + + + + + Gets the current line number. + + + The current line number or 0 if no line information is available (for example, HasLineInfo returns false). + + + + + Gets the current line position. + + + The current line position or 0 if no line information is available (for example, HasLineInfo returns false). + + + + + Instructs the to always serialize the member with the specified name. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the specified name. + + Name of the property. + + + + Gets or sets the null value handling used when serializing this property. + + The null value handling. + + + + Gets or sets the default value handling used when serializing this property. + + The default value handling. + + + + Gets or sets the reference loop handling used when serializing this property. + + The reference loop handling. + + + + Gets or sets the object creation handling used when deserializing this property. + + The object creation handling. + + + + Gets or sets whether this property's value is serialized as a reference. + + Whether this property's value is serialized as a reference. + + + + Gets or sets the name of the property. + + The name of the property. + + + + Gets or sets a value indicating whether this property is required. + + + A value indicating whether this property is required. + + + + + Instructs the not to serialize the public field or public read/write property value. + + + + + Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. + + + + + Creates an instance of the JsonWriter class using the specified . + + The TextWriter to write to. + + + + Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + + + + + Closes this stream and the underlying stream. + + + + + Writes the beginning of a Json object. + + + + + Writes the beginning of a Json array. + + + + + Writes the start of a constructor with the given name. + + The name of the constructor. + + + + Writes the specified end token. + + The end token to write. + + + + Writes the property name of a name/value pair on a Json object. + + The name of the property. + + + + Writes indent characters. + + + + + Writes the JSON value delimiter. + + + + + Writes an indent space. + + + + + Writes a null value. + + + + + Writes an undefined value. + + + + + Writes raw JSON. + + The raw JSON to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes out a comment /*...*/ containing the specified text. + + Text to place inside the comment. + + + + Writes out the given white space. + + The string of white space characters. + + + + Gets or sets how many IndentChars to write for each level in the hierarchy when is set to Formatting.Indented. + + + + + Gets or sets which character to use to quote attribute values. + + + + + Gets or sets which character to use for indenting when is set to Formatting.Indented. + + + + + Gets or sets a value indicating whether object names will be surrounded with quotes. + + + + + The exception thrown when an error occurs while reading Json text. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + The exception thrown when an error occurs while reading Json text. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + Gets the line number indicating where the error occurred. + + The line number indicating where the error occurred. + + + + Gets the line position indicating where the error occurred. + + The line position indicating where the error occurred. + + + + Represents a collection of . + + + + + Provides methods for converting between common language runtime types and JSON types. + + + + + Represents JavaScript's boolean value true as a string. This field is read-only. + + + + + Represents JavaScript's boolean value false as a string. This field is read-only. + + + + + Represents JavaScript's null as a string. This field is read-only. + + + + + Represents JavaScript's undefined as a string. This field is read-only. + + + + + Represents JavaScript's positive infinity as a string. This field is read-only. + + + + + Represents JavaScript's negative infinity as a string. This field is read-only. + + + + + Represents JavaScript's NaN as a string. This field is read-only. + + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + The string delimiter character. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Serializes the specified object to a JSON string. + + The object to serialize. + A JSON string representation of the object. + + + + Serializes the specified object to a JSON string. + + The object to serialize. + Indicates how the output is formatted. + + A JSON string representation of the object. + + + + + Serializes the specified object to a JSON string using a collection of . + + The object to serialize. + A collection converters used while serializing. + A JSON string representation of the object. + + + + Serializes the specified object to a JSON string using a collection of . + + The object to serialize. + Indicates how the output is formatted. + A collection converters used while serializing. + A JSON string representation of the object. + + + + Serializes the specified object to a JSON string using a collection of . + + The object to serialize. + Indicates how the output is formatted. + The used to serialize the object. + If this is null, default serialization settings will be is used. + + A JSON string representation of the object. + + + + + Deserializes the specified object to a Json object. + + The object to deserialize. + The deserialized object from the Json string. + + + + Deserializes the specified object to a Json object. + + The object to deserialize. + The of object being deserialized. + The deserialized object from the Json string. + + + + Deserializes the specified object to a Json object. + + The type of the object to deserialize. + The object to deserialize. + The deserialized object from the Json string. + + + + Deserializes the specified JSON to the given anonymous type. + + + The anonymous type to deserialize to. This can't be specified + traditionally and must be infered from the anonymous type passed + as a parameter. + + The object to deserialize. + The anonymous type object. + The deserialized anonymous type from the JSON string. + + + + Deserializes the JSON string to the specified type. + + The type of the object to deserialize. + The object to deserialize. + Converters to use while deserializing. + The deserialized object from the JSON string. + + + + Deserializes the JSON string to the specified type. + + The type of the object to deserialize. + The object to deserialize. + + The used to deserialize the object. + If this is null, default serialization settings will be is used. + + The deserialized object from the JSON string. + + + + Deserializes the JSON string to the specified type. + + The object to deserialize. + The type of the object to deserialize. + Converters to use while deserializing. + The deserialized object from the JSON string. + + + + Deserializes the JSON string to the specified type. + + The JSON to deserialize. + The type of the object to deserialize. + + The used to deserialize the object. + If this is null, default serialization settings will be is used. + + The deserialized object from the JSON string. + + + + Populates the object with values from the JSON string. + + The JSON to populate values from. + The target object to populate values onto. + + + + Populates the object with values from the JSON string. + + The JSON to populate values from. + The target object to populate values onto. + + The used to deserialize the object. + If this is null, default serialization settings will be is used. + + + + + Serializes the XML node to a JSON string. + + The node to serialize. + A JSON string of the XmlNode. + + + + Deserializes the XmlNode from a JSON string. + + The JSON string. + The deserialized XmlNode + + + + Deserializes the XmlNode from a JSON string nested in a root elment. + + The JSON string. + The name of the root element to append when deserializing. + The deserialized XmlNode + + + + The exception thrown when an error occurs during Json serialization or deserialization. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + Serializes and deserializes objects into and from the JSON format. + The enables you to control how objects are encoded into JSON. + + + + + Initializes a new instance of the class. + + + + + Creates a new instance using the specified . + + The settings to be applied to the . + A new instance using the specified . + + + + Populates the JSON values onto the target object. + + The that contains the JSON structure to reader values from. + The target object to populate values onto. + + + + Populates the JSON values onto the target object. + + The that contains the JSON structure to reader values from. + The target object to populate values onto. + + + + Deserializes the Json structure contained by the specified . + + The that contains the JSON structure to deserialize. + The being deserialized. + + + + Deserializes the Json structure contained by the specified + into an instance of the specified type. + + The containing the object. + The of object being deserialized. + The instance of being deserialized. + + + + Deserializes the Json structure contained by the specified + into an instance of the specified type. + + The containing the object. + The type of the object to deserialize. + The instance of being deserialized. + + + + Deserializes the Json structure contained by the specified + into an instance of the specified type. + + The containing the object. + The of object being deserialized. + The instance of being deserialized. + + + + Serializes the specified and writes the Json structure + to a Stream using the specified . + + The used to write the Json structure. + The to serialize. + + + + Serializes the specified and writes the Json structure + to a Stream using the specified . + + The used to write the Json structure. + The to serialize. + + + + Occurs when the errors during serialization and deserialization. + + + + + Gets or sets the used by the serializer when resolving references. + + + + + Gets or sets the used by the serializer when resolving type names. + + + + + Gets or sets how type name writing and reading is handled by the serializer. + + + + + Gets or sets how object references are preserved by the serializer. + + + + + Get or set how reference loops (e.g. a class referencing itself) is handled. + + + + + Get or set how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. + + + + + Get or set how null values are handled during serialization and deserialization. + + + + + Get or set how null default are handled during serialization and deserialization. + + + + + Gets or sets how objects are created during deserialization. + + The object creation handling. + + + + Gets or sets how constructors are used during deserialization. + + The constructor handling. + + + + Gets a collection that will be used during serialization. + + Collection that will be used during serialization. + + + + Gets or sets the contract resolver used by the serializer when + serializing .NET objects to JSON and vice versa. + + + + + Gets or sets the used by the serializer when invoking serialization callback methods. + + The context. + + + + Contains the LINQ to JSON extension methods. + + + + + Returns a collection of tokens that contains the ancestors of every token in the source collection. + + The type of the objects in source, constrained to . + An of that contains the source collection. + An of that contains the ancestors of every node in the source collection. + + + + Returns a collection of tokens that contains the descendants of every token in the source collection. + + The type of the objects in source, constrained to . + An of that contains the source collection. + An of that contains the descendants of every node in the source collection. + + + + Returns a collection of child properties of every object in the source collection. + + An of that contains the source collection. + An of that contains the properties of every object in the source collection. + + + + Returns a collection of child values of every object in the source collection with the given key. + + An of that contains the source collection. + The token key. + An of that contains the values of every node in the source collection with the given key. + + + + Returns a collection of child values of every object in the source collection. + + An of that contains the source collection. + An of that contains the values of every node in the source collection. + + + + Returns a collection of converted child values of every object in the source collection with the given key. + + The type to convert the values to. + An of that contains the source collection. + The token key. + An that contains the converted values of every node in the source collection with the given key. + + + + Returns a collection of converted child values of every object in the source collection. + + The type to convert the values to. + An of that contains the source collection. + An that contains the converted values of every node in the source collection. + + + + Converts the value. + + The type to convert the value to. + A cast as a of . + A converted value. + + + + Converts the value. + + The source collection type. + The type to convert the value to. + A cast as a of . + A converted value. + + + + Returns a collection of child tokens of every array in the source collection. + + The source collection type. + An of that contains the source collection. + An of that contains the values of every node in the source collection. + + + + Returns a collection of converted child tokens of every array in the source collection. + + An of that contains the source collection. + The type to convert the values to. + The source collection type. + An that contains the converted values of every node in the source collection. + + + + Returns the input typed as . + + An of that contains the source collection. + The input typed as . + + + + Returns the input typed as . + + The source collection type. + An of that contains the source collection. + The input typed as . + + + + Represents a JSON constructor. + + + + + Represents a token that can contain other tokens. + + + + + Raises the event. + + The instance containing the event data. + + + + Raises the event. + + The instance containing the event data. + + + + Returns a collection of the child tokens of this token, in document order. + + + An of containing the child tokens of this , in document order. + + + + + Returns a collection of the child values of this token, in document order. + + The type to convert the values to. + + A containing the child values of this , in document order. + + + + + Returns a collection of the descendant tokens for this token in document order. + + An containing the descendant tokens of the . + + + + Adds the specified content as children of this . + + The content to be added. + + + + Adds the specified content as the first children of this . + + The content to be added. + + + + Creates an that can be used to add tokens to the . + + An that is ready to have content written to it. + + + + Replaces the children nodes of this token with the specified content. + + The content. + + + + Removes the child nodes from this token. + + + + + Occurs when the list changes or an item in the list changes. + + + + + Occurs before an item is added to the collection. + + + + + Gets a value indicating whether this token has childen tokens. + + + true if this token has child values; otherwise, false. + + + + + Get the first child token of this token. + + + A containing the first child token of the . + + + + + Get the last child token of this token. + + + A containing the last child token of the . + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class with the specified name and content. + + The constructor name. + The contents of the constructor. + + + + Initializes a new instance of the class with the specified name and content. + + The constructor name. + The contents of the constructor. + + + + Initializes a new instance of the class with the specified name. + + The constructor name. + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Loads an from a . + + A that will be read for the content of the . + A that contains the JSON that was read from the specified . + + + + Gets or sets the name of this constructor. + + The constructor name. + + + + Gets the node type for this . + + The type. + + + + Gets the with the specified key. + + The with the specified key. + + + + Represents a collection of objects. + + The type of token + + + + An empty collection of objects. + + + + + Initializes a new instance of the struct. + + The enumerable. + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Returns an enumerator that iterates through a collection. + + + An object that can be used to iterate through the collection. + + + + + Determines whether the specified is equal to this instance. + + The to compare with this instance. + + true if the specified is equal to this instance; otherwise, false. + + + + + Returns a hash code for this instance. + + + A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + + + + + Gets the with the specified key. + + + + + + Represents a JSON object. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class with the specified content. + + The contents of the object. + + + + Initializes a new instance of the class with the specified content. + + The contents of the object. + + + + Gets an of this object's properties. + + An of this object's properties. + + + + Gets a the specified name. + + The property name. + A with the specified name or null. + + + + Gets an of this object's property values. + + An of this object's property values. + + + + Loads an from a . + + A that will be read for the content of the . + A that contains the JSON that was read from the specified . + + + + Load a from a string that contains JSON. + + A that contains JSON. + A populated from the string that contains JSON. + + + + Creates a from an object. + + The object that will be used to create . + A with the values of the specified object + + + + Creates a from an object. + + The object that will be used to create . + The that will be used to read the object. + A with the values of the specified object + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Adds the specified property name. + + Name of the property. + The value. + + + + Removes the property with the specified name. + + Name of the property. + true if item was successfully removed; otherwise, false. + + + + Tries the get value. + + Name of the property. + The value. + true if a value was successfully retrieved; otherwise, false. + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Raises the event with the provided arguments. + + Name of the property. + + + + Occurs when a property value changes. + + + + + Gets the node type for this . + + The type. + + + + Gets the with the specified key. + + The with the specified key. + + + + Gets or sets the with the specified property name. + + + + + + Gets the number of elements contained in the . + + + The number of elements contained in the . + + + + Represents a JSON array. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class with the specified content. + + The contents of the array. + + + + Initializes a new instance of the class with the specified content. + + The contents of the array. + + + + Loads an from a . + + A that will be read for the content of the . + A that contains the JSON that was read from the specified . + + + + Load a from a string that contains JSON. + + A that contains JSON. + A populated from the string that contains JSON. + + + + Creates a from an object. + + The object that will be used to create . + A with the values of the specified object + + + + Creates a from an object. + + The object that will be used to create . + The that will be used to read the object. + A with the values of the specified object + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Determines the index of a specific item in the . + + The object to locate in the . + + The index of if found in the list; otherwise, -1. + + + + + Inserts an item to the at the specified index. + + The zero-based index at which should be inserted. + The object to insert into the . + + is not a valid index in the . + The is read-only. + + + + Removes the item at the specified index. + + The zero-based index of the item to remove. + + is not a valid index in the . + The is read-only. + + + + Adds an item to the . + + The object to add to the . + The is read-only. + + + + Removes all items from the . + + The is read-only. + + + + Determines whether the contains a specific value. + + The object to locate in the . + + true if is found in the ; otherwise, false. + + + + + Removes the first occurrence of a specific object from the . + + The object to remove from the . + + true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . + + The is read-only. + + + + Gets the node type for this . + + The type. + + + + Gets the with the specified key. + + The with the specified key. + + + + Gets or sets the at the specified index. + + + + + + Gets the number of elements contained in the . + + + The number of elements contained in the . + + + + Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. + + + + + Initializes a new instance of the class. + + The token to read from. + + + + Reads the next JSON token from the stream as a . + + + A or a null reference if the next JSON token is null. + + + + + Reads the next JSON token from the stream. + + + true if the next token was read successfully; false if there are no more tokens to read. + + + + + Represents a JSON property. + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Returns a collection of the child tokens of this token, in document order. + + + An of containing the child tokens of this , in document order. + + + + + Initializes a new instance of the class. + + The property name. + The property content. + + + + Initializes a new instance of the class. + + The property name. + The property content. + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Loads an from a . + + A that will be read for the content of the . + A that contains the JSON that was read from the specified . + + + + Gets the property name. + + The property name. + + + + Gets or sets the property value. + + The property value. + + + + Gets the node type for this . + + The type. + + + + Specifies the type of token. + + + + + No token type has been set. + + + + + A JSON object. + + + + + A JSON array. + + + + + A JSON constructor. + + + + + A JSON object property. + + + + + A comment. + + + + + An integer value. + + + + + A float value. + + + + + A string value. + + + + + A boolean value. + + + + + A null value. + + + + + An undefined value. + + + + + A date value. + + + + + A raw JSON value. + + + + + A collection of bytes value. + + + + + Contains the JSON schema extension methods. + + + + + Determines whether the is valid. + + The source to test. + The schema to test with. + + true if the specified is valid; otherwise, false. + + + + + Validates the specified . + + The source to test. + The schema to test with. + + + + Validates the specified . + + The source to test. + The schema to test with. + The validation event handler. + + + + Returns detailed information about the schema exception. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + Gets the line number indicating where the error occurred. + + The line number indicating where the error occurred. + + + + Gets the line position indicating where the error occurred. + + The line position indicating where the error occurred. + + + + Resolves from an id. + + + + + Initializes a new instance of the class. + + + + + Gets a for the specified id. + + The id. + A for the specified id. + + + + Gets or sets the loaded schemas. + + The loaded schemas. + + + + Specifies undefined schema Id handling options for the . + + + + + Do not infer a schema Id. + + + + + Use the .NET type name as the schema Id. + + + + + Use the assembly qualified .NET type name as the schema Id. + + + + + Returns detailed information related to the . + + + + + Gets the associated with the validation event. + + The JsonSchemaException associated with the validation event. + + + + Gets the text description corresponding to the validation event. + + The text description. + + + + Represents the callback method that will handle JSON schema validation events and the . + + + + + Resolves member mappings for a type, camel casing property names. + + + + + Used by to resolves a for a given . + + + + + Used by to resolves a for a given . + + + + + Resolves the contract for a given type. + + The type to resolve a contract for. + The contract for a given type. + + + + Initializes a new instance of the class. + + + + + Resolves the contract for a given type. + + The type to resolve a contract for. + The contract for a given type. + + + + Gets the serializable members for the type. + + The type to get serializable members for. + The serializable members for the type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Resolves the default for the contract. + + Type of the object. + + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates properties for the given . + + The contract to create properties for. + Properties for the given . + + + + Creates the used by the serializer to get and set values from a member. + + The member. + The used by the serializer to get and set values from a member. + + + + Creates a for the given . + + The member's declaring types . + The member to create a for. + A created for the given . + + + + Resolves the name of the property. + + Name of the property. + Name of the property. + + + + Gets or sets the default members search flags. + + The default members search flags. + + + + Resolves the name of the property. + + Name of the property. + The property name camel cased. + + + + The default serialization binder used when resolving and loading classes from type names. + + + + + When overridden in a derived class, controls the binding of a serialized object to a type. + + Specifies the name of the serialized object. + Specifies the name of the serialized object. + + The type of the object the formatter creates a new instance of. + + + + + Get and set values for a using dynamic methods. + + + + + Provides methods to get and set values. + + + + + Sets the value. + + The target to set the value on. + The value to set on the target. + + + + Gets the value. + + The target to get the value from. + The value. + + + + Initializes a new instance of the class. + + The member info. + + + + Sets the value. + + The target to set the value on. + The value to set on the target. + + + + Gets the value. + + The target to get the value from. + The value. + + + + Provides information surrounding an error. + + + + + Gets or sets the error. + + The error. + + + + Gets the original object that caused the error. + + The original object that caused the error. + + + + Gets the member that caused the error. + + The member that caused the error. + + + + Gets or sets a value indicating whether this is handled. + + true if handled; otherwise, false. + + + + Provides data for the Error event. + + + + + Initializes a new instance of the class. + + The current object. + The error context. + + + + Gets the current object the error event is being raised against. + + The current object the error event is being raised against. + + + + Gets the error context. + + The error context. + + + + Contract details for a used by the . + + + + + Contract details for a used by the . + + + + + Gets the underlying type for the contract. + + The underlying type for the contract. + + + + Gets or sets the type created during deserialization. + + The type created during deserialization. + + + + Gets or sets whether this type contract is serialized as a reference. + + Whether this type contract is serialized as a reference. + + + + Gets or sets the default for this contract. + + The converter. + + + + Gets or sets the method called immediately after deserialization of the object. + + The method called immediately after deserialization of the object. + + + + Gets or sets the method called during deserialization of the object. + + The method called during deserialization of the object. + + + + Gets or sets the method called after serialization of the object graph. + + The method called after serialization of the object graph. + + + + Gets or sets the method called before serialization of the object. + + The method called before serialization of the object. + + + + Gets or sets the default creator. + + The default creator. + + + + Gets or sets a value indicating whether [default creator non public]. + + true if the default object creator is non-public; otherwise, false. + + + + Gets or sets the method called when an error is thrown during the serialization of the object. + + The method called when an error is thrown during the serialization of the object. + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Maps a JSON property to a .NET member. + + + + + Gets the name of the property. + + The name of the property. + + + + Gets the that will get and set the during serialization. + + The that will get and set the during serialization. + + + + Gets or sets the type of the property. + + The type of the property. + + + + Gets or sets the for the property. + If set this converter takes presidence over the contract converter for the property type. + + The converter. + + + + Gets a value indicating whether this is ignored. + + true if ignored; otherwise, false. + + + + Gets a value indicating whether this is readable. + + true if readable; otherwise, false. + + + + Gets a value indicating whether this is writable. + + true if writable; otherwise, false. + + + + Gets the member converter. + + The member converter. + + + + Gets the default value. + + The default value. + + + + Gets a value indicating whether this is required. + + A value indicating whether this is required. + + + + Gets a value indicating whether this property preserves object references. + + + true if this instance is reference; otherwise, false. + + + + + Gets the property null value handling. + + The null value handling. + + + + Gets the property default value handling. + + The default value handling. + + + + Gets the property reference loop handling. + + The reference loop handling. + + + + Gets the property object creation handling. + + The object creation handling. + + + + A collection of objects. + + + + + Initializes a new instance of the class. + + The contract. + + + + When implemented in a derived class, extracts the key from the specified element. + + The element from which to extract the key. + The key for the specified element. + + + + Adds a object. + + The property to add to the collection. + + + + Gets the closest matching object. + First attempts to get an exact case match of propertyName and then + a case insensitive match. + + Name of the property. + A matching property if found. + + + + Gets a property by property name. + + The name of the property to get. + Type property name string comparison. + A matching property if found. + + + + Specifies missing member handling options for the . + + + + + Ignore a missing member and do not attempt to deserialize it. + + + + + Throw a when a missing member is encountered during deserialization. + + + + + Specifies null value handling options for the . + + + + + Include null values when serializing and deserializing objects. + + + + + Ignore null values when serializing and deserializing objects. + + + + + Specifies reference loop handling options for the . + + + + + Throw a when a loop is encountered. + + + + + Ignore loop references and do not serialize. + + + + + Serialize loop references. + + + + + An in-memory representation of a JSON Schema. + + + + + Initializes a new instance of the class. + + + + + Reads a from the specified . + + The containing the JSON Schema to read. + The object representing the JSON Schema. + + + + Reads a from the specified . + + The containing the JSON Schema to read. + The to use when resolving schema references. + The object representing the JSON Schema. + + + + Load a from a string that contains schema JSON. + + A that contains JSON. + A populated from the string that contains JSON. + + + + Parses the specified json. + + The json. + The resolver. + A populated from the string that contains JSON. + + + + Writes this schema to a . + + A into which this method will write. + + + + Writes this schema to a using the specified . + + A into which this method will write. + The resolver used. + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Gets or sets the id. + + + + + Gets or sets the title. + + + + + Gets or sets whether the object is optional. + + + + + Gets or sets whether the object is read only. + + + + + Gets or sets whether the object is visible to users. + + + + + Gets or sets whether the object is transient. + + + + + Gets or sets the description of the object. + + + + + Gets or sets the types of values allowed by the object. + + The type. + + + + Gets or sets the pattern. + + The pattern. + + + + Gets or sets the minimum length. + + The minimum length. + + + + Gets or sets the maximum length. + + The maximum length. + + + + Gets or sets the maximum decimals. + + The maximum decimals. + + + + Gets or sets the minimum. + + The minimum. + + + + Gets or sets the maximum. + + The maximum. + + + + Gets or sets the minimum number of items. + + The minimum number of items. + + + + Gets or sets the maximum number of items. + + The maximum number of items. + + + + Gets or sets the of items. + + The of items. + + + + Gets or sets the of properties. + + The of properties. + + + + Gets or sets the of additional properties. + + The of additional properties. + + + + Gets or sets a value indicating whether additional properties are allowed. + + + true if additional properties are allowed; otherwise, false. + + + + + Gets or sets the required property if this property is present. + + The required property if this property is present. + + + + Gets or sets the identity. + + The identity. + + + + Gets or sets the a collection of valid enum values allowed. + + A collection of valid enum values allowed. + + + + Gets or sets a collection of options. + + A collection of options. + + + + Gets or sets disallowed types. + + The disallow types. + + + + Gets or sets the default value. + + The default value. + + + + Gets or sets the extend . + + The extended . + + + + Gets or sets the format. + + The format. + + + + Generates a from a specified . + + + + + Generate a from the specified type. + + The type to generate a from. + A generated from the specified type. + + + + Generate a from the specified type. + + The type to generate a from. + The used to resolve schema references. + A generated from the specified type. + + + + Generate a from the specified type. + + The type to generate a from. + Specify whether the generated root will be nullable. + A generated from the specified type. + + + + Generate a from the specified type. + + The type to generate a from. + The used to resolve schema references. + Specify whether the generated root will be nullable. + A generated from the specified type. + + + + Gets or sets how undefined schemas are handled by the serializer. + + + + + Gets or sets the contract resolver. + + The contract resolver. + + + + The value types allowed by the . + + + + + No type specified. + + + + + String type. + + + + + Float type. + + + + + Integer type. + + + + + Boolean type. + + + + + Object type. + + + + + Array type. + + + + + Null type. + + + + + Any type. + + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Gets or sets the object member serialization. + + The member object serialization. + + + + Gets the object's properties. + + The object's properties. + + + + Gets or sets the parametrized constructor used to create the object. + + The parametrized constructor. + + + + When applied to a method, specifies that the method is called when an error occurs serializing an object. + + + + + Get and set values for a using reflection. + + + + + Initializes a new instance of the class. + + The member info. + + + + Sets the value. + + The target to set the value on. + The value to set on the target. + + + + Gets the value. + + The target to get the value from. + The value. + + + + Specifies type name handling options for the . + + + + + Do not include the .NET type name when serializing types. + + + + + Include the .NET type name when serializing into a JSON object structure. + + + + + Include the .NET type name when serializing into a JSON array structure. + + + + + Always include the .NET type name when serializing. + + + + + Converts the value to the specified type. + + The type to convert the value to. + The value to convert. + The converted type. + + + + Converts the value to the specified type. + + The type to convert the value to. + The value to convert. + The culture to use when converting. + The converted type. + + + + Converts the value to the specified type. + + The value to convert. + The culture to use when converting. + The type to convert the value to. + The converted type. + + + + Converts the value to the specified type. + + The type to convert the value to. + The value to convert. + The converted value if the conversion was successful or the default value of T if it failed. + + true if initialValue was converted successfully; otherwise, false. + + + + + Converts the value to the specified type. + + The type to convert the value to. + The value to convert. + The culture to use when converting. + The converted value if the conversion was successful or the default value of T if it failed. + + true if initialValue was converted successfully; otherwise, false. + + + + + Converts the value to the specified type. + + The value to convert. + The culture to use when converting. + The type to convert the value to. + The converted value if the conversion was successful or the default value of T if it failed. + + true if initialValue was converted successfully; otherwise, false. + + + + + Converts the value to the specified type. If the value is unable to be converted, the + value is checked whether it assignable to the specified type. + + The type to convert or cast the value to. + The value to convert. + The converted type. If conversion was unsuccessful, the initial value is returned if assignable to the target type + + + + Converts the value to the specified type. If the value is unable to be converted, the + value is checked whether it assignable to the specified type. + + The type to convert or cast the value to. + The value to convert. + The culture to use when converting. + The converted type. If conversion was unsuccessful, the initial value is returned if assignable to the target type + + + + Converts the value to the specified type. If the value is unable to be converted, the + value is checked whether it assignable to the specified type. + + The value to convert. + The culture to use when converting. + The type to convert or cast the value to. + + The converted type. If conversion was unsuccessful, the initial value + is returned if assignable to the target type. + + + + + Converts the value to the specified type. If the value is unable to be converted, the + value is checked whether it assignable to the specified type. + + The type to convert the value to. + The value to convert. + The converted value if the conversion was successful or the default value of T if it failed. + + true if initialValue was converted successfully or is assignable; otherwise, false. + + + + + Converts the value to the specified type. If the value is unable to be converted, the + value is checked whether it assignable to the specified type. + + The type to convert the value to. + The value to convert. + The culture to use when converting. + The converted value if the conversion was successful or the default value of T if it failed. + + true if initialValue was converted successfully or is assignable; otherwise, false. + + + + + Converts the value to the specified type. If the value is unable to be converted, the + value is checked whether it assignable to the specified type. + + The value to convert. + The culture to use when converting. + The type to convert the value to. + The converted value if the conversion was successful or the default value of T if it failed. + + true if initialValue was converted successfully or is assignable; otherwise, false. + + + + + Parses the specified enum member name, returning it's value. + + Name of the enum member. + + + + + Parses the specified enum member name, returning it's value. + + Name of the enum member. + If set to true ignore case. + + + + + Gets a dictionary of the names and values of an Enum type. + + + + + + Gets a dictionary of the names and values of an Enum type. + + + + + + Gets a dictionary of the names and values of an Enum type. + + The enum type to get names and values for. + + + + + Gets the maximum valid value of an Enum type. Flags enums are ORed. + + The type of the returned value. Must be assignable from the enum's underlying value type. + The enum type to get the maximum value for. + + + + + Specifies the type of Json token. + + + + + This is returned by the if a method has not been called. + + + + + An object start token. + + + + + An array start token. + + + + + A constructor start token. + + + + + An object property name. + + + + + A comment. + + + + + Raw JSON. + + + + + An interger. + + + + + A float. + + + + + A string. + + + + + A boolean. + + + + + A null token. + + + + + An undefined token. + + + + + An object end token. + + + + + An array end token. + + + + + A constructor end token. + + + + + A Date. + + + + + Byte data. + + + + + Specifies the state of the . + + + + + An exception has been thrown, which has left the in an invalid state. + You may call the method to put the in the Closed state. + Any other method calls results in an being thrown. + + + + + The method has been called. + + + + + An object is being written. + + + + + A array is being written. + + + + + A constructor is being written. + + + + + A property is being written. + + + + + A write method has not been called. + + + + + Specifies formatting options for the . + + + + + No special formatting is applied. This is the default. + + + + + Causes child objects to be indented according to the and settings. + + + + + Builds a string. Unlike StringBuilder this class lets you reuse it's internal buffer. + + + + + Determines whether the collection is null or empty. + + The collection. + + true if the collection is null or empty; otherwise, false. + + + + + Determines whether the collection is null or empty. + + The collection. + + true if the collection is null or empty; otherwise, false. + + + + + Determines whether the collection is null, empty or its contents are uninitialized values. + + The list. + + true if the collection is null or empty or its contents are uninitialized values; otherwise, false. + + + + + Makes a slice of the specified list in between the start and end indexes. + + The list. + The start index. + The end index. + A slice of the list. + + + + Makes a slice of the specified list in between the start and end indexes, + getting every so many items based upon the step. + + The list. + The start index. + The end index. + The step. + A slice of the list. + + + + Group the collection using a function which returns the key. + + The source collection to group. + The key selector. + A Dictionary with each key relating to a list of objects in a list grouped under it. + + + + Adds the elements of the specified collection to the specified generic IList. + + The list to add to. + The collection of elements to add. + + + + Gets the type of the typed collection's items. + + The type. + The type of the typed collection's items. + + + + Tests whether the list's items are their unitialized value. + + The list. + Whether the list's items are their unitialized value + + + + Gets the member's underlying type. + + The member. + The underlying type of the member. + + + + Determines whether the member is an indexed property. + + The member. + + true if the member is an indexed property; otherwise, false. + + + + + Determines whether the property is an indexed property. + + The property. + + true if the property is an indexed property; otherwise, false. + + + + + Gets the member's value on the object. + + The member. + The target object. + The member's value on the object. + + + + Sets the member's value on the target object. + + The member. + The target. + The value. + + + + Determines whether the specified MemberInfo can be read. + + The MemberInfo to determine whether can be read. + + true if the specified MemberInfo can be read; otherwise, false. + + + + + Determines whether the specified MemberInfo can be set. + + The MemberInfo to determine whether can be set. + + true if the specified MemberInfo can be set; otherwise, false. + + + + + Determines whether the string contains white space. + + The string to test for white space. + + true if the string contains white space; otherwise, false. + + + + + Determines whether the string is all white space. Empty string will return false. + + The string to test whether it is all white space. + + true if the string is all white space; otherwise, false. + + + + + Ensures the target string ends with the specified string. + + The target. + The value. + The target string with the value string at the end. + + + + Perform an action if the string is not null or empty. + + The value. + The action to perform. + + + + Indents the specified string. + + The string to indent. + The number of characters to indent by. + + + + + Indents the specified string. + + The string to indent. + The number of characters to indent by. + The indent character. + + + + + Numbers the lines. + + The string to number. + + + + + Nulls an empty string. + + The string. + Null if the string was null, otherwise the string unchanged. + + + diff --git a/bin/libbulletnet.dll b/bin/libbulletnet.dll index 3edd005..8ec7c55 100644 Binary files a/bin/libbulletnet.dll and b/bin/libbulletnet.dll differ -- cgit v1.1 From b9f5cd75bc9b46b067d151a1a13d4e95cc98cedb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Mar 2010 22:39:15 +0000 Subject: refactor: move client invoked AttachObject from SceneGraph to AttachmentsModule --- .../Avatar/Attachments/AttachmentsModule.cs | 32 +++++++++++++++++++- .../Framework/Interfaces/IAttachmentsModule.cs | 17 +++++++++-- OpenSim/Region/Framework/Scenes/Scene.cs | 13 ++++---- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 35 ---------------------- 4 files changed, 53 insertions(+), 44 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 3b7fe88..3c2cc42 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -67,6 +67,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments get { return false; } } + public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent) + { + m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject"); + + // If we can't take it, we can't attach it! + SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID); + if (part == null) + return; + + if (!m_scene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId)) + return; + + // Calls attach with a Zero position + if (AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false)) + { + m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); + + // Save avatar attachment information + ScenePresence presence; + if (m_scene.AvatarFactory != null && m_scene.TryGetAvatar(remoteClient.AgentId, out presence)) + { + m_log.Info( + "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + + ", AttachmentPoint: " + AttachmentPt); + + m_scene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); + } + } + } + public bool AttachObject( IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent) { @@ -143,7 +173,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt) { m_log.DebugFormat( - "[ATTACHMENTS MODULEY]: Updating inventory of {0} to show attachment of {1} (item ID {2})", + "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} (item ID {2})", remoteClient.Name, att.Name, itemID); if (!att.IsDeleted) diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 6cf2a2e..21c1056 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -35,17 +35,28 @@ namespace OpenSim.Region.Framework.Interfaces public interface IAttachmentsModule { /// + /// Attach an object to an avatar from the world. + /// + /// + /// + /// + /// + /// + void AttachObject( + IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent); + + /// /// Attach an object to an avatar. /// /// /// /// /// - /// + /// /// - /// true if the object was successfully attached, false otherwise + /// true if the object was successfully attached, false otherwise bool AttachObject( - IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent); + IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent); /// /// Update the user inventory to the attachment of an item diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 87a753e..d4d134f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2644,12 +2644,14 @@ namespace OpenSim.Region.Framework.Scenes public virtual void SubscribeToClientAttachmentEvents(IClientAPI client) { client.OnRezSingleAttachmentFromInv += RezSingleAttachment; - client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachments; - client.OnObjectAttach += m_sceneGraph.AttachObject; + client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachments; client.OnObjectDetach += m_sceneGraph.DetachObject; if (AttachmentsModule != null) + { + client.OnObjectAttach += AttachmentsModule.AttachObject; client.OnDetachAttachmentIntoInv += AttachmentsModule.ShowDetachInUserInventory; + } } public virtual void SubscribeToClientTeleportEvents(IClientAPI client) @@ -2774,7 +2776,6 @@ namespace OpenSim.Region.Framework.Scenes client.OnRezObject -= RezObject; } - public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client) { client.OnCreateNewInventoryItem -= CreateNewInventoryItem; @@ -2799,12 +2800,14 @@ namespace OpenSim.Region.Framework.Scenes public virtual void UnSubscribeToClientAttachmentEvents(IClientAPI client) { client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachments; - client.OnRezSingleAttachmentFromInv -= RezSingleAttachment; - client.OnObjectAttach -= m_sceneGraph.AttachObject; + client.OnRezSingleAttachmentFromInv -= RezSingleAttachment; client.OnObjectDetach -= m_sceneGraph.DetachObject; if (AttachmentsModule != null) + { + client.OnObjectAttach -= AttachmentsModule.AttachObject; client.OnDetachAttachmentIntoInv -= AttachmentsModule.ShowDetachInUserInventory; + } } public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 380722d..a88d456 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -487,41 +487,6 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Event Handling routine for Attach Object - /// - /// - /// - /// - /// - protected internal void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent) - { - // If we can't take it, we can't attach it! - SceneObjectPart part = m_parentScene.GetSceneObjectPart(objectLocalID); - if (part == null) - return; - - if (!m_parentScene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId)) - return; - - // Calls attach with a Zero position - if (m_parentScene.AttachmentsModule.AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false)) - { - m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); - - // Save avatar attachment information - ScenePresence presence; - if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence)) - { - m_log.Info( - "[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId - + ", AttachmentPoint: " + AttachmentPt); - - m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); - } - } - } - - /// /// Rez an attachment /// /// -- cgit v1.1 From 3ea9fdea8b8a17f50e2156e7a09ebb6523a0d4fc Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Fri, 12 Mar 2010 14:39:51 -0800 Subject: Minor tweak to clean up SimianGrid asset service URLs --- OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs index 7cb075e..1c22a72 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs @@ -101,7 +101,7 @@ namespace OpenSim.Services.Connectors.SimianGrid throw new Exception("Asset connector init error"); } - if (!serviceUrl.EndsWith("/")) + if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) serviceUrl = serviceUrl + '/'; m_serverUrl = serviceUrl; -- cgit v1.1 From 582375509c82220c40579c4e4095225bd9d67010 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Mar 2010 22:48:49 +0000 Subject: refactor: move RezSingleAttachmentFromInventory() from SceneGraph to AttachmentsModule --- .../Avatar/Attachments/AttachmentsModule.cs | 46 +++++++++++++++++++ .../Framework/Interfaces/IAttachmentsModule.cs | 11 ++++- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 6 +-- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 53 ---------------------- 5 files changed, 60 insertions(+), 58 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 3c2cc42..084f3c9 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -168,6 +168,52 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return true; } + + public SceneObjectGroup RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) + { + IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); + if (invAccess != null) + { + SceneObjectGroup objatt = invAccess.RezObject(remoteClient, + itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, + false, false, remoteClient.AgentId, true); + +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", +// objatt.Name, remoteClient.Name, AttachmentPt); + + if (objatt != null) + { + bool tainted = false; + if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) + tainted = true; + + AttachObject( + remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false); + //objatt.ScheduleGroupForFullUpdate(); + + if (tainted) + objatt.HasGroupChanged = true; + + // Fire after attach, so we don't get messy perms dialogs + // 3 == AttachedRez + objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 3); + + // Do this last so that event listeners have access to all the effects of the attachment + m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId); + } + else + { + m_log.WarnFormat( + "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", + itemID, remoteClient.Name, AttachmentPt); + } + + return objatt; + } + + return null; + } public UUID SetAttachmentInventoryStatus( SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt) diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 21c1056..1fa77e4 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -56,7 +56,16 @@ namespace OpenSim.Region.Framework.Interfaces /// /// true if the object was successfully attached, false otherwise bool AttachObject( - IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent); + IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent); + + /// + /// Rez an attachment from user inventory + /// + /// + /// + /// + /// The scene object that was attached. Null if the scene object could not be found + SceneObjectGroup RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt); /// /// Update the user inventory to the attachment of an item diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 7277527..dcd92d6 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1854,7 +1854,7 @@ namespace OpenSim.Region.Framework.Scenes { m_log.DebugFormat("[USER INVENTORY]: Rezzing single attachment from item {0} for {1}", itemID, remoteClient.Name); - SceneObjectGroup att = m_sceneGraph.RezSingleAttachment(remoteClient, itemID, AttachmentPt); + SceneObjectGroup att = AttachmentsModule.RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt); if (att == null) { diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d4d134f..50553dd 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2338,10 +2338,10 @@ namespace OpenSim.Region.Framework.Scenes //m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID); ScenePresence sp = GetScenePresence(userID); - if (sp != null) + if (sp != null && AttachmentsModule != null) { - uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID); - m_sceneGraph.RezSingleAttachment(sp.ControllingClient, itemID, attPt); + uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID); + AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt); } return false; diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index a88d456..d944834 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -486,59 +486,6 @@ namespace OpenSim.Region.Framework.Scenes } } - /// - /// Rez an attachment - /// - /// - /// - /// - /// The scene object that was attached. Null if the scene object could not be found - public SceneObjectGroup RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) - { - IInventoryAccessModule invAccess = m_parentScene.RequestModuleInterface(); - if (invAccess != null) - { - SceneObjectGroup objatt = invAccess.RezObject(remoteClient, - itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, - false, false, remoteClient.AgentId, true); - -// m_log.DebugFormat( -// "[SCENE GRAPH]: Retrieved single object {0} for attachment to {1} on point {2}", -// objatt.Name, remoteClient.Name, AttachmentPt); - - if (objatt != null) - { - bool tainted = false; - if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) - tainted = true; - - m_parentScene.AttachmentsModule.AttachObject( - remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false); - //objatt.ScheduleGroupForFullUpdate(); - - if (tainted) - objatt.HasGroupChanged = true; - - // Fire after attach, so we don't get messy perms dialogs - // 3 == AttachedRez - objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3); - - // Do this last so that event listeners have access to all the effects of the attachment - m_parentScene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId); - } - else - { - m_log.WarnFormat( - "[SCENE GRAPH]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", - itemID, remoteClient.Name, AttachmentPt); - } - - return objatt; - } - - return null; - } - protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance) { ScenePresence newAvatar = null; -- cgit v1.1 From 315fa06c75d023ef3e4285842dd730a4d94b78d6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Mar 2010 23:20:38 +0000 Subject: refactor: Move another RezSingleAttachment() from Scene.Inventory to AttachmentsModule --- .../Avatar/Attachments/AttachmentsModule.cs | 31 +++++++++++++++++++++- .../Framework/Interfaces/IAttachmentsModule.cs | 18 +++++++++++-- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 25 +---------------- OpenSim/Region/Framework/Scenes/Scene.cs | 8 +++--- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 12 ++++----- 5 files changed, 57 insertions(+), 37 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 084f3c9..f54e41a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -169,7 +169,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return true; } - public SceneObjectGroup RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) + public UUID RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) + { + m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing single attachment from item {0} for {1}", itemID, remoteClient.Name); + + return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true); + } + + public UUID RezSingleAttachmentFromInventory( + IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus) + { + SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(remoteClient, itemID, AttachmentPt); + + if (updateInventoryStatus) + { + if (att == null) + { + ShowDetachInUserInventory(itemID, remoteClient); + } + + SetAttachmentInventoryStatus(att, remoteClient, itemID, AttachmentPt); + } + + if (null == att) + return UUID.Zero; + else + return att.UUID; + } + + protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( + IClientAPI remoteClient, UUID itemID, uint AttachmentPt) { IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); if (invAccess != null) diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 1fa77e4..0222b02 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -59,13 +59,27 @@ namespace OpenSim.Region.Framework.Interfaces IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent); /// - /// Rez an attachment from user inventory + /// Rez an attachment from user inventory and change inventory status to match. /// /// /// /// /// The scene object that was attached. Null if the scene object could not be found - SceneObjectGroup RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt); + UUID RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt); + + /// + /// Rez an attachment from user inventory + /// + /// + /// + /// + /// + /// If true, we also update the user's inventory to show that the attachment is set. If false, we do not. + /// False is required so that we don't attempt to update information when a user enters a scene with the + /// attachment already correctly set up in inventory. + /// The uuid of the scene object that was attached. Null if the scene object could not be found + UUID RezSingleAttachmentFromInventory( + IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus); /// /// Update the user inventory to the attachment of an item diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index dcd92d6..41533a1 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1842,35 +1842,12 @@ namespace OpenSim.Region.Framework.Scenes EventManager.TriggerOnAttach(localID, itemID, avatarID); } - /// - /// Called when the client receives a request to rez a single attachment on to the avatar from inventory - /// (RezSingleAttachmentFromInv packet). - /// - /// - /// - /// - /// - public UUID RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) - { - m_log.DebugFormat("[USER INVENTORY]: Rezzing single attachment from item {0} for {1}", itemID, remoteClient.Name); - - SceneObjectGroup att = AttachmentsModule.RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt); - - if (att == null) - { - AttachmentsModule.ShowDetachInUserInventory(itemID, remoteClient); - return UUID.Zero; - } - - return AttachmentsModule.SetAttachmentInventoryStatus(att, remoteClient, itemID, AttachmentPt); - } - public void RezMultipleAttachments(IClientAPI remoteClient, RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header, RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects) { foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects) { - RezSingleAttachment(remoteClient, obj.ItemID, obj.AttachmentPt); + AttachmentsModule.RezSingleAttachmentFromInventory(remoteClient, obj.ItemID, obj.AttachmentPt); } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 50553dd..c510dc8 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2642,13 +2642,13 @@ namespace OpenSim.Region.Framework.Scenes } public virtual void SubscribeToClientAttachmentEvents(IClientAPI client) - { - client.OnRezSingleAttachmentFromInv += RezSingleAttachment; + { client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachments; client.OnObjectDetach += m_sceneGraph.DetachObject; if (AttachmentsModule != null) { + client.OnRezSingleAttachmentFromInv += AttachmentsModule.RezSingleAttachmentFromInventory; client.OnObjectAttach += AttachmentsModule.AttachObject; client.OnDetachAttachmentIntoInv += AttachmentsModule.ShowDetachInUserInventory; } @@ -2799,12 +2799,12 @@ namespace OpenSim.Region.Framework.Scenes public virtual void UnSubscribeToClientAttachmentEvents(IClientAPI client) { - client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachments; - client.OnRezSingleAttachmentFromInv -= RezSingleAttachment; + client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachments; client.OnObjectDetach -= m_sceneGraph.DetachObject; if (AttachmentsModule != null) { + client.OnRezSingleAttachmentFromInv -= AttachmentsModule.RezSingleAttachmentFromInventory; client.OnObjectAttach -= AttachmentsModule.AttachObject; client.OnDetachAttachmentIntoInv -= AttachmentsModule.ShowDetachInUserInventory; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 7661f1e..317c908 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3738,7 +3738,7 @@ namespace OpenSim.Region.Framework.Scenes { if (null == m_appearance) { - m_log.WarnFormat("[ATTACHMENT] Appearance has not been initialized for agent {0}", UUID); + m_log.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", UUID); return; } @@ -3762,12 +3762,12 @@ namespace OpenSim.Region.Framework.Scenes try { // Rez from inventory - UUID asset = m_scene.RezSingleAttachment(ControllingClient, - itemID, (uint)p); - - m_log.InfoFormat("[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", - p, itemID, assetID, asset); + UUID asset + = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); + m_log.InfoFormat( + "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", + p, itemID, assetID, asset); } catch (Exception e) { -- cgit v1.1 From 4b813932745775ef585a2cbca99233e57d20e13e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 12 Mar 2010 23:21:45 +0000 Subject: minor: remove some mono compiler warnings --- OpenSim/Services/GridService/GridService.cs | 6 ++---- OpenSim/Services/GridService/HypergridLinker.cs | 5 +++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index 1368e46..2faf018 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -123,8 +123,7 @@ namespace OpenSim.Services.GridService if ((rflags & OpenSim.Data.RegionFlags.Reservation) != 0) { // Regions reserved for the null key cannot be taken. - // - if (region.Data["PrincipalID"] == UUID.Zero.ToString()) + if ((string)region.Data["PrincipalID"] == UUID.Zero.ToString()) return "Region location us reserved"; // Treat it as an auth request @@ -132,7 +131,6 @@ namespace OpenSim.Services.GridService // NOTE: Fudging the flags value here, so these flags // should not be used elsewhere. Don't optimize // this with the later retrieval of the same flags! - // rflags |= OpenSim.Data.RegionFlags.Authenticate; } @@ -489,7 +487,7 @@ namespace OpenSim.Services.GridService f |= (OpenSim.Data.RegionFlags)val; } } - catch (Exception e) + catch (Exception) { MainConsole.Instance.Output("Error in flag specification: " + p); } diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs index de5df9d..58746d0 100644 --- a/OpenSim/Services/GridService/HypergridLinker.cs +++ b/OpenSim/Services/GridService/HypergridLinker.cs @@ -168,10 +168,11 @@ namespace OpenSim.Services.GridService } // Sanity check. - IPAddress ipaddr = null; + //IPAddress ipaddr = null; try { - ipaddr = Util.GetHostFromDNS(host); + //ipaddr = Util.GetHostFromDNS(host); + Util.GetHostFromDNS(host); } catch { -- cgit v1.1 From 1d14cf8c3f2ac706d7e4e9cc3a32a0dcc76d0061 Mon Sep 17 00:00:00 2001 From: dahlia Date: Fri, 12 Mar 2010 21:21:28 -0800 Subject: some improvements to sculptmap alpha handling and LOD --- OpenSim/Region/Physics/Meshing/SculptMesh.cs | 1272 +++++++++++++------------- 1 file changed, 645 insertions(+), 627 deletions(-) diff --git a/OpenSim/Region/Physics/Meshing/SculptMesh.cs b/OpenSim/Region/Physics/Meshing/SculptMesh.cs index 4dc6e2e..11b6cd4 100644 --- a/OpenSim/Region/Physics/Meshing/SculptMesh.cs +++ b/OpenSim/Region/Physics/Meshing/SculptMesh.cs @@ -1,627 +1,645 @@ -/* - * Copyright (c) Contributors - * 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. - */ - -// 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 -{ - - public class SculptMesh - { - public List coords; - public List faces; - - public List viewerFaces; - public List normals; - public List uvs; - - 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; - // int sourceHeight = srcImage.Height; - // int sourceX = 0; - // int sourceY = 0; - - // int destX = 0; - // int destY = 0; - // int destWidth = (int)(srcImage.Width * scale); - // int destHeight = (int)(srcImage.Height * scale); - - // if (srcImage.PixelFormat == PixelFormat.Format32bppArgb) - // for (int y = 0; y < srcImage.Height; y++) - // for (int x = 0; x < srcImage.Width; x++) - // { - // Color c = srcImage.GetPixel(x, y); - // srcImage.SetPixel(x, y, Color.FromArgb(255, c.R, c.G, c.B)); - // } - - // Bitmap scaledImage = new Bitmap(destWidth, destHeight, - // PixelFormat.Format24bppRgb); - - // scaledImage.SetResolution(96.0f, 96.0f); - - // Graphics grPhoto = Graphics.FromImage(scaledImage); - // grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low; - - // grPhoto.DrawImage(srcImage, - // new Rectangle(destX, destY, destWidth, destHeight), - // new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), - // GraphicsUnit.Pixel); - - // grPhoto.Dispose(); - // return scaledImage; - // } - - - public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode) - { - Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); - SculptMesh sculptMesh = new SculptMesh(bitmap, sculptType, lod, viewerMode); - bitmap.Dispose(); - return sculptMesh; - } - - public SculptMesh(string fileName, int sculptType, int lod, int viewerMode, int mirror, int invert) - { - Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); - _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 - /// Construct a sculpt mesh from a 2D array of floats - /// - /// - /// - /// - /// - /// - /// - public SculptMesh(float[,] zMap, float xBegin, float xEnd, float yBegin, float yEnd, bool viewerMode) - { - float xStep, yStep; - float uStep, vStep; - - int numYElements = zMap.GetLength(0); - int numXElements = zMap.GetLength(1); - - try - { - xStep = (xEnd - xBegin) / (float)(numXElements - 1); - yStep = (yEnd - yBegin) / (float)(numYElements - 1); - - uStep = 1.0f / (numXElements - 1); - vStep = 1.0f / (numYElements - 1); - } - catch (DivideByZeroException) - { - return; - } - - coords = new List(); - faces = new List(); - normals = new List(); - uvs = new List(); - - viewerFaces = new List(); - - int p1, p2, p3, p4; - - int x, y; - int xStart = 0, yStart = 0; - - for (y = yStart; y < numYElements; y++) - { - int rowOffset = y * numXElements; - - for (x = xStart; x < numXElements; x++) - { - /* - * p1-----p2 - * | \ f2 | - * | \ | - * | f1 \| - * p3-----p4 - */ - - p4 = rowOffset + x; - p3 = p4 - 1; - - p2 = p4 - numXElements; - p1 = p3 - numXElements; - - Coord c = new Coord(xBegin + x * xStep, yBegin + y * yStep, zMap[y, x]); - this.coords.Add(c); - if (viewerMode) - { - this.normals.Add(new Coord()); - this.uvs.Add(new UVCoord(uStep * x, 1.0f - vStep * y)); - } - - if (y > 0 && x > 0) - { - Face f1, f2; - - if (viewerMode) - { - f1 = new Face(p1, p4, p3, p1, p4, p3); - f1.uv1 = p1; - f1.uv2 = p4; - f1.uv3 = p3; - - f2 = new Face(p1, p2, p4, p1, p2, p4); - f2.uv1 = p1; - f2.uv2 = p2; - f2.uv3 = p4; - } - else - { - f1 = new Face(p1, p4, p3); - f2 = new Face(p1, p2, p4); - } - - this.faces.Add(f1); - this.faces.Add(f2); - } - } - } - - if (viewerMode) - 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); - } - - public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert) - { - _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 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. - /// - /// - /// - /// - /// - private List> bitmap2Coords(Bitmap bitmap, int scale, bool mirror) - { - int numRows = bitmap.Height / scale; - int numCols = bitmap.Width / scale; - List> rows = new List>(numRows); - - float pixScale = 1.0f / (scale * scale); - pixScale /= 255; - - int imageX, imageY = 0; - - int rowNdx, colNdx; - - for (rowNdx = 0; rowNdx < numRows; rowNdx++) - { - List row = new List(numCols); - for (colNdx = 0; colNdx < numCols; colNdx++) - { - imageX = colNdx * scale; - int imageYStart = rowNdx * scale; - int imageYEnd = imageYStart + scale; - int imageXEnd = imageX + scale; - float rSum = 0.0f; - float gSum = 0.0f; - float bSum = 0.0f; - for (; imageX < imageXEnd; imageX++) - { - for (imageY = imageYStart; imageY < imageYEnd; imageY++) - { - Color c = bitmap.GetPixel(imageX, imageY); - rSum += c.R; - gSum += c.G; - bSum += c.B; - } - } - if (mirror) - row.Add(new Coord(-(rSum * pixScale - 0.5f), gSum * pixScale - 0.5f, bSum * pixScale - 0.5f)); - else - row.Add(new Coord(rSum * pixScale - 0.5f, gSum * pixScale - 0.5f, bSum * pixScale - 0.5f)); - - } - rows.Add(row); - } - return rows; - } - - - void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, 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; - - float sourceScaleFactor = (float)(lod) / (float)Math.Sqrt(sculptBitmap.Width * sculptBitmap.Height); - - int scale = (int)(1.0f / sourceScaleFactor); - if (scale < 1) scale = 1; - - _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 = rows[0].Count; - - int p1, p2, p3, p4; - - int imageX, imageY; - - if (sculptType != SculptType.plane) - { - for (int rowNdx = 0; rowNdx < rows.Count; rowNdx++) - rows[rowNdx].Add(rows[rowNdx][0]); - } - - Coord topPole = rows[0][width / 2]; - Coord bottomPole = rows[rows.Count - 1][width / 2]; - - if (sculptType == SculptType.sphere) - { - int count = rows[0].Count; - List topPoleRow = new List(count); - List bottomPoleRow = new List(count); - - for (int i = 0; i < count; i++) - { - topPoleRow.Add(topPole); - bottomPoleRow.Add(bottomPole); - } - rows.Insert(0, topPoleRow); - rows.Add(bottomPoleRow); - } - else if (sculptType == SculptType.torus) - rows.Add(rows[0]); - - int coordsDown = rows.Count; - int coordsAcross = rows[0].Count; - - float widthUnit = 1.0f / (coordsAcross - 1); - float heightUnit = 1.0f / (coordsDown - 1); - - for (imageY = 0; imageY < coordsDown; imageY++) - { - int rowOffset = imageY * coordsAcross; - - for (imageX = 0; imageX < coordsAcross; imageX++) - { - /* - * p1-----p2 - * | \ f2 | - * | \ | - * | f1 \| - * p3-----p4 - */ - - p4 = rowOffset + imageX; - p3 = p4 - 1; - - p2 = p4 - coordsAcross; - p1 = p3 - coordsAcross; - - this.coords.Add(rows[imageY][imageX]); - if (viewerMode) - { - this.normals.Add(new Coord()); - this.uvs.Add(new UVCoord(widthUnit * imageX, heightUnit * imageY)); - } - - if (imageY > 0 && imageX > 0) - { - Face f1, f2; - - if (viewerMode) - { - if (invert) - { - f1 = new Face(p1, p4, p3, p1, p4, p3); - f1.uv1 = p1; - f1.uv2 = p4; - f1.uv3 = p3; - - f2 = new Face(p1, p2, p4, p1, p2, p4); - f2.uv1 = p1; - f2.uv2 = p2; - f2.uv3 = p4; - } - else - { - f1 = new Face(p1, p3, p4, p1, p3, p4); - f1.uv1 = p1; - f1.uv2 = p3; - f1.uv3 = p4; - - f2 = new Face(p1, p4, p2, p1, p4, p2); - f2.uv1 = p1; - f2.uv2 = p4; - f2.uv3 = p2; - } - } - else - { - if (invert) - { - f1 = new Face(p1, p4, p3); - f2 = new Face(p1, p2, p4); - } - else - { - f1 = new Face(p1, p3, p4); - f2 = new Face(p1, p4, p2); - } - } - - this.faces.Add(f1); - this.faces.Add(f2); - } - } - } - - if (viewerMode) - calcVertexNormals(sculptType, coordsAcross, coordsDown); - } - - /// - /// Duplicates a SculptMesh object. All object properties are copied by value, including lists. - /// - /// - public SculptMesh Copy() - { - return new SculptMesh(this); - } - - public SculptMesh(SculptMesh sm) - { - coords = new List(sm.coords); - faces = new List(sm.faces); - viewerFaces = new List(sm.viewerFaces); - normals = new List(sm.normals); - uvs = new List(sm.uvs); - } - - private void calcVertexNormals(SculptType sculptType, int xSize, int ySize) - { // compute vertex normals by summing all the surface normals of all the triangles sharing - // each vertex and then normalizing - int numFaces = this.faces.Count; - for (int i = 0; i < numFaces; i++) - { - Face face = this.faces[i]; - Coord surfaceNormal = face.SurfaceNormal(this.coords); - this.normals[face.n1] += surfaceNormal; - this.normals[face.n2] += surfaceNormal; - this.normals[face.n3] += surfaceNormal; - } - - int numNormals = this.normals.Count; - for (int i = 0; i < numNormals; i++) - this.normals[i] = this.normals[i].Normalize(); - - if (sculptType != SculptType.plane) - { // blend the vertex normals at the cylinder seam - for (int y = 0; y < ySize; y++) - { - int rowOffset = y * xSize; - - this.normals[rowOffset] = this.normals[rowOffset + xSize - 1] = (this.normals[rowOffset] + this.normals[rowOffset + xSize - 1]).Normalize(); - } - } - - foreach (Face face in this.faces) - { - ViewerFace vf = new ViewerFace(0); - vf.v1 = this.coords[face.v1]; - vf.v2 = this.coords[face.v2]; - vf.v3 = this.coords[face.v3]; - - vf.coordIndex1 = face.v1; - vf.coordIndex2 = face.v2; - vf.coordIndex3 = face.v3; - - vf.n1 = this.normals[face.n1]; - vf.n2 = this.normals[face.n2]; - vf.n3 = this.normals[face.n3]; - - vf.uv1 = this.uvs[face.uv1]; - vf.uv2 = this.uvs[face.uv2]; - vf.uv3 = this.uvs[face.uv3]; - - this.viewerFaces.Add(vf); - } - } - - /// - /// Adds a value to each XYZ vertex coordinate in the mesh - /// - /// - /// - /// - public void AddPos(float x, float y, float z) - { - int i; - int numVerts = this.coords.Count; - Coord vert; - - for (i = 0; i < numVerts; i++) - { - vert = this.coords[i]; - vert.X += x; - vert.Y += y; - vert.Z += z; - this.coords[i] = vert; - } - - if (this.viewerFaces != null) - { - int numViewerFaces = this.viewerFaces.Count; - - for (i = 0; i < numViewerFaces; i++) - { - ViewerFace v = this.viewerFaces[i]; - v.AddPos(x, y, z); - this.viewerFaces[i] = v; - } - } - } - - /// - /// Rotates the mesh - /// - /// - public void AddRot(Quat q) - { - int i; - int numVerts = this.coords.Count; - - for (i = 0; i < numVerts; i++) - this.coords[i] *= q; - - int numNormals = this.normals.Count; - for (i = 0; i < numNormals; i++) - this.normals[i] *= q; - - if (this.viewerFaces != null) - { - int numViewerFaces = this.viewerFaces.Count; - - for (i = 0; i < numViewerFaces; i++) - { - ViewerFace v = this.viewerFaces[i]; - v.v1 *= q; - v.v2 *= q; - v.v3 *= q; - - v.n1 *= q; - v.n2 *= q; - v.n3 *= q; - - this.viewerFaces[i] = v; - } - } - } - - public void Scale(float x, float y, float z) - { - int i; - int numVerts = this.coords.Count; - - Coord m = new Coord(x, y, z); - for (i = 0; i < numVerts; i++) - this.coords[i] *= m; - - if (this.viewerFaces != null) - { - int numViewerFaces = this.viewerFaces.Count; - for (i = 0; i < numViewerFaces; i++) - { - ViewerFace v = this.viewerFaces[i]; - v.v1 *= m; - v.v2 *= m; - v.v3 *= m; - this.viewerFaces[i] = v; - } - } - } - - public void DumpRaw(String path, String name, String title) - { - if (path == null) - return; - String fileName = name + "_" + title + ".raw"; - String completePath = System.IO.Path.Combine(path, fileName); - StreamWriter sw = new StreamWriter(completePath); - - for (int i = 0; i < this.faces.Count; i++) - { - string s = this.coords[this.faces[i].v1].ToString(); - s += " " + this.coords[this.faces[i].v2].ToString(); - s += " " + this.coords[this.faces[i].v3].ToString(); - - sw.WriteLine(s); - } - - sw.Close(); - } - } -} +/* + * Copyright (c) Contributors + * 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. + */ + +// 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 +{ + + public class SculptMesh + { + public List coords; + public List faces; + + public List viewerFaces; + public List normals; + public List uvs; + + public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 }; + +#if SYSTEM_DRAWING + private Bitmap ScaleImage(Bitmap srcImage, float scale, bool removeAlpha) + { + int sourceWidth = srcImage.Width; + int sourceHeight = srcImage.Height; + int sourceX = 0; + int sourceY = 0; + + int destX = 0; + int destY = 0; + int destWidth = (int)(srcImage.Width * scale); + int destHeight = (int)(srcImage.Height * scale); + + Bitmap scaledImage; + + if (removeAlpha) + { + if (srcImage.PixelFormat == PixelFormat.Format32bppArgb) + for (int y = 0; y < srcImage.Height; y++) + for (int x = 0; x < srcImage.Width; x++) + { + Color c = srcImage.GetPixel(x, y); + srcImage.SetPixel(x, y, Color.FromArgb(255, c.R, c.G, c.B)); + } + + scaledImage = new Bitmap(destWidth, destHeight, + PixelFormat.Format24bppRgb); + } + else + scaledImage = new Bitmap(srcImage, destWidth, destHeight); + + scaledImage.SetResolution(96.0f, 96.0f); + + Graphics grPhoto = Graphics.FromImage(scaledImage); + grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low; + + grPhoto.DrawImage(srcImage, + new Rectangle(destX, destY, destWidth, destHeight), + new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), + GraphicsUnit.Pixel); + + grPhoto.Dispose(); + return scaledImage; + } + + + public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode) + { + Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); + SculptMesh sculptMesh = new SculptMesh(bitmap, sculptType, lod, viewerMode); + bitmap.Dispose(); + return sculptMesh; + } + + public SculptMesh(string fileName, int sculptType, int lod, int viewerMode, int mirror, int invert) + { + Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); + _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 + /// Construct a sculpt mesh from a 2D array of floats + /// + /// + /// + /// + /// + /// + /// + public SculptMesh(float[,] zMap, float xBegin, float xEnd, float yBegin, float yEnd, bool viewerMode) + { + float xStep, yStep; + float uStep, vStep; + + int numYElements = zMap.GetLength(0); + int numXElements = zMap.GetLength(1); + + try + { + xStep = (xEnd - xBegin) / (float)(numXElements - 1); + yStep = (yEnd - yBegin) / (float)(numYElements - 1); + + uStep = 1.0f / (numXElements - 1); + vStep = 1.0f / (numYElements - 1); + } + catch (DivideByZeroException) + { + return; + } + + coords = new List(); + faces = new List(); + normals = new List(); + uvs = new List(); + + viewerFaces = new List(); + + int p1, p2, p3, p4; + + int x, y; + int xStart = 0, yStart = 0; + + for (y = yStart; y < numYElements; y++) + { + int rowOffset = y * numXElements; + + for (x = xStart; x < numXElements; x++) + { + /* + * p1-----p2 + * | \ f2 | + * | \ | + * | f1 \| + * p3-----p4 + */ + + p4 = rowOffset + x; + p3 = p4 - 1; + + p2 = p4 - numXElements; + p1 = p3 - numXElements; + + Coord c = new Coord(xBegin + x * xStep, yBegin + y * yStep, zMap[y, x]); + this.coords.Add(c); + if (viewerMode) + { + this.normals.Add(new Coord()); + this.uvs.Add(new UVCoord(uStep * x, 1.0f - vStep * y)); + } + + if (y > 0 && x > 0) + { + Face f1, f2; + + if (viewerMode) + { + f1 = new Face(p1, p4, p3, p1, p4, p3); + f1.uv1 = p1; + f1.uv2 = p4; + f1.uv3 = p3; + + f2 = new Face(p1, p2, p4, p1, p2, p4); + f2.uv1 = p1; + f2.uv2 = p2; + f2.uv3 = p4; + } + else + { + f1 = new Face(p1, p4, p3); + f2 = new Face(p1, p2, p4); + } + + this.faces.Add(f1); + this.faces.Add(f2); + } + } + } + + if (viewerMode) + 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); + } + + public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert) + { + _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 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. + /// + /// + /// + /// + /// + private List> bitmap2Coords(Bitmap bitmap, int scale, bool mirror) + { + int numRows = bitmap.Height / scale; + int numCols = bitmap.Width / scale; + List> rows = new List>(numRows); + + float pixScale = 1.0f / (scale * scale); + pixScale /= 255; + + int imageX, imageY = 0; + + int rowNdx, colNdx; + + for (rowNdx = 0; rowNdx < numRows; rowNdx++) + { + List row = new List(numCols); + for (colNdx = 0; colNdx < numCols; colNdx++) + { + imageX = colNdx * scale; + int imageYStart = rowNdx * scale; + int imageYEnd = imageYStart + scale; + int imageXEnd = imageX + scale; + float rSum = 0.0f; + float gSum = 0.0f; + float bSum = 0.0f; + for (; imageX < imageXEnd; imageX++) + { + for (imageY = imageYStart; imageY < imageYEnd; imageY++) + { + Color c = bitmap.GetPixel(imageX, imageY); + if (c.A != 255) + { + bitmap.SetPixel(imageX, imageY, Color.FromArgb(255, c.R, c.G, c.B)); + c = bitmap.GetPixel(imageX, imageY); + } + rSum += c.R; + gSum += c.G; + bSum += c.B; + } + } + if (mirror) + row.Add(new Coord(-(rSum * pixScale - 0.5f), gSum * pixScale - 0.5f, bSum * pixScale - 0.5f)); + else + row.Add(new Coord(rSum * pixScale - 0.5f, gSum * pixScale - 0.5f, bSum * pixScale - 0.5f)); + + } + rows.Add(row); + } + return rows; + } + + + void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, 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; + + float sculptBitmapLod = (float)Math.Sqrt(sculptBitmap.Width * sculptBitmap.Height); + + float sourceScaleFactor = (float)(lod) / sculptBitmapLod; + + float fScale = 1.0f / sourceScaleFactor; + + int iScale = (int)fScale; + if (iScale < 1) iScale = 1; + if (iScale > 2 && iScale % 2 == 0) + _SculptMesh(bitmap2Coords(ScaleImage(sculptBitmap, 64.0f / sculptBitmapLod, true), 64 / lod, mirror), sculptType, viewerMode, mirror, invert); + else + _SculptMesh(bitmap2Coords(sculptBitmap, iScale, 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 = rows[0].Count; + + int p1, p2, p3, p4; + + int imageX, imageY; + + if (sculptType != SculptType.plane) + { + for (int rowNdx = 0; rowNdx < rows.Count; rowNdx++) + rows[rowNdx].Add(rows[rowNdx][0]); + } + + Coord topPole = rows[0][width / 2]; + Coord bottomPole = rows[rows.Count - 1][width / 2]; + + if (sculptType == SculptType.sphere) + { + int count = rows[0].Count; + List topPoleRow = new List(count); + List bottomPoleRow = new List(count); + + for (int i = 0; i < count; i++) + { + topPoleRow.Add(topPole); + bottomPoleRow.Add(bottomPole); + } + rows.Insert(0, topPoleRow); + rows.Add(bottomPoleRow); + } + else if (sculptType == SculptType.torus) + rows.Add(rows[0]); + + int coordsDown = rows.Count; + int coordsAcross = rows[0].Count; + + float widthUnit = 1.0f / (coordsAcross - 1); + float heightUnit = 1.0f / (coordsDown - 1); + + for (imageY = 0; imageY < coordsDown; imageY++) + { + int rowOffset = imageY * coordsAcross; + + for (imageX = 0; imageX < coordsAcross; imageX++) + { + /* + * p1-----p2 + * | \ f2 | + * | \ | + * | f1 \| + * p3-----p4 + */ + + p4 = rowOffset + imageX; + p3 = p4 - 1; + + p2 = p4 - coordsAcross; + p1 = p3 - coordsAcross; + + this.coords.Add(rows[imageY][imageX]); + if (viewerMode) + { + this.normals.Add(new Coord()); + this.uvs.Add(new UVCoord(widthUnit * imageX, heightUnit * imageY)); + } + + if (imageY > 0 && imageX > 0) + { + Face f1, f2; + + if (viewerMode) + { + if (invert) + { + f1 = new Face(p1, p4, p3, p1, p4, p3); + f1.uv1 = p1; + f1.uv2 = p4; + f1.uv3 = p3; + + f2 = new Face(p1, p2, p4, p1, p2, p4); + f2.uv1 = p1; + f2.uv2 = p2; + f2.uv3 = p4; + } + else + { + f1 = new Face(p1, p3, p4, p1, p3, p4); + f1.uv1 = p1; + f1.uv2 = p3; + f1.uv3 = p4; + + f2 = new Face(p1, p4, p2, p1, p4, p2); + f2.uv1 = p1; + f2.uv2 = p4; + f2.uv3 = p2; + } + } + else + { + if (invert) + { + f1 = new Face(p1, p4, p3); + f2 = new Face(p1, p2, p4); + } + else + { + f1 = new Face(p1, p3, p4); + f2 = new Face(p1, p4, p2); + } + } + + this.faces.Add(f1); + this.faces.Add(f2); + } + } + } + + if (viewerMode) + calcVertexNormals(sculptType, coordsAcross, coordsDown); + } + + /// + /// Duplicates a SculptMesh object. All object properties are copied by value, including lists. + /// + /// + public SculptMesh Copy() + { + return new SculptMesh(this); + } + + public SculptMesh(SculptMesh sm) + { + coords = new List(sm.coords); + faces = new List(sm.faces); + viewerFaces = new List(sm.viewerFaces); + normals = new List(sm.normals); + uvs = new List(sm.uvs); + } + + private void calcVertexNormals(SculptType sculptType, int xSize, int ySize) + { // compute vertex normals by summing all the surface normals of all the triangles sharing + // each vertex and then normalizing + int numFaces = this.faces.Count; + for (int i = 0; i < numFaces; i++) + { + Face face = this.faces[i]; + Coord surfaceNormal = face.SurfaceNormal(this.coords); + this.normals[face.n1] += surfaceNormal; + this.normals[face.n2] += surfaceNormal; + this.normals[face.n3] += surfaceNormal; + } + + int numNormals = this.normals.Count; + for (int i = 0; i < numNormals; i++) + this.normals[i] = this.normals[i].Normalize(); + + if (sculptType != SculptType.plane) + { // blend the vertex normals at the cylinder seam + for (int y = 0; y < ySize; y++) + { + int rowOffset = y * xSize; + + this.normals[rowOffset] = this.normals[rowOffset + xSize - 1] = (this.normals[rowOffset] + this.normals[rowOffset + xSize - 1]).Normalize(); + } + } + + foreach (Face face in this.faces) + { + ViewerFace vf = new ViewerFace(0); + vf.v1 = this.coords[face.v1]; + vf.v2 = this.coords[face.v2]; + vf.v3 = this.coords[face.v3]; + + vf.coordIndex1 = face.v1; + vf.coordIndex2 = face.v2; + vf.coordIndex3 = face.v3; + + vf.n1 = this.normals[face.n1]; + vf.n2 = this.normals[face.n2]; + vf.n3 = this.normals[face.n3]; + + vf.uv1 = this.uvs[face.uv1]; + vf.uv2 = this.uvs[face.uv2]; + vf.uv3 = this.uvs[face.uv3]; + + this.viewerFaces.Add(vf); + } + } + + /// + /// Adds a value to each XYZ vertex coordinate in the mesh + /// + /// + /// + /// + public void AddPos(float x, float y, float z) + { + int i; + int numVerts = this.coords.Count; + Coord vert; + + for (i = 0; i < numVerts; i++) + { + vert = this.coords[i]; + vert.X += x; + vert.Y += y; + vert.Z += z; + this.coords[i] = vert; + } + + if (this.viewerFaces != null) + { + int numViewerFaces = this.viewerFaces.Count; + + for (i = 0; i < numViewerFaces; i++) + { + ViewerFace v = this.viewerFaces[i]; + v.AddPos(x, y, z); + this.viewerFaces[i] = v; + } + } + } + + /// + /// Rotates the mesh + /// + /// + public void AddRot(Quat q) + { + int i; + int numVerts = this.coords.Count; + + for (i = 0; i < numVerts; i++) + this.coords[i] *= q; + + int numNormals = this.normals.Count; + for (i = 0; i < numNormals; i++) + this.normals[i] *= q; + + if (this.viewerFaces != null) + { + int numViewerFaces = this.viewerFaces.Count; + + for (i = 0; i < numViewerFaces; i++) + { + ViewerFace v = this.viewerFaces[i]; + v.v1 *= q; + v.v2 *= q; + v.v3 *= q; + + v.n1 *= q; + v.n2 *= q; + v.n3 *= q; + + this.viewerFaces[i] = v; + } + } + } + + public void Scale(float x, float y, float z) + { + int i; + int numVerts = this.coords.Count; + + Coord m = new Coord(x, y, z); + for (i = 0; i < numVerts; i++) + this.coords[i] *= m; + + if (this.viewerFaces != null) + { + int numViewerFaces = this.viewerFaces.Count; + for (i = 0; i < numViewerFaces; i++) + { + ViewerFace v = this.viewerFaces[i]; + v.v1 *= m; + v.v2 *= m; + v.v3 *= m; + this.viewerFaces[i] = v; + } + } + } + + public void DumpRaw(String path, String name, String title) + { + if (path == null) + return; + String fileName = name + "_" + title + ".raw"; + String completePath = System.IO.Path.Combine(path, fileName); + StreamWriter sw = new StreamWriter(completePath); + + for (int i = 0; i < this.faces.Count; i++) + { + string s = this.coords[this.faces[i].v1].ToString(); + s += " " + this.coords[this.faces[i].v2].ToString(); + s += " " + this.coords[this.faces[i].v3].ToString(); + + sw.WriteLine(s); + } + + sw.Close(); + } + } +} -- cgit v1.1 From 41a98b902b0d95b28a5f26717150556107ca07b7 Mon Sep 17 00:00:00 2001 From: dahlia Date: Fri, 12 Mar 2010 22:05:22 -0800 Subject: correct some references which could produce erroneous prim face numbers --- OpenSim/Region/Physics/Meshing/PrimMesher.cs | 4403 +++++++++++++------------- 1 file changed, 2201 insertions(+), 2202 deletions(-) diff --git a/OpenSim/Region/Physics/Meshing/PrimMesher.cs b/OpenSim/Region/Physics/Meshing/PrimMesher.cs index 2a213c3..b75e271 100644 --- a/OpenSim/Region/Physics/Meshing/PrimMesher.cs +++ b/OpenSim/Region/Physics/Meshing/PrimMesher.cs @@ -1,2202 +1,2201 @@ -/* - * Copyright (c) Contributors - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Text; -using System.IO; - -namespace PrimMesher -{ - public struct Quat - { - /// X value - public float X; - /// Y value - public float Y; - /// Z value - public float Z; - /// W value - public float W; - - public Quat(float x, float y, float z, float w) - { - X = x; - Y = y; - Z = z; - W = w; - } - - public Quat(Coord axis, float angle) - { - axis = axis.Normalize(); - - angle *= 0.5f; - float c = (float)Math.Cos(angle); - float s = (float)Math.Sin(angle); - - X = axis.X * s; - Y = axis.Y * s; - Z = axis.Z * s; - W = c; - - Normalize(); - } - - public float Length() - { - return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W); - } - - public Quat Normalize() - { - const float MAG_THRESHOLD = 0.0000001f; - float mag = Length(); - - // Catch very small rounding errors when normalizing - if (mag > MAG_THRESHOLD) - { - float oomag = 1f / mag; - X *= oomag; - Y *= oomag; - Z *= oomag; - W *= oomag; - } - else - { - X = 0f; - Y = 0f; - Z = 0f; - W = 1f; - } - - return this; - } - - public static Quat operator *(Quat q1, Quat q2) - { - float x = q1.W * q2.X + q1.X * q2.W + q1.Y * q2.Z - q1.Z * q2.Y; - float y = q1.W * q2.Y - q1.X * q2.Z + q1.Y * q2.W + q1.Z * q2.X; - float z = q1.W * q2.Z + q1.X * q2.Y - q1.Y * q2.X + q1.Z * q2.W; - float w = q1.W * q2.W - q1.X * q2.X - q1.Y * q2.Y - q1.Z * q2.Z; - return new Quat(x, y, z, w); - } - - public override string ToString() - { - return "< X: " + this.X.ToString() + ", Y: " + this.Y.ToString() + ", Z: " + this.Z.ToString() + ", W: " + this.W.ToString() + ">"; - } - } - - public struct Coord - { - public float X; - public float Y; - public float Z; - - public Coord(float x, float y, float z) - { - this.X = x; - this.Y = y; - this.Z = z; - } - - public float Length() - { - return (float)Math.Sqrt(this.X * this.X + this.Y * this.Y + this.Z * this.Z); - } - - public Coord Invert() - { - this.X = -this.X; - this.Y = -this.Y; - this.Z = -this.Z; - - return this; - } - - public Coord Normalize() - { - const float MAG_THRESHOLD = 0.0000001f; - float mag = Length(); - - // Catch very small rounding errors when normalizing - if (mag > MAG_THRESHOLD) - { - float oomag = 1.0f / mag; - this.X *= oomag; - this.Y *= oomag; - this.Z *= oomag; - } - else - { - this.X = 0.0f; - this.Y = 0.0f; - this.Z = 0.0f; - } - - return this; - } - - public override string ToString() - { - return this.X.ToString() + " " + this.Y.ToString() + " " + this.Z.ToString(); - } - - public static Coord Cross(Coord c1, Coord c2) - { - return new Coord( - c1.Y * c2.Z - c2.Y * c1.Z, - c1.Z * c2.X - c2.Z * c1.X, - c1.X * c2.Y - c2.X * c1.Y - ); - } - - public static Coord operator +(Coord v, Coord a) - { - return new Coord(v.X + a.X, v.Y + a.Y, v.Z + a.Z); - } - - public static Coord operator *(Coord v, Coord m) - { - return new Coord(v.X * m.X, v.Y * m.Y, v.Z * m.Z); - } - - public static Coord operator *(Coord v, Quat q) - { - // From http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/ - - Coord c2 = new Coord(0.0f, 0.0f, 0.0f); - - c2.X = q.W * q.W * v.X + - 2f * q.Y * q.W * v.Z - - 2f * q.Z * q.W * v.Y + - q.X * q.X * v.X + - 2f * q.Y * q.X * v.Y + - 2f * q.Z * q.X * v.Z - - q.Z * q.Z * v.X - - q.Y * q.Y * v.X; - - c2.Y = - 2f * q.X * q.Y * v.X + - q.Y * q.Y * v.Y + - 2f * q.Z * q.Y * v.Z + - 2f * q.W * q.Z * v.X - - q.Z * q.Z * v.Y + - q.W * q.W * v.Y - - 2f * q.X * q.W * v.Z - - q.X * q.X * v.Y; - - c2.Z = - 2f * q.X * q.Z * v.X + - 2f * q.Y * q.Z * v.Y + - q.Z * q.Z * v.Z - - 2f * q.W * q.Y * v.X - - q.Y * q.Y * v.Z + - 2f * q.W * q.X * v.Y - - q.X * q.X * v.Z + - q.W * q.W * v.Z; - - return c2; - } - } - - public struct UVCoord - { - public float U; - public float V; - - - public UVCoord(float u, float v) - { - this.U = u; - this.V = v; - } - } - - public struct Face - { - public int primFace; - - // vertices - public int v1; - public int v2; - public int v3; - - //normals - public int n1; - public int n2; - public int n3; - - // uvs - public int uv1; - public int uv2; - public int uv3; - - - public Face(int v1, int v2, int v3) - { - primFace = 0; - - this.v1 = v1; - this.v2 = v2; - this.v3 = v3; - - this.n1 = 0; - this.n2 = 0; - this.n3 = 0; - - this.uv1 = 0; - this.uv2 = 0; - this.uv3 = 0; - - } - - public Face(int v1, int v2, int v3, int n1, int n2, int n3) - { - primFace = 0; - - this.v1 = v1; - this.v2 = v2; - this.v3 = v3; - - this.n1 = n1; - this.n2 = n2; - this.n3 = n3; - - this.uv1 = 0; - this.uv2 = 0; - this.uv3 = 0; - } - - public Coord SurfaceNormal(List coordList) - { - Coord c1 = coordList[this.v1]; - Coord c2 = coordList[this.v2]; - Coord c3 = coordList[this.v3]; - - Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z); - Coord edge2 = new Coord(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z); - - return Coord.Cross(edge1, edge2).Normalize(); - } - } - - public struct ViewerFace - { - public int primFaceNumber; - - public Coord v1; - public Coord v2; - public Coord v3; - - public int coordIndex1; - public int coordIndex2; - public int coordIndex3; - - public Coord n1; - public Coord n2; - public Coord n3; - - public UVCoord uv1; - public UVCoord uv2; - public UVCoord uv3; - - public ViewerFace(int primFaceNumber) - { - this.primFaceNumber = primFaceNumber; - - this.v1 = new Coord(); - this.v2 = new Coord(); - this.v3 = new Coord(); - - this.coordIndex1 = this.coordIndex2 = this.coordIndex3 = -1; // -1 means not assigned yet - - this.n1 = new Coord(); - this.n2 = new Coord(); - this.n3 = new Coord(); - - this.uv1 = new UVCoord(); - this.uv2 = new UVCoord(); - this.uv3 = new UVCoord(); - } - - public void Scale(float x, float y, float z) - { - this.v1.X *= x; - this.v1.Y *= y; - this.v1.Z *= z; - - this.v2.X *= x; - this.v2.Y *= y; - this.v2.Z *= z; - - this.v3.X *= x; - this.v3.Y *= y; - this.v3.Z *= z; - } - - public void AddPos(float x, float y, float z) - { - this.v1.X += x; - this.v2.X += x; - this.v3.X += x; - - this.v1.Y += y; - this.v2.Y += y; - this.v3.Y += y; - - this.v1.Z += z; - this.v2.Z += z; - this.v3.Z += z; - } - - public void AddRot(Quat q) - { - this.v1 *= q; - this.v2 *= q; - this.v3 *= q; - - this.n1 *= q; - this.n2 *= q; - this.n3 *= q; - } - - public void CalcSurfaceNormal() - { - - Coord edge1 = new Coord(this.v2.X - this.v1.X, this.v2.Y - this.v1.Y, this.v2.Z - this.v1.Z); - Coord edge2 = new Coord(this.v3.X - this.v1.X, this.v3.Y - this.v1.Y, this.v3.Z - this.v1.Z); - - this.n1 = this.n2 = this.n3 = Coord.Cross(edge1, edge2).Normalize(); - } - } - - internal struct Angle - { - internal float angle; - internal float X; - internal float Y; - - internal Angle(float angle, float x, float y) - { - this.angle = angle; - this.X = x; - this.Y = y; - } - } - - internal class AngleList - { - private float iX, iY; // intersection point - - private static Angle[] angles3 = - { - new Angle(0.0f, 1.0f, 0.0f), - new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), - new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f), - new Angle(1.0f, 1.0f, 0.0f) - }; - - private static Coord[] normals3 = - { - new Coord(0.25f, 0.4330127019f, 0.0f).Normalize(), - new Coord(-0.5f, 0.0f, 0.0f).Normalize(), - new Coord(0.25f, -0.4330127019f, 0.0f).Normalize(), - new Coord(0.25f, 0.4330127019f, 0.0f).Normalize() - }; - - private static Angle[] angles4 = - { - new Angle(0.0f, 1.0f, 0.0f), - new Angle(0.25f, 0.0f, 1.0f), - new Angle(0.5f, -1.0f, 0.0f), - new Angle(0.75f, 0.0f, -1.0f), - new Angle(1.0f, 1.0f, 0.0f) - }; - - private static Coord[] normals4 = - { - new Coord(0.5f, 0.5f, 0.0f).Normalize(), - new Coord(-0.5f, 0.5f, 0.0f).Normalize(), - new Coord(-0.5f, -0.5f, 0.0f).Normalize(), - new Coord(0.5f, -0.5f, 0.0f).Normalize(), - new Coord(0.5f, 0.5f, 0.0f).Normalize() - }; - - private static Angle[] angles24 = - { - new Angle(0.0f, 1.0f, 0.0f), - new Angle(0.041666666666666664f, 0.96592582628906831f, 0.25881904510252074f), - new Angle(0.083333333333333329f, 0.86602540378443871f, 0.5f), - new Angle(0.125f, 0.70710678118654757f, 0.70710678118654746f), - new Angle(0.16666666666666667f, 0.5f, 0.8660254037844386f), - new Angle(0.20833333333333331f, 0.25881904510252096f, 0.9659258262890682f), - new Angle(0.25f, 0.0f, 1.0f), - new Angle(0.29166666666666663f, -0.25881904510252063f, 0.96592582628906831f), - new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), - new Angle(0.375f, -0.70710678118654746f, 0.70710678118654757f), - new Angle(0.41666666666666663f, -0.86602540378443849f, 0.5f), - new Angle(0.45833333333333331f, -0.9659258262890682f, 0.25881904510252102f), - new Angle(0.5f, -1.0f, 0.0f), - new Angle(0.54166666666666663f, -0.96592582628906842f, -0.25881904510252035f), - new Angle(0.58333333333333326f, -0.86602540378443882f, -0.5f), - new Angle(0.62499999999999989f, -0.70710678118654791f, -0.70710678118654713f), - new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f), - new Angle(0.70833333333333326f, -0.25881904510252152f, -0.96592582628906809f), - new Angle(0.75f, 0.0f, -1.0f), - new Angle(0.79166666666666663f, 0.2588190451025203f, -0.96592582628906842f), - new Angle(0.83333333333333326f, 0.5f, -0.86602540378443904f), - new Angle(0.875f, 0.70710678118654735f, -0.70710678118654768f), - new Angle(0.91666666666666663f, 0.86602540378443837f, -0.5f), - new Angle(0.95833333333333326f, 0.96592582628906809f, -0.25881904510252157f), - new Angle(1.0f, 1.0f, 0.0f) - }; - - private Angle interpolatePoints(float newPoint, Angle p1, Angle p2) - { - float m = (newPoint - p1.angle) / (p2.angle - p1.angle); - return new Angle(newPoint, p1.X + m * (p2.X - p1.X), p1.Y + m * (p2.Y - p1.Y)); - } - - private void intersection(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) - { // ref: http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ - double denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); - double uaNumerator = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3); - - if (denom != 0.0) - { - double ua = uaNumerator / denom; - iX = (float)(x1 + ua * (x2 - x1)); - iY = (float)(y1 + ua * (y2 - y1)); - } - } - - internal List angles; - internal List normals; - - internal void makeAngles(int sides, float startAngle, float stopAngle) - { - angles = new List(); - normals = new List(); - - double twoPi = System.Math.PI * 2.0; - float twoPiInv = 1.0f / (float)twoPi; - - if (sides < 1) - throw new Exception("number of sides not greater than zero"); - if (stopAngle <= startAngle) - throw new Exception("stopAngle not greater than startAngle"); - - if ((sides == 3 || sides == 4 || sides == 24)) - { - startAngle *= twoPiInv; - stopAngle *= twoPiInv; - - Angle[] sourceAngles; - if (sides == 3) - sourceAngles = angles3; - else if (sides == 4) - sourceAngles = angles4; - else sourceAngles = angles24; - - int startAngleIndex = (int)(startAngle * sides); - int endAngleIndex = sourceAngles.Length - 1; - if (stopAngle < 1.0f) - endAngleIndex = (int)(stopAngle * sides) + 1; - if (endAngleIndex == startAngleIndex) - endAngleIndex++; - - for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex + 1; angleIndex++) - { - angles.Add(sourceAngles[angleIndex]); - if (sides == 3) - normals.Add(normals3[angleIndex]); - else if (sides == 4) - normals.Add(normals4[angleIndex]); - } - - if (startAngle > 0.0f) - angles[0] = interpolatePoints(startAngle, angles[0], angles[1]); - - if (stopAngle < 1.0f) - { - int lastAngleIndex = angles.Count - 1; - angles[lastAngleIndex] = interpolatePoints(stopAngle, angles[lastAngleIndex - 1], angles[lastAngleIndex]); - } - } - else - { - double stepSize = twoPi / sides; - - int startStep = (int)(startAngle / stepSize); - double angle = stepSize * startStep; - int step = startStep; - double stopAngleTest = stopAngle; - if (stopAngle < twoPi) - { - stopAngleTest = stepSize * ((int)(stopAngle / stepSize) + 1); - if (stopAngleTest < stopAngle) - stopAngleTest += stepSize; - if (stopAngleTest > twoPi) - stopAngleTest = twoPi; - } - - while (angle <= stopAngleTest) - { - Angle newAngle; - newAngle.angle = (float)angle; - newAngle.X = (float)System.Math.Cos(angle); - newAngle.Y = (float)System.Math.Sin(angle); - angles.Add(newAngle); - step += 1; - angle = stepSize * step; - } - - if (startAngle > angles[0].angle) - { - Angle newAngle; - intersection(angles[0].X, angles[0].Y, angles[1].X, angles[1].Y, 0.0f, 0.0f, (float)Math.Cos(startAngle), (float)Math.Sin(startAngle)); - newAngle.angle = startAngle; - newAngle.X = iX; - newAngle.Y = iY; - angles[0] = newAngle; - } - - int index = angles.Count - 1; - if (stopAngle < angles[index].angle) - { - Angle newAngle; - intersection(angles[index - 1].X, angles[index - 1].Y, angles[index].X, angles[index].Y, 0.0f, 0.0f, (float)Math.Cos(stopAngle), (float)Math.Sin(stopAngle)); - newAngle.angle = stopAngle; - newAngle.X = iX; - newAngle.Y = iY; - angles[index] = newAngle; - } - } - } - } - - /// - /// generates a profile for extrusion - /// - internal class Profile - { - private const float twoPi = 2.0f * (float)Math.PI; - - internal string errorMessage = null; - - internal List coords; - internal List faces; - internal List vertexNormals; - internal List us; - internal List faceUVs; - internal List faceNumbers; - - // use these for making individual meshes for each prim face - internal List outerCoordIndices = null; - internal List hollowCoordIndices = null; - internal List cut1CoordIndices = null; - internal List cut2CoordIndices = null; - - internal Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f); - internal Coord cutNormal1 = new Coord(); - internal Coord cutNormal2 = new Coord(); - - internal int numOuterVerts = 0; - internal int numHollowVerts = 0; - - internal bool calcVertexNormals = false; - internal int bottomFaceNumber = 0; - internal int numPrimFaces = 0; - - internal Profile() - { - this.coords = new List(); - this.faces = new List(); - this.vertexNormals = new List(); - this.us = new List(); - this.faceUVs = new List(); - this.faceNumbers = new List(); - } - - internal Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals) - { - this.calcVertexNormals = calcVertexNormals; - this.coords = new List(); - this.faces = new List(); - this.vertexNormals = new List(); - this.us = new List(); - this.faceUVs = new List(); - this.faceNumbers = new List(); - - Coord center = new Coord(0.0f, 0.0f, 0.0f); - //bool hasCenter = false; - - List hollowCoords = new List(); - List hollowNormals = new List(); - List hollowUs = new List(); - - if (calcVertexNormals) - { - this.outerCoordIndices = new List(); - this.hollowCoordIndices = new List(); - this.cut1CoordIndices = new List(); - this.cut2CoordIndices = new List(); - } - - bool hasHollow = (hollow > 0.0f); - - bool hasProfileCut = (profileStart > 0.0f || profileEnd < 1.0f); - - AngleList angles = new AngleList(); - AngleList hollowAngles = new AngleList(); - - float xScale = 0.5f; - float yScale = 0.5f; - if (sides == 4) // corners of a square are sqrt(2) from center - { - xScale = 0.707f; - yScale = 0.707f; - } - - float startAngle = profileStart * twoPi; - float stopAngle = profileEnd * twoPi; - - try { angles.makeAngles(sides, startAngle, stopAngle); } - catch (Exception ex) - { - - errorMessage = "makeAngles failed: Exception: " + ex.ToString() - + "\nsides: " + sides.ToString() + " startAngle: " + startAngle.ToString() + " stopAngle: " + stopAngle.ToString(); - - return; - } - - this.numOuterVerts = angles.angles.Count; - - // flag to create as few triangles as possible for 3 or 4 side profile - bool simpleFace = (sides < 5 && !hasHollow && !hasProfileCut); - - if (hasHollow) - { - if (sides == hollowSides) - hollowAngles = angles; - else - { - try { hollowAngles.makeAngles(hollowSides, startAngle, stopAngle); } - catch (Exception ex) - { - errorMessage = "makeAngles failed: Exception: " + ex.ToString() - + "\nsides: " + sides.ToString() + " startAngle: " + startAngle.ToString() + " stopAngle: " + stopAngle.ToString(); - - return; - } - } - this.numHollowVerts = hollowAngles.angles.Count; - } - else if (!simpleFace) - { - this.coords.Add(center); - //hasCenter = true; - if (this.calcVertexNormals) - this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f)); - this.us.Add(0.0f); - } - - float z = 0.0f; - - Angle angle; - Coord newVert = new Coord(); - if (hasHollow && hollowSides != sides) - { - int numHollowAngles = hollowAngles.angles.Count; - for (int i = 0; i < numHollowAngles; i++) - { - angle = hollowAngles.angles[i]; - newVert.X = hollow * xScale * angle.X; - newVert.Y = hollow * yScale * angle.Y; - newVert.Z = z; - - hollowCoords.Add(newVert); - if (this.calcVertexNormals) - { - if (hollowSides < 5) - hollowNormals.Add(hollowAngles.normals[i].Invert()); - else - hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); - - hollowUs.Add(angle.angle * hollow); - } - } - } - - int index = 0; - int numAngles = angles.angles.Count; - - for (int i = 0; i < numAngles; i++) - { - angle = angles.angles[i]; - newVert.X = angle.X * xScale; - newVert.Y = angle.Y * yScale; - newVert.Z = z; - this.coords.Add(newVert); - if (this.calcVertexNormals) - { - this.outerCoordIndices.Add(this.coords.Count - 1); - - if (sides < 5) - { - this.vertexNormals.Add(angles.normals[i]); - float u = angle.angle; - this.us.Add(u); - } - else - { - this.vertexNormals.Add(new Coord(angle.X, angle.Y, 0.0f)); - this.us.Add(angle.angle); - } - } - - if (hasHollow) - { - if (hollowSides == sides) - { - newVert.X *= hollow; - newVert.Y *= hollow; - newVert.Z = z; - hollowCoords.Add(newVert); - if (this.calcVertexNormals) - { - if (sides < 5) - { - hollowNormals.Add(angles.normals[i].Invert()); - } - - else - hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); - - hollowUs.Add(angle.angle * hollow); - } - } - } - else if (!simpleFace && createFaces && angle.angle > 0.0001f) - { - Face newFace = new Face(); - newFace.v1 = 0; - newFace.v2 = index; - newFace.v3 = index + 1; - - this.faces.Add(newFace); - } - index += 1; - } - - if (hasHollow) - { - hollowCoords.Reverse(); - if (this.calcVertexNormals) - { - hollowNormals.Reverse(); - hollowUs.Reverse(); - } - - if (createFaces) - { - int numOuterVerts = this.coords.Count; - int numHollowVerts = hollowCoords.Count; - int numTotalVerts = numOuterVerts + numHollowVerts; - - if (numOuterVerts == numHollowVerts) - { - Face newFace = new Face(); - - for (int coordIndex = 0; coordIndex < numOuterVerts - 1; coordIndex++) - { - newFace.v1 = coordIndex; - newFace.v2 = coordIndex + 1; - newFace.v3 = numTotalVerts - coordIndex - 1; - this.faces.Add(newFace); - - newFace.v1 = coordIndex + 1; - newFace.v2 = numTotalVerts - coordIndex - 2; - newFace.v3 = numTotalVerts - coordIndex - 1; - this.faces.Add(newFace); - } - } - else - { - if (numOuterVerts < numHollowVerts) - { - Face newFace = new Face(); - int j = 0; // j is the index for outer vertices - int maxJ = numOuterVerts - 1; - for (int i = 0; i < numHollowVerts; i++) // i is the index for inner vertices - { - if (j < maxJ) - if (angles.angles[j + 1].angle - hollowAngles.angles[i].angle < hollowAngles.angles[i].angle - angles.angles[j].angle + 0.000001f) - { - newFace.v1 = numTotalVerts - i - 1; - newFace.v2 = j; - newFace.v3 = j + 1; - - this.faces.Add(newFace); - j += 1; - } - - newFace.v1 = j; - newFace.v2 = numTotalVerts - i - 2; - newFace.v3 = numTotalVerts - i - 1; - - this.faces.Add(newFace); - } - } - else // numHollowVerts < numOuterVerts - { - Face newFace = new Face(); - int j = 0; // j is the index for inner vertices - int maxJ = numHollowVerts - 1; - for (int i = 0; i < numOuterVerts; i++) - { - if (j < maxJ) - if (hollowAngles.angles[j + 1].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[j].angle + 0.000001f) - { - newFace.v1 = i; - newFace.v2 = numTotalVerts - j - 2; - newFace.v3 = numTotalVerts - j - 1; - - this.faces.Add(newFace); - j += 1; - } - - newFace.v1 = numTotalVerts - j - 1; - newFace.v2 = i; - newFace.v3 = i + 1; - - this.faces.Add(newFace); - } - } - } - } - - if (calcVertexNormals) - { - foreach (Coord hc in hollowCoords) - { - this.coords.Add(hc); - hollowCoordIndices.Add(this.coords.Count - 1); - } - } - else - this.coords.AddRange(hollowCoords); - - if (this.calcVertexNormals) - { - this.vertexNormals.AddRange(hollowNormals); - this.us.AddRange(hollowUs); - - } - } - - if (simpleFace && createFaces) - { - if (sides == 3) - this.faces.Add(new Face(0, 1, 2)); - else if (sides == 4) - { - this.faces.Add(new Face(0, 1, 2)); - this.faces.Add(new Face(0, 2, 3)); - } - } - - if (calcVertexNormals && hasProfileCut) - { - if (hasHollow) - { - int lastOuterVertIndex = this.numOuterVerts - 1; - - this.cut1CoordIndices.Add(0); - this.cut1CoordIndices.Add(this.coords.Count - 1); - - this.cut2CoordIndices.Add(lastOuterVertIndex + 1); - this.cut2CoordIndices.Add(lastOuterVertIndex); - - this.cutNormal1.X = this.coords[0].Y - this.coords[this.coords.Count - 1].Y; - this.cutNormal1.Y = -(this.coords[0].X - this.coords[this.coords.Count - 1].X); - - this.cutNormal2.X = this.coords[lastOuterVertIndex + 1].Y - this.coords[lastOuterVertIndex].Y; - this.cutNormal2.Y = -(this.coords[lastOuterVertIndex + 1].X - this.coords[lastOuterVertIndex].X); - } - - else - { - this.cutNormal1.X = this.vertexNormals[1].Y; - this.cutNormal1.Y = -this.vertexNormals[1].X; - - this.cutNormal2.X = -this.vertexNormals[this.vertexNormals.Count - 2].Y; - this.cutNormal2.Y = this.vertexNormals[this.vertexNormals.Count - 2].X; - - } - this.cutNormal1.Normalize(); - this.cutNormal2.Normalize(); - } - - this.MakeFaceUVs(); - - hollowCoords = null; - hollowNormals = null; - hollowUs = null; - - if (calcVertexNormals) - { // calculate prim face numbers - - // face number order is top, outer, hollow, bottom, start cut, end cut - // I know it's ugly but so is the whole concept of prim face numbers - - int faceNum = 1; // start with outer faces - int startVert = hasProfileCut && !hasHollow ? 1 : 0; - if (startVert > 0) - this.faceNumbers.Add(-1); - for (int i = 0; i < numOuterVerts - 1; i++) - this.faceNumbers.Add(sides < 5 ? faceNum++ : faceNum); - - //if (!hasHollow && !hasProfileCut) - // this.bottomFaceNumber = faceNum++; - - this.faceNumbers.Add(hasProfileCut ? -1 : faceNum++); - - if (sides > 4 && (hasHollow || hasProfileCut)) - faceNum++; - - if (hasHollow) - { - for (int i = 0; i < numHollowVerts; i++) - this.faceNumbers.Add(faceNum); - - faceNum++; - } - //if (hasProfileCut || hasHollow) - // this.bottomFaceNumber = faceNum++; - this.bottomFaceNumber = faceNum++; - - if (hasHollow && hasProfileCut) - this.faceNumbers.Add(faceNum++); - for (int i = 0; i < this.faceNumbers.Count; i++) - if (this.faceNumbers[i] == -1) - this.faceNumbers[i] = faceNum++; - - - this.numPrimFaces = faceNum; - } - - } - - internal void MakeFaceUVs() - { - this.faceUVs = new List(); - foreach (Coord c in this.coords) - this.faceUVs.Add(new UVCoord(1.0f - (0.5f + c.X), 1.0f - (0.5f - c.Y))); - } - - internal Profile Copy() - { - return this.Copy(true); - } - - internal Profile Copy(bool needFaces) - { - Profile copy = new Profile(); - - copy.coords.AddRange(this.coords); - copy.faceUVs.AddRange(this.faceUVs); - - if (needFaces) - copy.faces.AddRange(this.faces); - if ((copy.calcVertexNormals = this.calcVertexNormals) == true) - { - copy.vertexNormals.AddRange(this.vertexNormals); - copy.faceNormal = this.faceNormal; - copy.cutNormal1 = this.cutNormal1; - copy.cutNormal2 = this.cutNormal2; - copy.us.AddRange(this.us); - copy.faceNumbers.AddRange(this.faceNumbers); - - copy.cut1CoordIndices = new List(this.cut1CoordIndices); - copy.cut2CoordIndices = new List(this.cut2CoordIndices); - copy.hollowCoordIndices = new List(this.hollowCoordIndices); - copy.outerCoordIndices = new List(this.outerCoordIndices); - } - copy.numOuterVerts = this.numOuterVerts; - copy.numHollowVerts = this.numHollowVerts; - - return copy; - } - - internal void AddPos(Coord v) - { - this.AddPos(v.X, v.Y, v.Z); - } - - internal void AddPos(float x, float y, float z) - { - int i; - int numVerts = this.coords.Count; - Coord vert; - - for (i = 0; i < numVerts; i++) - { - vert = this.coords[i]; - vert.X += x; - vert.Y += y; - vert.Z += z; - this.coords[i] = vert; - } - } - - internal void AddRot(Quat q) - { - int i; - int numVerts = this.coords.Count; - - for (i = 0; i < numVerts; i++) - this.coords[i] *= q; - - if (this.calcVertexNormals) - { - int numNormals = this.vertexNormals.Count; - for (i = 0; i < numNormals; i++) - this.vertexNormals[i] *= q; - - this.faceNormal *= q; - this.cutNormal1 *= q; - this.cutNormal2 *= q; - - } - } - - internal void Scale(float x, float y) - { - int i; - int numVerts = this.coords.Count; - Coord vert; - - for (i = 0; i < numVerts; i++) - { - vert = this.coords[i]; - vert.X *= x; - vert.Y *= y; - this.coords[i] = vert; - } - } - - /// - /// Changes order of the vertex indices and negates the center vertex normal. Does not alter vertex normals of radial vertices - /// - internal void FlipNormals() - { - int i; - int numFaces = this.faces.Count; - Face tmpFace; - int tmp; - - for (i = 0; i < numFaces; i++) - { - tmpFace = this.faces[i]; - tmp = tmpFace.v3; - tmpFace.v3 = tmpFace.v1; - tmpFace.v1 = tmp; - this.faces[i] = tmpFace; - } - - if (this.calcVertexNormals) - { - int normalCount = this.vertexNormals.Count; - if (normalCount > 0) - { - Coord n = this.vertexNormals[normalCount - 1]; - n.Z = -n.Z; - this.vertexNormals[normalCount - 1] = n; - } - } - - this.faceNormal.X = -this.faceNormal.X; - this.faceNormal.Y = -this.faceNormal.Y; - this.faceNormal.Z = -this.faceNormal.Z; - - int numfaceUVs = this.faceUVs.Count; - for (i = 0; i < numfaceUVs; i++) - { - UVCoord uv = this.faceUVs[i]; - uv.V = 1.0f - uv.V; - this.faceUVs[i] = uv; - } - } - - internal void AddValue2FaceVertexIndices(int num) - { - int numFaces = this.faces.Count; - Face tmpFace; - for (int i = 0; i < numFaces; i++) - { - tmpFace = this.faces[i]; - tmpFace.v1 += num; - tmpFace.v2 += num; - tmpFace.v3 += num; - - this.faces[i] = tmpFace; - } - } - - internal void AddValue2FaceNormalIndices(int num) - { - if (this.calcVertexNormals) - { - int numFaces = this.faces.Count; - Face tmpFace; - for (int i = 0; i < numFaces; i++) - { - tmpFace = this.faces[i]; - tmpFace.n1 += num; - tmpFace.n2 += num; - tmpFace.n3 += num; - - this.faces[i] = tmpFace; - } - } - } - - internal void DumpRaw(String path, String name, String title) - { - if (path == null) - return; - String fileName = name + "_" + title + ".raw"; - String completePath = System.IO.Path.Combine(path, fileName); - StreamWriter sw = new StreamWriter(completePath); - - for (int i = 0; i < this.faces.Count; i++) - { - string s = this.coords[this.faces[i].v1].ToString(); - s += " " + this.coords[this.faces[i].v2].ToString(); - s += " " + this.coords[this.faces[i].v3].ToString(); - - sw.WriteLine(s); - } - - sw.Close(); - } - } - - public struct PathNode - { - public Coord position; - public Quat rotation; - public float xScale; - public float yScale; - public float percentOfPath; - } - - public enum PathType { Linear = 0, Circular = 1, Flexible = 2 } - - public class Path - { - public List pathNodes = new List(); - - public float twistBegin = 0.0f; - public float twistEnd = 0.0f; - 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; - - private const float twoPi = 2.0f * (float)Math.PI; - - public void Create(PathType pathType, int steps) - { - if (pathType == PathType.Linear || pathType == PathType.Flexible) - { - int step = 0; - - float length = this.pathCutEnd - this.pathCutBegin; - 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 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; - - // sanity checks - - bool done = false; - - while (!done) - { - PathNode newNode = new PathNode(); - - newNode.xScale = 1.0f; - if (this.taperX == 0.0f) - newNode.xScale = 1.0f; - else if (this.taperX > 0.0f) - newNode.xScale = 1.0f - percentOfPath * this.taperX; - else newNode.xScale = 1.0f + (1.0f - percentOfPath) * this.taperX; - - newNode.yScale = 1.0f; - if (this.taperY == 0.0f) - newNode.yScale = 1.0f; - else if (this.taperY > 0.0f) - newNode.yScale = 1.0f - percentOfPath * this.taperY; - else newNode.yScale = 1.0f + (1.0f - percentOfPath) * this.taperY; - - float twist = twistBegin + twistTotal * percentOfPath; - - newNode.rotation = new Quat(new Coord(0.0f, 0.0f, 1.0f), twist); - newNode.position = new Coord(xOffset, yOffset, zOffset); - newNode.percentOfPath = percentOfPath; - - pathNodes.Add(newNode); - - if (step < steps) - { - step += 1; - percentOfPath += percentOfPathMultiplier; - xOffset += xOffsetStepIncrement; - yOffset += yOffsetStepIncrement; - zOffset += stepSize; - if (percentOfPath > this.pathCutEnd) - done = true; - } - else done = true; - } - } // end of linear path code - - else // pathType == Circular - { - 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; - - int step = (int)(startAngle / stepSize); -// int firstStep = step; - float angle = startAngle; - - bool done = false; - while (!done) // loop through the length of the path and add the layers - { - PathNode newNode = new PathNode(); - - 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; - - newNode.xScale = xProfileScale; - newNode.yScale = 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; - - newNode.position = new Coord(xOffset, yOffset, zOffset); - - // 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 - - newNode.rotation = new Quat(new Coord(1.0f, 0.0f, 0.0f), angle + this.topShearY); - - // next apply twist rotation to the profile layer - if (twistTotal != 0.0f || twistBegin != 0.0f) - newNode.rotation *= new Quat(new Coord(0.0f, 0.0f, 1.0f), twist); - - newNode.percentOfPath = percentOfPath; - - pathNodes.Add(newNode); - - // 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; - } - } - } - } - } - - public class PrimMesh - { - public string errorMessage = ""; - private const float twoPi = 2.0f * (float)Math.PI; - - public List coords; - public List normals; - public List faces; - - public List viewerFaces; - - private int sides = 4; - private int hollowSides = 4; - private float profileStart = 0.0f; - private float profileEnd = 1.0f; - private float hollow = 0.0f; - 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; - - private bool hasProfileCut = false; - private bool hasHollow = false; - public bool calcVertexNormals = false; - private bool normalsProcessed = false; - public bool viewerMode = false; - - public int numPrimFaces = 0; - - /// - /// Human readable string representation of the parameters used to create a mesh. - /// - /// - public string ParamsToDisplayString() - { - string s = ""; - s += "sides..................: " + this.sides.ToString(); - s += "\nhollowSides..........: " + this.hollowSides.ToString(); - s += "\nprofileStart.........: " + this.profileStart.ToString(); - s += "\nprofileEnd...........: " + this.profileEnd.ToString(); - s += "\nhollow...............: " + this.hollow.ToString(); - s += "\ntwistBegin...........: " + this.twistBegin.ToString(); - s += "\ntwistEnd.............: " + this.twistEnd.ToString(); - s += "\ntopShearX............: " + this.topShearX.ToString(); - s += "\ntopShearY............: " + this.topShearY.ToString(); - s += "\npathCutBegin.........: " + this.pathCutBegin.ToString(); - s += "\npathCutEnd...........: " + this.pathCutEnd.ToString(); - s += "\ndimpleBegin..........: " + this.dimpleBegin.ToString(); - s += "\ndimpleEnd............: " + this.dimpleEnd.ToString(); - s += "\nskew.................: " + this.skew.ToString(); - s += "\nholeSizeX............: " + this.holeSizeX.ToString(); - s += "\nholeSizeY............: " + this.holeSizeY.ToString(); - s += "\ntaperX...............: " + this.taperX.ToString(); - s += "\ntaperY...............: " + this.taperY.ToString(); - s += "\nradius...............: " + this.radius.ToString(); - s += "\nrevolutions..........: " + this.revolutions.ToString(); - s += "\nstepsPerRevolution...: " + this.stepsPerRevolution.ToString(); - - return s; - } - - /// - /// Constructs a PrimMesh object and creates the profile for extrusion. - /// - /// - /// - /// - /// - /// - public PrimMesh(int sides, float profileStart, float profileEnd, float hollow, int hollowSides) - { - this.coords = new List(); - this.faces = new List(); - - this.sides = sides; - this.profileStart = profileStart; - this.profileEnd = profileEnd; - this.hollow = hollow; - this.hollowSides = hollowSides; - - if (sides < 3) - this.sides = 3; - if (hollowSides < 3) - this.hollowSides = 3; - if (profileStart < 0.0f) - this.profileStart = 0.0f; - if (profileEnd > 1.0f) - this.profileEnd = 1.0f; - if (profileEnd < 0.02f) - this.profileEnd = 0.02f; - if (profileStart >= profileEnd) - this.profileStart = profileEnd - 0.02f; - if (hollow > 0.99f) - this.hollow = 0.99f; - if (hollow < 0.0f) - this.hollow = 0.0f; - - this.hasProfileCut = (this.profileStart > 0.0f || this.profileEnd < 1.0f); - this.hasHollow = (this.hollow > 0.001f); - } - - /// - /// Extrudes a profile along a path. - /// - public void Extrude(PathType pathType) - { - 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 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 hollow = this.hollow; - - // sanity checks - float initialProfileRot = 0.0f; - if (pathType == PathType.Circular) - { - 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; - } - } - } - else - { - 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; - - Path path = new Path(); - path.twistBegin = twistBegin; - path.twistEnd = twistEnd; - path.topShearX = topShearX; - path.topShearY = topShearY; - path.pathCutBegin = pathCutBegin; - path.pathCutEnd = pathCutEnd; - path.dimpleBegin = dimpleBegin; - path.dimpleEnd = dimpleEnd; - path.skew = skew; - path.holeSizeX = holeSizeX; - path.holeSizeY = holeSizeY; - path.taperX = taperX; - path.taperY = taperY; - path.radius = radius; - path.revolutions = revolutions; - path.stepsPerRevolution = stepsPerRevolution; - - path.Create(pathType, steps); - - bool needEndFaces = false; - if (pathType == PathType.Circular) - { - 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; - } - else needEndFaces = true; - - for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) - { - PathNode node = path.pathNodes[nodeIndex]; - Profile newLayer = profile.Copy(); - newLayer.Scale(node.xScale, node.yScale); - - newLayer.AddRot(node.rotation); - newLayer.AddPos(node.position); - - if (needEndFaces && nodeIndex == 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); - } - } - } // if (nodeIndex == 0) - - // 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 (node.percentOfPath < this.pathCutBegin + 0.01f || node.percentOfPath > this.pathCutEnd - 0.01f) - this.faces.AddRange(newLayer.faces); - - // fill faces between layers - - int numVerts = newLayer.coords.Count; - Face newFace = new Face(); - - if (nodeIndex > 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; - - 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 = profile.faceNumbers[whichVert]; - if (!needEndFaces) - primFaceNum -= 1; - - 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) - { - if (whichVert < profile.numOuterVerts) - { // 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; - } - else if (whichVert > profile.coords.Count - profile.numHollowVerts - 1) - { - u1 *= 2.0f; - u2 *= 2.0f; - } - } - - newViewerFace1.uv1.U = u1; - newViewerFace1.uv2.U = u1; - newViewerFace1.uv3.U = u2; - - newViewerFace1.uv1.V = 1.0f - node.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 - node.percentOfPath; - newViewerFace2.uv2.V = lastV; - newViewerFace2.uv3.V = 1.0f - node.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)) - { // looks terrible when path is twisted... need vertex normals here - 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]; - } - } - - this.viewerFaces.Add(newViewerFace1); - this.viewerFaces.Add(newViewerFace2); - - } - } - } - - lastCutNormal1 = newLayer.cutNormal1; - lastCutNormal2 = newLayer.cutNormal2; - lastV = 1.0f - node.percentOfPath; - - if (needEndFaces && nodeIndex == path.pathNodes.Count - 1 && 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); - } - } - - - } // for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) - - } - - - /// - /// 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.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.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); - Coord edge2 = new Coord(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z); - - Coord normal = Coord.Cross(edge1, edge2); - - normal.Normalize(); - - return normal; - } - - private Coord SurfaceNormal(Face face) - { - return SurfaceNormal(this.coords[face.v1], this.coords[face.v2], this.coords[face.v3]); - } - - /// - /// Calculate the surface normal for a face in the list of faces - /// - /// - /// - public Coord SurfaceNormal(int faceIndex) - { - int numFaces = this.faces.Count; - if (faceIndex < 0 || faceIndex >= numFaces) - throw new Exception("faceIndex out of range"); - - return SurfaceNormal(this.faces[faceIndex]); - } - - /// - /// Duplicates a PrimMesh object. All object properties are copied by value, including lists. - /// - /// - public PrimMesh Copy() - { - PrimMesh copy = new PrimMesh(this.sides, this.profileStart, this.profileEnd, this.hollow, this.hollowSides); - copy.twistBegin = this.twistBegin; - copy.twistEnd = this.twistEnd; - copy.topShearX = this.topShearX; - copy.topShearY = this.topShearY; - copy.pathCutBegin = this.pathCutBegin; - copy.pathCutEnd = this.pathCutEnd; - copy.dimpleBegin = this.dimpleBegin; - copy.dimpleEnd = this.dimpleEnd; - copy.skew = this.skew; - copy.holeSizeX = this.holeSizeX; - copy.holeSizeY = this.holeSizeY; - copy.taperX = this.taperX; - copy.taperY = this.taperY; - copy.radius = this.radius; - copy.revolutions = this.revolutions; - copy.stepsPerRevolution = this.stepsPerRevolution; - copy.calcVertexNormals = this.calcVertexNormals; - copy.normalsProcessed = this.normalsProcessed; - copy.viewerMode = this.viewerMode; - copy.numPrimFaces = this.numPrimFaces; - copy.errorMessage = this.errorMessage; - - copy.coords = new List(this.coords); - copy.faces = new List(this.faces); - copy.viewerFaces = new List(this.viewerFaces); - copy.normals = new List(this.normals); - - return copy; - } - - /// - /// Calculate surface normals for all of the faces in the list of faces in this mesh - /// - public void CalcNormals() - { - if (normalsProcessed) - return; - - normalsProcessed = true; - - int numFaces = faces.Count; - - if (!this.calcVertexNormals) - this.normals = new List(); - - for (int i = 0; i < numFaces; i++) - { - Face face = faces[i]; - - this.normals.Add(SurfaceNormal(i).Normalize()); - - int normIndex = normals.Count - 1; - face.n1 = normIndex; - face.n2 = normIndex; - face.n3 = normIndex; - - this.faces[i] = face; - } - } - - /// - /// Adds a value to each XYZ vertex coordinate in the mesh - /// - /// - /// - /// - public void AddPos(float x, float y, float z) - { - int i; - int numVerts = this.coords.Count; - Coord vert; - - for (i = 0; i < numVerts; i++) - { - vert = this.coords[i]; - vert.X += x; - vert.Y += y; - vert.Z += z; - this.coords[i] = vert; - } - - if (this.viewerFaces != null) - { - int numViewerFaces = this.viewerFaces.Count; - - for (i = 0; i < numViewerFaces; i++) - { - ViewerFace v = this.viewerFaces[i]; - v.AddPos(x, y, z); - this.viewerFaces[i] = v; - } - } - } - - /// - /// Rotates the mesh - /// - /// - public void AddRot(Quat q) - { - int i; - int numVerts = this.coords.Count; - - for (i = 0; i < numVerts; i++) - this.coords[i] *= q; - - if (this.normals != null) - { - int numNormals = this.normals.Count; - for (i = 0; i < numNormals; i++) - this.normals[i] *= q; - } - - if (this.viewerFaces != null) - { - int numViewerFaces = this.viewerFaces.Count; - - for (i = 0; i < numViewerFaces; i++) - { - ViewerFace v = this.viewerFaces[i]; - v.v1 *= q; - v.v2 *= q; - v.v3 *= q; - - v.n1 *= q; - v.n2 *= q; - v.n3 *= q; - this.viewerFaces[i] = v; - } - } - } - -#if VERTEX_INDEXER - public VertexIndexer GetVertexIndexer() - { - if (this.viewerMode && this.viewerFaces.Count > 0) - return new VertexIndexer(this); - return null; - } -#endif - - /// - /// Scales the mesh - /// - /// - /// - /// - public void Scale(float x, float y, float z) - { - int i; - int numVerts = this.coords.Count; - //Coord vert; - - Coord m = new Coord(x, y, z); - for (i = 0; i < numVerts; i++) - this.coords[i] *= m; - - if (this.viewerFaces != null) - { - int numViewerFaces = this.viewerFaces.Count; - for (i = 0; i < numViewerFaces; i++) - { - ViewerFace v = this.viewerFaces[i]; - v.v1 *= m; - v.v2 *= m; - v.v3 *= m; - this.viewerFaces[i] = v; - } - - } - - } - - /// - /// Dumps the mesh to a Blender compatible "Raw" format file - /// - /// - /// - /// - public void DumpRaw(String path, String name, String title) - { - if (path == null) - return; - String fileName = name + "_" + title + ".raw"; - String completePath = System.IO.Path.Combine(path, fileName); - StreamWriter sw = new StreamWriter(completePath); - - for (int i = 0; i < this.faces.Count; i++) - { - string s = this.coords[this.faces[i].v1].ToString(); - s += " " + this.coords[this.faces[i].v2].ToString(); - s += " " + this.coords[this.faces[i].v3].ToString(); - - sw.WriteLine(s); - } - - sw.Close(); - } - } -} +/* + * Copyright (c) Contributors + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace PrimMesher +{ + public struct Quat + { + /// X value + public float X; + /// Y value + public float Y; + /// Z value + public float Z; + /// W value + public float W; + + public Quat(float x, float y, float z, float w) + { + X = x; + Y = y; + Z = z; + W = w; + } + + public Quat(Coord axis, float angle) + { + axis = axis.Normalize(); + + angle *= 0.5f; + float c = (float)Math.Cos(angle); + float s = (float)Math.Sin(angle); + + X = axis.X * s; + Y = axis.Y * s; + Z = axis.Z * s; + W = c; + + Normalize(); + } + + public float Length() + { + return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W); + } + + public Quat Normalize() + { + const float MAG_THRESHOLD = 0.0000001f; + float mag = Length(); + + // Catch very small rounding errors when normalizing + if (mag > MAG_THRESHOLD) + { + float oomag = 1f / mag; + X *= oomag; + Y *= oomag; + Z *= oomag; + W *= oomag; + } + else + { + X = 0f; + Y = 0f; + Z = 0f; + W = 1f; + } + + return this; + } + + public static Quat operator *(Quat q1, Quat q2) + { + float x = q1.W * q2.X + q1.X * q2.W + q1.Y * q2.Z - q1.Z * q2.Y; + float y = q1.W * q2.Y - q1.X * q2.Z + q1.Y * q2.W + q1.Z * q2.X; + float z = q1.W * q2.Z + q1.X * q2.Y - q1.Y * q2.X + q1.Z * q2.W; + float w = q1.W * q2.W - q1.X * q2.X - q1.Y * q2.Y - q1.Z * q2.Z; + return new Quat(x, y, z, w); + } + + public override string ToString() + { + return "< X: " + this.X.ToString() + ", Y: " + this.Y.ToString() + ", Z: " + this.Z.ToString() + ", W: " + this.W.ToString() + ">"; + } + } + + public struct Coord + { + public float X; + public float Y; + public float Z; + + public Coord(float x, float y, float z) + { + this.X = x; + this.Y = y; + this.Z = z; + } + + public float Length() + { + return (float)Math.Sqrt(this.X * this.X + this.Y * this.Y + this.Z * this.Z); + } + + public Coord Invert() + { + this.X = -this.X; + this.Y = -this.Y; + this.Z = -this.Z; + + return this; + } + + public Coord Normalize() + { + const float MAG_THRESHOLD = 0.0000001f; + float mag = Length(); + + // Catch very small rounding errors when normalizing + if (mag > MAG_THRESHOLD) + { + float oomag = 1.0f / mag; + this.X *= oomag; + this.Y *= oomag; + this.Z *= oomag; + } + else + { + this.X = 0.0f; + this.Y = 0.0f; + this.Z = 0.0f; + } + + return this; + } + + public override string ToString() + { + return this.X.ToString() + " " + this.Y.ToString() + " " + this.Z.ToString(); + } + + public static Coord Cross(Coord c1, Coord c2) + { + return new Coord( + c1.Y * c2.Z - c2.Y * c1.Z, + c1.Z * c2.X - c2.Z * c1.X, + c1.X * c2.Y - c2.X * c1.Y + ); + } + + public static Coord operator +(Coord v, Coord a) + { + return new Coord(v.X + a.X, v.Y + a.Y, v.Z + a.Z); + } + + public static Coord operator *(Coord v, Coord m) + { + return new Coord(v.X * m.X, v.Y * m.Y, v.Z * m.Z); + } + + public static Coord operator *(Coord v, Quat q) + { + // From http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/ + + Coord c2 = new Coord(0.0f, 0.0f, 0.0f); + + c2.X = q.W * q.W * v.X + + 2f * q.Y * q.W * v.Z - + 2f * q.Z * q.W * v.Y + + q.X * q.X * v.X + + 2f * q.Y * q.X * v.Y + + 2f * q.Z * q.X * v.Z - + q.Z * q.Z * v.X - + q.Y * q.Y * v.X; + + c2.Y = + 2f * q.X * q.Y * v.X + + q.Y * q.Y * v.Y + + 2f * q.Z * q.Y * v.Z + + 2f * q.W * q.Z * v.X - + q.Z * q.Z * v.Y + + q.W * q.W * v.Y - + 2f * q.X * q.W * v.Z - + q.X * q.X * v.Y; + + c2.Z = + 2f * q.X * q.Z * v.X + + 2f * q.Y * q.Z * v.Y + + q.Z * q.Z * v.Z - + 2f * q.W * q.Y * v.X - + q.Y * q.Y * v.Z + + 2f * q.W * q.X * v.Y - + q.X * q.X * v.Z + + q.W * q.W * v.Z; + + return c2; + } + } + + public struct UVCoord + { + public float U; + public float V; + + + public UVCoord(float u, float v) + { + this.U = u; + this.V = v; + } + } + + public struct Face + { + public int primFace; + + // vertices + public int v1; + public int v2; + public int v3; + + //normals + public int n1; + public int n2; + public int n3; + + // uvs + public int uv1; + public int uv2; + public int uv3; + + + public Face(int v1, int v2, int v3) + { + primFace = 0; + + this.v1 = v1; + this.v2 = v2; + this.v3 = v3; + + this.n1 = 0; + this.n2 = 0; + this.n3 = 0; + + this.uv1 = 0; + this.uv2 = 0; + this.uv3 = 0; + + } + + public Face(int v1, int v2, int v3, int n1, int n2, int n3) + { + primFace = 0; + + this.v1 = v1; + this.v2 = v2; + this.v3 = v3; + + this.n1 = n1; + this.n2 = n2; + this.n3 = n3; + + this.uv1 = 0; + this.uv2 = 0; + this.uv3 = 0; + } + + public Coord SurfaceNormal(List coordList) + { + Coord c1 = coordList[this.v1]; + Coord c2 = coordList[this.v2]; + Coord c3 = coordList[this.v3]; + + Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z); + Coord edge2 = new Coord(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z); + + return Coord.Cross(edge1, edge2).Normalize(); + } + } + + public struct ViewerFace + { + public int primFaceNumber; + + public Coord v1; + public Coord v2; + public Coord v3; + + public int coordIndex1; + public int coordIndex2; + public int coordIndex3; + + public Coord n1; + public Coord n2; + public Coord n3; + + public UVCoord uv1; + public UVCoord uv2; + public UVCoord uv3; + + public ViewerFace(int primFaceNumber) + { + this.primFaceNumber = primFaceNumber; + + this.v1 = new Coord(); + this.v2 = new Coord(); + this.v3 = new Coord(); + + this.coordIndex1 = this.coordIndex2 = this.coordIndex3 = -1; // -1 means not assigned yet + + this.n1 = new Coord(); + this.n2 = new Coord(); + this.n3 = new Coord(); + + this.uv1 = new UVCoord(); + this.uv2 = new UVCoord(); + this.uv3 = new UVCoord(); + } + + public void Scale(float x, float y, float z) + { + this.v1.X *= x; + this.v1.Y *= y; + this.v1.Z *= z; + + this.v2.X *= x; + this.v2.Y *= y; + this.v2.Z *= z; + + this.v3.X *= x; + this.v3.Y *= y; + this.v3.Z *= z; + } + + public void AddPos(float x, float y, float z) + { + this.v1.X += x; + this.v2.X += x; + this.v3.X += x; + + this.v1.Y += y; + this.v2.Y += y; + this.v3.Y += y; + + this.v1.Z += z; + this.v2.Z += z; + this.v3.Z += z; + } + + public void AddRot(Quat q) + { + this.v1 *= q; + this.v2 *= q; + this.v3 *= q; + + this.n1 *= q; + this.n2 *= q; + this.n3 *= q; + } + + public void CalcSurfaceNormal() + { + + Coord edge1 = new Coord(this.v2.X - this.v1.X, this.v2.Y - this.v1.Y, this.v2.Z - this.v1.Z); + Coord edge2 = new Coord(this.v3.X - this.v1.X, this.v3.Y - this.v1.Y, this.v3.Z - this.v1.Z); + + this.n1 = this.n2 = this.n3 = Coord.Cross(edge1, edge2).Normalize(); + } + } + + internal struct Angle + { + internal float angle; + internal float X; + internal float Y; + + internal Angle(float angle, float x, float y) + { + this.angle = angle; + this.X = x; + this.Y = y; + } + } + + internal class AngleList + { + private float iX, iY; // intersection point + + private static Angle[] angles3 = + { + new Angle(0.0f, 1.0f, 0.0f), + new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), + new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f), + new Angle(1.0f, 1.0f, 0.0f) + }; + + private static Coord[] normals3 = + { + new Coord(0.25f, 0.4330127019f, 0.0f).Normalize(), + new Coord(-0.5f, 0.0f, 0.0f).Normalize(), + new Coord(0.25f, -0.4330127019f, 0.0f).Normalize(), + new Coord(0.25f, 0.4330127019f, 0.0f).Normalize() + }; + + private static Angle[] angles4 = + { + new Angle(0.0f, 1.0f, 0.0f), + new Angle(0.25f, 0.0f, 1.0f), + new Angle(0.5f, -1.0f, 0.0f), + new Angle(0.75f, 0.0f, -1.0f), + new Angle(1.0f, 1.0f, 0.0f) + }; + + private static Coord[] normals4 = + { + new Coord(0.5f, 0.5f, 0.0f).Normalize(), + new Coord(-0.5f, 0.5f, 0.0f).Normalize(), + new Coord(-0.5f, -0.5f, 0.0f).Normalize(), + new Coord(0.5f, -0.5f, 0.0f).Normalize(), + new Coord(0.5f, 0.5f, 0.0f).Normalize() + }; + + private static Angle[] angles24 = + { + new Angle(0.0f, 1.0f, 0.0f), + new Angle(0.041666666666666664f, 0.96592582628906831f, 0.25881904510252074f), + new Angle(0.083333333333333329f, 0.86602540378443871f, 0.5f), + new Angle(0.125f, 0.70710678118654757f, 0.70710678118654746f), + new Angle(0.16666666666666667f, 0.5f, 0.8660254037844386f), + new Angle(0.20833333333333331f, 0.25881904510252096f, 0.9659258262890682f), + new Angle(0.25f, 0.0f, 1.0f), + new Angle(0.29166666666666663f, -0.25881904510252063f, 0.96592582628906831f), + new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), + new Angle(0.375f, -0.70710678118654746f, 0.70710678118654757f), + new Angle(0.41666666666666663f, -0.86602540378443849f, 0.5f), + new Angle(0.45833333333333331f, -0.9659258262890682f, 0.25881904510252102f), + new Angle(0.5f, -1.0f, 0.0f), + new Angle(0.54166666666666663f, -0.96592582628906842f, -0.25881904510252035f), + new Angle(0.58333333333333326f, -0.86602540378443882f, -0.5f), + new Angle(0.62499999999999989f, -0.70710678118654791f, -0.70710678118654713f), + new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f), + new Angle(0.70833333333333326f, -0.25881904510252152f, -0.96592582628906809f), + new Angle(0.75f, 0.0f, -1.0f), + new Angle(0.79166666666666663f, 0.2588190451025203f, -0.96592582628906842f), + new Angle(0.83333333333333326f, 0.5f, -0.86602540378443904f), + new Angle(0.875f, 0.70710678118654735f, -0.70710678118654768f), + new Angle(0.91666666666666663f, 0.86602540378443837f, -0.5f), + new Angle(0.95833333333333326f, 0.96592582628906809f, -0.25881904510252157f), + new Angle(1.0f, 1.0f, 0.0f) + }; + + private Angle interpolatePoints(float newPoint, Angle p1, Angle p2) + { + float m = (newPoint - p1.angle) / (p2.angle - p1.angle); + return new Angle(newPoint, p1.X + m * (p2.X - p1.X), p1.Y + m * (p2.Y - p1.Y)); + } + + private void intersection(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) + { // ref: http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ + double denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); + double uaNumerator = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3); + + if (denom != 0.0) + { + double ua = uaNumerator / denom; + iX = (float)(x1 + ua * (x2 - x1)); + iY = (float)(y1 + ua * (y2 - y1)); + } + } + + internal List angles; + internal List normals; + + internal void makeAngles(int sides, float startAngle, float stopAngle) + { + angles = new List(); + normals = new List(); + + double twoPi = System.Math.PI * 2.0; + float twoPiInv = 1.0f / (float)twoPi; + + if (sides < 1) + throw new Exception("number of sides not greater than zero"); + if (stopAngle <= startAngle) + throw new Exception("stopAngle not greater than startAngle"); + + if ((sides == 3 || sides == 4 || sides == 24)) + { + startAngle *= twoPiInv; + stopAngle *= twoPiInv; + + Angle[] sourceAngles; + if (sides == 3) + sourceAngles = angles3; + else if (sides == 4) + sourceAngles = angles4; + else sourceAngles = angles24; + + int startAngleIndex = (int)(startAngle * sides); + int endAngleIndex = sourceAngles.Length - 1; + if (stopAngle < 1.0f) + endAngleIndex = (int)(stopAngle * sides) + 1; + if (endAngleIndex == startAngleIndex) + endAngleIndex++; + + for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex + 1; angleIndex++) + { + angles.Add(sourceAngles[angleIndex]); + if (sides == 3) + normals.Add(normals3[angleIndex]); + else if (sides == 4) + normals.Add(normals4[angleIndex]); + } + + if (startAngle > 0.0f) + angles[0] = interpolatePoints(startAngle, angles[0], angles[1]); + + if (stopAngle < 1.0f) + { + int lastAngleIndex = angles.Count - 1; + angles[lastAngleIndex] = interpolatePoints(stopAngle, angles[lastAngleIndex - 1], angles[lastAngleIndex]); + } + } + else + { + double stepSize = twoPi / sides; + + int startStep = (int)(startAngle / stepSize); + double angle = stepSize * startStep; + int step = startStep; + double stopAngleTest = stopAngle; + if (stopAngle < twoPi) + { + stopAngleTest = stepSize * ((int)(stopAngle / stepSize) + 1); + if (stopAngleTest < stopAngle) + stopAngleTest += stepSize; + if (stopAngleTest > twoPi) + stopAngleTest = twoPi; + } + + while (angle <= stopAngleTest) + { + Angle newAngle; + newAngle.angle = (float)angle; + newAngle.X = (float)System.Math.Cos(angle); + newAngle.Y = (float)System.Math.Sin(angle); + angles.Add(newAngle); + step += 1; + angle = stepSize * step; + } + + if (startAngle > angles[0].angle) + { + Angle newAngle; + intersection(angles[0].X, angles[0].Y, angles[1].X, angles[1].Y, 0.0f, 0.0f, (float)Math.Cos(startAngle), (float)Math.Sin(startAngle)); + newAngle.angle = startAngle; + newAngle.X = iX; + newAngle.Y = iY; + angles[0] = newAngle; + } + + int index = angles.Count - 1; + if (stopAngle < angles[index].angle) + { + Angle newAngle; + intersection(angles[index - 1].X, angles[index - 1].Y, angles[index].X, angles[index].Y, 0.0f, 0.0f, (float)Math.Cos(stopAngle), (float)Math.Sin(stopAngle)); + newAngle.angle = stopAngle; + newAngle.X = iX; + newAngle.Y = iY; + angles[index] = newAngle; + } + } + } + } + + /// + /// generates a profile for extrusion + /// + internal class Profile + { + private const float twoPi = 2.0f * (float)Math.PI; + + internal string errorMessage = null; + + internal List coords; + internal List faces; + internal List vertexNormals; + internal List us; + internal List faceUVs; + internal List faceNumbers; + + // use these for making individual meshes for each prim face + internal List outerCoordIndices = null; + internal List hollowCoordIndices = null; + internal List cut1CoordIndices = null; + internal List cut2CoordIndices = null; + + internal Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f); + internal Coord cutNormal1 = new Coord(); + internal Coord cutNormal2 = new Coord(); + + internal int numOuterVerts = 0; + internal int numHollowVerts = 0; + + internal bool calcVertexNormals = false; + internal int bottomFaceNumber = 0; + internal int numPrimFaces = 0; + + internal Profile() + { + this.coords = new List(); + this.faces = new List(); + this.vertexNormals = new List(); + this.us = new List(); + this.faceUVs = new List(); + this.faceNumbers = new List(); + } + + internal Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals) + { + this.calcVertexNormals = calcVertexNormals; + this.coords = new List(); + this.faces = new List(); + this.vertexNormals = new List(); + this.us = new List(); + this.faceUVs = new List(); + this.faceNumbers = new List(); + + Coord center = new Coord(0.0f, 0.0f, 0.0f); + //bool hasCenter = false; + + List hollowCoords = new List(); + List hollowNormals = new List(); + List hollowUs = new List(); + + if (calcVertexNormals) + { + this.outerCoordIndices = new List(); + this.hollowCoordIndices = new List(); + this.cut1CoordIndices = new List(); + this.cut2CoordIndices = new List(); + } + + bool hasHollow = (hollow > 0.0f); + + bool hasProfileCut = (profileStart > 0.0f || profileEnd < 1.0f); + + AngleList angles = new AngleList(); + AngleList hollowAngles = new AngleList(); + + float xScale = 0.5f; + float yScale = 0.5f; + if (sides == 4) // corners of a square are sqrt(2) from center + { + xScale = 0.707f; + yScale = 0.707f; + } + + float startAngle = profileStart * twoPi; + float stopAngle = profileEnd * twoPi; + + try { angles.makeAngles(sides, startAngle, stopAngle); } + catch (Exception ex) + { + + errorMessage = "makeAngles failed: Exception: " + ex.ToString() + + "\nsides: " + sides.ToString() + " startAngle: " + startAngle.ToString() + " stopAngle: " + stopAngle.ToString(); + + return; + } + + this.numOuterVerts = angles.angles.Count; + + // flag to create as few triangles as possible for 3 or 4 side profile + bool simpleFace = (sides < 5 && !hasHollow && !hasProfileCut); + + if (hasHollow) + { + if (sides == hollowSides) + hollowAngles = angles; + else + { + try { hollowAngles.makeAngles(hollowSides, startAngle, stopAngle); } + catch (Exception ex) + { + errorMessage = "makeAngles failed: Exception: " + ex.ToString() + + "\nsides: " + sides.ToString() + " startAngle: " + startAngle.ToString() + " stopAngle: " + stopAngle.ToString(); + + return; + } + } + this.numHollowVerts = hollowAngles.angles.Count; + } + else if (!simpleFace) + { + this.coords.Add(center); + //hasCenter = true; + if (this.calcVertexNormals) + this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f)); + this.us.Add(0.0f); + } + + float z = 0.0f; + + Angle angle; + Coord newVert = new Coord(); + if (hasHollow && hollowSides != sides) + { + int numHollowAngles = hollowAngles.angles.Count; + for (int i = 0; i < numHollowAngles; i++) + { + angle = hollowAngles.angles[i]; + newVert.X = hollow * xScale * angle.X; + newVert.Y = hollow * yScale * angle.Y; + newVert.Z = z; + + hollowCoords.Add(newVert); + if (this.calcVertexNormals) + { + if (hollowSides < 5) + hollowNormals.Add(hollowAngles.normals[i].Invert()); + else + hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); + + hollowUs.Add(angle.angle * hollow); + } + } + } + + int index = 0; + int numAngles = angles.angles.Count; + + for (int i = 0; i < numAngles; i++) + { + angle = angles.angles[i]; + newVert.X = angle.X * xScale; + newVert.Y = angle.Y * yScale; + newVert.Z = z; + this.coords.Add(newVert); + if (this.calcVertexNormals) + { + this.outerCoordIndices.Add(this.coords.Count - 1); + + if (sides < 5) + { + this.vertexNormals.Add(angles.normals[i]); + float u = angle.angle; + this.us.Add(u); + } + else + { + this.vertexNormals.Add(new Coord(angle.X, angle.Y, 0.0f)); + this.us.Add(angle.angle); + } + } + + if (hasHollow) + { + if (hollowSides == sides) + { + newVert.X *= hollow; + newVert.Y *= hollow; + newVert.Z = z; + hollowCoords.Add(newVert); + if (this.calcVertexNormals) + { + if (sides < 5) + { + hollowNormals.Add(angles.normals[i].Invert()); + } + + else + hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); + + hollowUs.Add(angle.angle * hollow); + } + } + } + else if (!simpleFace && createFaces && angle.angle > 0.0001f) + { + Face newFace = new Face(); + newFace.v1 = 0; + newFace.v2 = index; + newFace.v3 = index + 1; + + this.faces.Add(newFace); + } + index += 1; + } + + if (hasHollow) + { + hollowCoords.Reverse(); + if (this.calcVertexNormals) + { + hollowNormals.Reverse(); + hollowUs.Reverse(); + } + + if (createFaces) + { + //int numOuterVerts = this.coords.Count; + //numOuterVerts = this.coords.Count; + //int numHollowVerts = hollowCoords.Count; + int numTotalVerts = this.numOuterVerts + this.numHollowVerts; + + if (this.numOuterVerts == this.numHollowVerts) + { + Face newFace = new Face(); + + for (int coordIndex = 0; coordIndex < this.numOuterVerts - 1; coordIndex++) + { + newFace.v1 = coordIndex; + newFace.v2 = coordIndex + 1; + newFace.v3 = numTotalVerts - coordIndex - 1; + this.faces.Add(newFace); + + newFace.v1 = coordIndex + 1; + newFace.v2 = numTotalVerts - coordIndex - 2; + newFace.v3 = numTotalVerts - coordIndex - 1; + this.faces.Add(newFace); + } + } + else + { + if (this.numOuterVerts < this.numHollowVerts) + { + Face newFace = new Face(); + int j = 0; // j is the index for outer vertices + int maxJ = this.numOuterVerts - 1; + for (int i = 0; i < this.numHollowVerts; i++) // i is the index for inner vertices + { + if (j < maxJ) + if (angles.angles[j + 1].angle - hollowAngles.angles[i].angle < hollowAngles.angles[i].angle - angles.angles[j].angle + 0.000001f) + { + newFace.v1 = numTotalVerts - i - 1; + newFace.v2 = j; + newFace.v3 = j + 1; + + this.faces.Add(newFace); + j += 1; + } + + newFace.v1 = j; + newFace.v2 = numTotalVerts - i - 2; + newFace.v3 = numTotalVerts - i - 1; + + this.faces.Add(newFace); + } + } + else // numHollowVerts < numOuterVerts + { + Face newFace = new Face(); + int j = 0; // j is the index for inner vertices + int maxJ = this.numHollowVerts - 1; + for (int i = 0; i < this.numOuterVerts; i++) + { + if (j < maxJ) + if (hollowAngles.angles[j + 1].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[j].angle + 0.000001f) + { + newFace.v1 = i; + newFace.v2 = numTotalVerts - j - 2; + newFace.v3 = numTotalVerts - j - 1; + + this.faces.Add(newFace); + j += 1; + } + + newFace.v1 = numTotalVerts - j - 1; + newFace.v2 = i; + newFace.v3 = i + 1; + + this.faces.Add(newFace); + } + } + } + } + + if (calcVertexNormals) + { + foreach (Coord hc in hollowCoords) + { + this.coords.Add(hc); + hollowCoordIndices.Add(this.coords.Count - 1); + } + } + else + this.coords.AddRange(hollowCoords); + + if (this.calcVertexNormals) + { + this.vertexNormals.AddRange(hollowNormals); + this.us.AddRange(hollowUs); + + } + } + + if (simpleFace && createFaces) + { + if (sides == 3) + this.faces.Add(new Face(0, 1, 2)); + else if (sides == 4) + { + this.faces.Add(new Face(0, 1, 2)); + this.faces.Add(new Face(0, 2, 3)); + } + } + + if (calcVertexNormals && hasProfileCut) + { + if (hasHollow) + { + int lastOuterVertIndex = this.numOuterVerts - 1; + + this.cut1CoordIndices.Add(0); + this.cut1CoordIndices.Add(this.coords.Count - 1); + + this.cut2CoordIndices.Add(lastOuterVertIndex + 1); + this.cut2CoordIndices.Add(lastOuterVertIndex); + + this.cutNormal1.X = this.coords[0].Y - this.coords[this.coords.Count - 1].Y; + this.cutNormal1.Y = -(this.coords[0].X - this.coords[this.coords.Count - 1].X); + + this.cutNormal2.X = this.coords[lastOuterVertIndex + 1].Y - this.coords[lastOuterVertIndex].Y; + this.cutNormal2.Y = -(this.coords[lastOuterVertIndex + 1].X - this.coords[lastOuterVertIndex].X); + } + + else + { + this.cutNormal1.X = this.vertexNormals[1].Y; + this.cutNormal1.Y = -this.vertexNormals[1].X; + + this.cutNormal2.X = -this.vertexNormals[this.vertexNormals.Count - 2].Y; + this.cutNormal2.Y = this.vertexNormals[this.vertexNormals.Count - 2].X; + + } + this.cutNormal1.Normalize(); + this.cutNormal2.Normalize(); + } + + this.MakeFaceUVs(); + + hollowCoords = null; + hollowNormals = null; + hollowUs = null; + + if (calcVertexNormals) + { // calculate prim face numbers + + // face number order is top, outer, hollow, bottom, start cut, end cut + // I know it's ugly but so is the whole concept of prim face numbers + + int faceNum = 1; // start with outer faces + int startVert = hasProfileCut && !hasHollow ? 1 : 0; + if (startVert > 0) + this.faceNumbers.Add(-1); + for (int i = 0; i < this.numOuterVerts - 1; i++) + this.faceNumbers.Add(sides < 5 ? faceNum++ : faceNum); + + //if (!hasHollow && !hasProfileCut) + // this.bottomFaceNumber = faceNum++; + + this.faceNumbers.Add(hasProfileCut ? -1 : faceNum++); + + if (sides > 4 && (hasHollow || hasProfileCut)) + faceNum++; + + if (hasHollow) + { + for (int i = 0; i < this.numHollowVerts; i++) + this.faceNumbers.Add(faceNum); + + faceNum++; + } + //if (hasProfileCut || hasHollow) + // this.bottomFaceNumber = faceNum++; + this.bottomFaceNumber = faceNum++; + + if (hasHollow && hasProfileCut) + this.faceNumbers.Add(faceNum++); + for (int i = 0; i < this.faceNumbers.Count; i++) + if (this.faceNumbers[i] == -1) + this.faceNumbers[i] = faceNum++; + + + this.numPrimFaces = faceNum; + } + + } + + internal void MakeFaceUVs() + { + this.faceUVs = new List(); + foreach (Coord c in this.coords) + this.faceUVs.Add(new UVCoord(1.0f - (0.5f + c.X), 1.0f - (0.5f - c.Y))); + } + + internal Profile Copy() + { + return this.Copy(true); + } + + internal Profile Copy(bool needFaces) + { + Profile copy = new Profile(); + + copy.coords.AddRange(this.coords); + copy.faceUVs.AddRange(this.faceUVs); + + if (needFaces) + copy.faces.AddRange(this.faces); + if ((copy.calcVertexNormals = this.calcVertexNormals) == true) + { + copy.vertexNormals.AddRange(this.vertexNormals); + copy.faceNormal = this.faceNormal; + copy.cutNormal1 = this.cutNormal1; + copy.cutNormal2 = this.cutNormal2; + copy.us.AddRange(this.us); + copy.faceNumbers.AddRange(this.faceNumbers); + + copy.cut1CoordIndices = new List(this.cut1CoordIndices); + copy.cut2CoordIndices = new List(this.cut2CoordIndices); + copy.hollowCoordIndices = new List(this.hollowCoordIndices); + copy.outerCoordIndices = new List(this.outerCoordIndices); + } + copy.numOuterVerts = this.numOuterVerts; + copy.numHollowVerts = this.numHollowVerts; + + return copy; + } + + internal void AddPos(Coord v) + { + this.AddPos(v.X, v.Y, v.Z); + } + + internal void AddPos(float x, float y, float z) + { + int i; + int numVerts = this.coords.Count; + Coord vert; + + for (i = 0; i < numVerts; i++) + { + vert = this.coords[i]; + vert.X += x; + vert.Y += y; + vert.Z += z; + this.coords[i] = vert; + } + } + + internal void AddRot(Quat q) + { + int i; + int numVerts = this.coords.Count; + + for (i = 0; i < numVerts; i++) + this.coords[i] *= q; + + if (this.calcVertexNormals) + { + int numNormals = this.vertexNormals.Count; + for (i = 0; i < numNormals; i++) + this.vertexNormals[i] *= q; + + this.faceNormal *= q; + this.cutNormal1 *= q; + this.cutNormal2 *= q; + + } + } + + internal void Scale(float x, float y) + { + int i; + int numVerts = this.coords.Count; + Coord vert; + + for (i = 0; i < numVerts; i++) + { + vert = this.coords[i]; + vert.X *= x; + vert.Y *= y; + this.coords[i] = vert; + } + } + + /// + /// Changes order of the vertex indices and negates the center vertex normal. Does not alter vertex normals of radial vertices + /// + internal void FlipNormals() + { + int i; + int numFaces = this.faces.Count; + Face tmpFace; + int tmp; + + for (i = 0; i < numFaces; i++) + { + tmpFace = this.faces[i]; + tmp = tmpFace.v3; + tmpFace.v3 = tmpFace.v1; + tmpFace.v1 = tmp; + this.faces[i] = tmpFace; + } + + if (this.calcVertexNormals) + { + int normalCount = this.vertexNormals.Count; + if (normalCount > 0) + { + Coord n = this.vertexNormals[normalCount - 1]; + n.Z = -n.Z; + this.vertexNormals[normalCount - 1] = n; + } + } + + this.faceNormal.X = -this.faceNormal.X; + this.faceNormal.Y = -this.faceNormal.Y; + this.faceNormal.Z = -this.faceNormal.Z; + + int numfaceUVs = this.faceUVs.Count; + for (i = 0; i < numfaceUVs; i++) + { + UVCoord uv = this.faceUVs[i]; + uv.V = 1.0f - uv.V; + this.faceUVs[i] = uv; + } + } + + internal void AddValue2FaceVertexIndices(int num) + { + int numFaces = this.faces.Count; + Face tmpFace; + for (int i = 0; i < numFaces; i++) + { + tmpFace = this.faces[i]; + tmpFace.v1 += num; + tmpFace.v2 += num; + tmpFace.v3 += num; + + this.faces[i] = tmpFace; + } + } + + internal void AddValue2FaceNormalIndices(int num) + { + if (this.calcVertexNormals) + { + int numFaces = this.faces.Count; + Face tmpFace; + for (int i = 0; i < numFaces; i++) + { + tmpFace = this.faces[i]; + tmpFace.n1 += num; + tmpFace.n2 += num; + tmpFace.n3 += num; + + this.faces[i] = tmpFace; + } + } + } + + internal void DumpRaw(String path, String name, String title) + { + if (path == null) + return; + String fileName = name + "_" + title + ".raw"; + String completePath = System.IO.Path.Combine(path, fileName); + StreamWriter sw = new StreamWriter(completePath); + + for (int i = 0; i < this.faces.Count; i++) + { + string s = this.coords[this.faces[i].v1].ToString(); + s += " " + this.coords[this.faces[i].v2].ToString(); + s += " " + this.coords[this.faces[i].v3].ToString(); + + sw.WriteLine(s); + } + + sw.Close(); + } + } + + public struct PathNode + { + public Coord position; + public Quat rotation; + public float xScale; + public float yScale; + public float percentOfPath; + } + + public enum PathType { Linear = 0, Circular = 1, Flexible = 2 } + + public class Path + { + public List pathNodes = new List(); + + public float twistBegin = 0.0f; + public float twistEnd = 0.0f; + 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; + + private const float twoPi = 2.0f * (float)Math.PI; + + public void Create(PathType pathType, int steps) + { + if (pathType == PathType.Linear || pathType == PathType.Flexible) + { + int step = 0; + + float length = this.pathCutEnd - this.pathCutBegin; + 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 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; + + // sanity checks + + bool done = false; + + while (!done) + { + PathNode newNode = new PathNode(); + + newNode.xScale = 1.0f; + if (this.taperX == 0.0f) + newNode.xScale = 1.0f; + else if (this.taperX > 0.0f) + newNode.xScale = 1.0f - percentOfPath * this.taperX; + else newNode.xScale = 1.0f + (1.0f - percentOfPath) * this.taperX; + + newNode.yScale = 1.0f; + if (this.taperY == 0.0f) + newNode.yScale = 1.0f; + else if (this.taperY > 0.0f) + newNode.yScale = 1.0f - percentOfPath * this.taperY; + else newNode.yScale = 1.0f + (1.0f - percentOfPath) * this.taperY; + + float twist = twistBegin + twistTotal * percentOfPath; + + newNode.rotation = new Quat(new Coord(0.0f, 0.0f, 1.0f), twist); + newNode.position = new Coord(xOffset, yOffset, zOffset); + newNode.percentOfPath = percentOfPath; + + pathNodes.Add(newNode); + + if (step < steps) + { + step += 1; + percentOfPath += percentOfPathMultiplier; + xOffset += xOffsetStepIncrement; + yOffset += yOffsetStepIncrement; + zOffset += stepSize; + if (percentOfPath > this.pathCutEnd) + done = true; + } + else done = true; + } + } // end of linear path code + + else // pathType == Circular + { + 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; + + int step = (int)(startAngle / stepSize); + float angle = startAngle; + + bool done = false; + while (!done) // loop through the length of the path and add the layers + { + PathNode newNode = new PathNode(); + + 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; + + newNode.xScale = xProfileScale; + newNode.yScale = 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; + + newNode.position = new Coord(xOffset, yOffset, zOffset); + + // 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 + + newNode.rotation = new Quat(new Coord(1.0f, 0.0f, 0.0f), angle + this.topShearY); + + // next apply twist rotation to the profile layer + if (twistTotal != 0.0f || twistBegin != 0.0f) + newNode.rotation *= new Quat(new Coord(0.0f, 0.0f, 1.0f), twist); + + newNode.percentOfPath = percentOfPath; + + pathNodes.Add(newNode); + + // 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; + } + } + } + } + } + + public class PrimMesh + { + public string errorMessage = ""; + private const float twoPi = 2.0f * (float)Math.PI; + + public List coords; + public List normals; + public List faces; + + public List viewerFaces; + + private int sides = 4; + private int hollowSides = 4; + private float profileStart = 0.0f; + private float profileEnd = 1.0f; + private float hollow = 0.0f; + 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; + + private bool hasProfileCut = false; + private bool hasHollow = false; + public bool calcVertexNormals = false; + private bool normalsProcessed = false; + public bool viewerMode = false; + + public int numPrimFaces = 0; + + /// + /// Human readable string representation of the parameters used to create a mesh. + /// + /// + public string ParamsToDisplayString() + { + string s = ""; + s += "sides..................: " + this.sides.ToString(); + s += "\nhollowSides..........: " + this.hollowSides.ToString(); + s += "\nprofileStart.........: " + this.profileStart.ToString(); + s += "\nprofileEnd...........: " + this.profileEnd.ToString(); + s += "\nhollow...............: " + this.hollow.ToString(); + s += "\ntwistBegin...........: " + this.twistBegin.ToString(); + s += "\ntwistEnd.............: " + this.twistEnd.ToString(); + s += "\ntopShearX............: " + this.topShearX.ToString(); + s += "\ntopShearY............: " + this.topShearY.ToString(); + s += "\npathCutBegin.........: " + this.pathCutBegin.ToString(); + s += "\npathCutEnd...........: " + this.pathCutEnd.ToString(); + s += "\ndimpleBegin..........: " + this.dimpleBegin.ToString(); + s += "\ndimpleEnd............: " + this.dimpleEnd.ToString(); + s += "\nskew.................: " + this.skew.ToString(); + s += "\nholeSizeX............: " + this.holeSizeX.ToString(); + s += "\nholeSizeY............: " + this.holeSizeY.ToString(); + s += "\ntaperX...............: " + this.taperX.ToString(); + s += "\ntaperY...............: " + this.taperY.ToString(); + s += "\nradius...............: " + this.radius.ToString(); + s += "\nrevolutions..........: " + this.revolutions.ToString(); + s += "\nstepsPerRevolution...: " + this.stepsPerRevolution.ToString(); + + return s; + } + + /// + /// Constructs a PrimMesh object and creates the profile for extrusion. + /// + /// + /// + /// + /// + /// + public PrimMesh(int sides, float profileStart, float profileEnd, float hollow, int hollowSides) + { + this.coords = new List(); + this.faces = new List(); + + this.sides = sides; + this.profileStart = profileStart; + this.profileEnd = profileEnd; + this.hollow = hollow; + this.hollowSides = hollowSides; + + if (sides < 3) + this.sides = 3; + if (hollowSides < 3) + this.hollowSides = 3; + if (profileStart < 0.0f) + this.profileStart = 0.0f; + if (profileEnd > 1.0f) + this.profileEnd = 1.0f; + if (profileEnd < 0.02f) + this.profileEnd = 0.02f; + if (profileStart >= profileEnd) + this.profileStart = profileEnd - 0.02f; + if (hollow > 0.99f) + this.hollow = 0.99f; + if (hollow < 0.0f) + this.hollow = 0.0f; + + this.hasProfileCut = (this.profileStart > 0.0f || this.profileEnd < 1.0f); + this.hasHollow = (this.hollow > 0.001f); + } + + /// + /// Extrudes a profile along a path. + /// + public void Extrude(PathType pathType) + { + 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 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 hollow = this.hollow; + + // sanity checks + float initialProfileRot = 0.0f; + if (pathType == PathType.Circular) + { + 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; + } + } + } + else + { + 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; + + Path path = new Path(); + path.twistBegin = twistBegin; + path.twistEnd = twistEnd; + path.topShearX = topShearX; + path.topShearY = topShearY; + path.pathCutBegin = pathCutBegin; + path.pathCutEnd = pathCutEnd; + path.dimpleBegin = dimpleBegin; + path.dimpleEnd = dimpleEnd; + path.skew = skew; + path.holeSizeX = holeSizeX; + path.holeSizeY = holeSizeY; + path.taperX = taperX; + path.taperY = taperY; + path.radius = radius; + path.revolutions = revolutions; + path.stepsPerRevolution = stepsPerRevolution; + + path.Create(pathType, steps); + + bool needEndFaces = false; + if (pathType == PathType.Circular) + { + 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; + } + else needEndFaces = true; + + for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) + { + PathNode node = path.pathNodes[nodeIndex]; + Profile newLayer = profile.Copy(); + newLayer.Scale(node.xScale, node.yScale); + + newLayer.AddRot(node.rotation); + newLayer.AddPos(node.position); + + if (needEndFaces && nodeIndex == 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); + } + } + } // if (nodeIndex == 0) + + // append this layer + + 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 (node.percentOfPath < this.pathCutBegin + 0.01f || node.percentOfPath > this.pathCutEnd - 0.01f) + this.faces.AddRange(newLayer.faces); + + // fill faces between layers + + int numVerts = newLayer.coords.Count; + Face newFace = new Face(); + + if (nodeIndex > 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; + + 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 = profile.faceNumbers[whichVert]; + if (!needEndFaces) + primFaceNum -= 1; + + 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) + { + if (whichVert < profile.numOuterVerts) + { // 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; + } + else if (whichVert > profile.coords.Count - profile.numHollowVerts - 1) + { + u1 *= 2.0f; + u2 *= 2.0f; + } + } + + newViewerFace1.uv1.U = u1; + newViewerFace1.uv2.U = u1; + newViewerFace1.uv3.U = u2; + + newViewerFace1.uv1.V = 1.0f - node.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 - node.percentOfPath; + newViewerFace2.uv2.V = lastV; + newViewerFace2.uv3.V = 1.0f - node.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)) + { // looks terrible when path is twisted... need vertex normals here + 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]; + } + } + + this.viewerFaces.Add(newViewerFace1); + this.viewerFaces.Add(newViewerFace2); + + } + } + } + + lastCutNormal1 = newLayer.cutNormal1; + lastCutNormal2 = newLayer.cutNormal2; + lastV = 1.0f - node.percentOfPath; + + if (needEndFaces && nodeIndex == path.pathNodes.Count - 1 && 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); + } + } + + + } // for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) + + } + + + /// + /// 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.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.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); + Coord edge2 = new Coord(c3.X - c1.X, c3.Y - c1.Y, c3.Z - c1.Z); + + Coord normal = Coord.Cross(edge1, edge2); + + normal.Normalize(); + + return normal; + } + + private Coord SurfaceNormal(Face face) + { + return SurfaceNormal(this.coords[face.v1], this.coords[face.v2], this.coords[face.v3]); + } + + /// + /// Calculate the surface normal for a face in the list of faces + /// + /// + /// + public Coord SurfaceNormal(int faceIndex) + { + int numFaces = this.faces.Count; + if (faceIndex < 0 || faceIndex >= numFaces) + throw new Exception("faceIndex out of range"); + + return SurfaceNormal(this.faces[faceIndex]); + } + + /// + /// Duplicates a PrimMesh object. All object properties are copied by value, including lists. + /// + /// + public PrimMesh Copy() + { + PrimMesh copy = new PrimMesh(this.sides, this.profileStart, this.profileEnd, this.hollow, this.hollowSides); + copy.twistBegin = this.twistBegin; + copy.twistEnd = this.twistEnd; + copy.topShearX = this.topShearX; + copy.topShearY = this.topShearY; + copy.pathCutBegin = this.pathCutBegin; + copy.pathCutEnd = this.pathCutEnd; + copy.dimpleBegin = this.dimpleBegin; + copy.dimpleEnd = this.dimpleEnd; + copy.skew = this.skew; + copy.holeSizeX = this.holeSizeX; + copy.holeSizeY = this.holeSizeY; + copy.taperX = this.taperX; + copy.taperY = this.taperY; + copy.radius = this.radius; + copy.revolutions = this.revolutions; + copy.stepsPerRevolution = this.stepsPerRevolution; + copy.calcVertexNormals = this.calcVertexNormals; + copy.normalsProcessed = this.normalsProcessed; + copy.viewerMode = this.viewerMode; + copy.numPrimFaces = this.numPrimFaces; + copy.errorMessage = this.errorMessage; + + copy.coords = new List(this.coords); + copy.faces = new List(this.faces); + copy.viewerFaces = new List(this.viewerFaces); + copy.normals = new List(this.normals); + + return copy; + } + + /// + /// Calculate surface normals for all of the faces in the list of faces in this mesh + /// + public void CalcNormals() + { + if (normalsProcessed) + return; + + normalsProcessed = true; + + int numFaces = faces.Count; + + if (!this.calcVertexNormals) + this.normals = new List(); + + for (int i = 0; i < numFaces; i++) + { + Face face = faces[i]; + + this.normals.Add(SurfaceNormal(i).Normalize()); + + int normIndex = normals.Count - 1; + face.n1 = normIndex; + face.n2 = normIndex; + face.n3 = normIndex; + + this.faces[i] = face; + } + } + + /// + /// Adds a value to each XYZ vertex coordinate in the mesh + /// + /// + /// + /// + public void AddPos(float x, float y, float z) + { + int i; + int numVerts = this.coords.Count; + Coord vert; + + for (i = 0; i < numVerts; i++) + { + vert = this.coords[i]; + vert.X += x; + vert.Y += y; + vert.Z += z; + this.coords[i] = vert; + } + + if (this.viewerFaces != null) + { + int numViewerFaces = this.viewerFaces.Count; + + for (i = 0; i < numViewerFaces; i++) + { + ViewerFace v = this.viewerFaces[i]; + v.AddPos(x, y, z); + this.viewerFaces[i] = v; + } + } + } + + /// + /// Rotates the mesh + /// + /// + public void AddRot(Quat q) + { + int i; + int numVerts = this.coords.Count; + + for (i = 0; i < numVerts; i++) + this.coords[i] *= q; + + if (this.normals != null) + { + int numNormals = this.normals.Count; + for (i = 0; i < numNormals; i++) + this.normals[i] *= q; + } + + if (this.viewerFaces != null) + { + int numViewerFaces = this.viewerFaces.Count; + + for (i = 0; i < numViewerFaces; i++) + { + ViewerFace v = this.viewerFaces[i]; + v.v1 *= q; + v.v2 *= q; + v.v3 *= q; + + v.n1 *= q; + v.n2 *= q; + v.n3 *= q; + this.viewerFaces[i] = v; + } + } + } + +#if VERTEX_INDEXER + public VertexIndexer GetVertexIndexer() + { + if (this.viewerMode && this.viewerFaces.Count > 0) + return new VertexIndexer(this); + return null; + } +#endif + + /// + /// Scales the mesh + /// + /// + /// + /// + public void Scale(float x, float y, float z) + { + int i; + int numVerts = this.coords.Count; + //Coord vert; + + Coord m = new Coord(x, y, z); + for (i = 0; i < numVerts; i++) + this.coords[i] *= m; + + if (this.viewerFaces != null) + { + int numViewerFaces = this.viewerFaces.Count; + for (i = 0; i < numViewerFaces; i++) + { + ViewerFace v = this.viewerFaces[i]; + v.v1 *= m; + v.v2 *= m; + v.v3 *= m; + this.viewerFaces[i] = v; + } + + } + + } + + /// + /// Dumps the mesh to a Blender compatible "Raw" format file + /// + /// + /// + /// + public void DumpRaw(String path, String name, String title) + { + if (path == null) + return; + String fileName = name + "_" + title + ".raw"; + String completePath = System.IO.Path.Combine(path, fileName); + StreamWriter sw = new StreamWriter(completePath); + + for (int i = 0; i < this.faces.Count; i++) + { + string s = this.coords[this.faces[i].v1].ToString(); + s += " " + this.coords[this.faces[i].v2].ToString(); + s += " " + this.coords[this.faces[i].v3].ToString(); + + sw.WriteLine(s); + } + + sw.Close(); + } + } +} -- cgit v1.1 From 2ebc4be99d20269dd3cc261022f5f760b54fde6c Mon Sep 17 00:00:00 2001 From: dahlia Date: Sat, 13 Mar 2010 12:04:49 -0800 Subject: add a null check in ScenePresence constructor --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 317c908..6f16ff3 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -676,7 +676,8 @@ namespace OpenSim.Region.Framework.Scenes UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); - m_userLevel = account.UserLevel; + if (account != null) + m_userLevel = account.UserLevel; IGroupsModule gm = m_scene.RequestModuleInterface(); if (gm != null) -- cgit v1.1 From 1e73e16fd0743ae193c59d7ba353158d30874784 Mon Sep 17 00:00:00 2001 From: dahlia Date: Sat, 13 Mar 2010 18:41:36 -0800 Subject: flip UVs for profile faces --- OpenSim/Region/Physics/Meshing/PrimMesher.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Physics/Meshing/PrimMesher.cs b/OpenSim/Region/Physics/Meshing/PrimMesher.cs index b75e271..6e9654b 100644 --- a/OpenSim/Region/Physics/Meshing/PrimMesher.cs +++ b/OpenSim/Region/Physics/Meshing/PrimMesher.cs @@ -1020,7 +1020,7 @@ namespace PrimMesher { this.faceUVs = new List(); foreach (Coord c in this.coords) - this.faceUVs.Add(new UVCoord(1.0f - (0.5f + c.X), 1.0f - (0.5f - c.Y))); + this.faceUVs.Add(new UVCoord(0.5f + c.X, 0.5f - c.Y)); } internal Profile Copy() -- cgit v1.1