From 518a8b9f2ac09a5060e2e59c913dfbe7faf397ef Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Tue, 25 Nov 2008 16:00:55 +0000 Subject: Update svn properties. --- OpenSim/Region/Environment/Scenes/EntityManager.cs | 364 +++++----- .../Environment/Scenes/Hypergrid/HGAssetMapper.cs | 754 ++++++++++----------- .../Scenes/Hypergrid/HGScene.Inventory.cs | 304 ++++----- .../Region/Environment/Scenes/Hypergrid/HGScene.cs | 156 ++--- .../Hypergrid/HGSceneCommunicationService.cs | 526 +++++++------- 5 files changed, 1052 insertions(+), 1052 deletions(-) (limited to 'OpenSim/Region/Environment/Scenes') diff --git a/OpenSim/Region/Environment/Scenes/EntityManager.cs b/OpenSim/Region/Environment/Scenes/EntityManager.cs index be39878..eb29ead 100644 --- a/OpenSim/Region/Environment/Scenes/EntityManager.cs +++ b/OpenSim/Region/Environment/Scenes/EntityManager.cs @@ -1,182 +1,182 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using OpenMetaverse; - -namespace OpenSim.Region.Environment.Scenes -{ - public class EntityManager : IEnumerable - { - private readonly Dictionary m_eb_uuid = new Dictionary(); - private readonly Dictionary m_eb_localID = new Dictionary(); - private readonly Object m_lock = new Object(); - - [Obsolete("Use Add() instead.")] - public void Add(UUID id, EntityBase eb) - { - Add(eb); - } - - public void Add(EntityBase entity) - { - lock(m_lock) - { - m_eb_uuid.Add(entity.UUID, entity); - m_eb_localID.Add(entity.LocalId, entity); - } - } - - public void InsertOrReplace(EntityBase entity) - { - lock(m_lock) - { - m_eb_uuid[entity.UUID] = entity; - m_eb_localID[entity.LocalId] = entity; - } - } - - public void Clear() - { - lock (m_lock) - { - m_eb_uuid.Clear(); - m_eb_localID.Clear(); - } - } - - public int Count - { - get - { - lock (m_lock) - { - return m_eb_uuid.Count; - } - } - } - - public bool ContainsKey(UUID id) - { - lock(m_lock) - { - return m_eb_uuid.ContainsKey(id); - } - } - - public bool ContainsKey(uint localID) - { - lock (m_lock) - { - return m_eb_localID.ContainsKey(localID); - } - } - - public bool Remove(uint localID) - { - lock(m_lock) - { - bool a = m_eb_uuid.Remove(m_eb_localID[localID].UUID); - bool b = m_eb_localID.Remove(localID); - - return a && b; - } - } - - public bool Remove(UUID id) - { - lock(m_lock) - { - bool a = m_eb_localID.Remove(m_eb_uuid[id].LocalId); - bool b = m_eb_uuid.Remove(id); - - return a && b; - } - } - - public List GetAllByType() - { - List tmp = new List(); - - lock(m_lock) - { - foreach (KeyValuePair pair in m_eb_uuid) - { - if(pair.Value is T) - { - tmp.Add(pair.Value); - } - } - } - - return tmp; - } - - public List GetEntities() - { - lock (m_lock) - { - return new List(m_eb_uuid.Values); - } - } - - public EntityBase this[UUID id] - { - get - { - lock (m_lock) - { - return m_eb_uuid[id]; - } - } - set - { - InsertOrReplace(value); - } - } - - public EntityBase this[uint localID] - { - get - { - lock (m_lock) - { - return m_eb_localID[localID]; - } - } - set - { - InsertOrReplace(value); - } - } - - public bool TryGetValue(UUID key, out EntityBase obj) - { - lock(m_lock) - { - return m_eb_uuid.TryGetValue(key, out obj); - } - } - - public bool TryGetValue(uint key, out EntityBase obj) - { - lock (m_lock) - { - return m_eb_localID.TryGetValue(key, out obj); - } - } - - /// - /// This could be optimised to work on the list 'live' rather than making a safe copy and iterating that. - /// - /// - public IEnumerator GetEnumerator() - { - return GetEntities().GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} +using System; +using System.Collections; +using System.Collections.Generic; +using OpenMetaverse; + +namespace OpenSim.Region.Environment.Scenes +{ + public class EntityManager : IEnumerable + { + private readonly Dictionary m_eb_uuid = new Dictionary(); + private readonly Dictionary m_eb_localID = new Dictionary(); + private readonly Object m_lock = new Object(); + + [Obsolete("Use Add() instead.")] + public void Add(UUID id, EntityBase eb) + { + Add(eb); + } + + public void Add(EntityBase entity) + { + lock(m_lock) + { + m_eb_uuid.Add(entity.UUID, entity); + m_eb_localID.Add(entity.LocalId, entity); + } + } + + public void InsertOrReplace(EntityBase entity) + { + lock(m_lock) + { + m_eb_uuid[entity.UUID] = entity; + m_eb_localID[entity.LocalId] = entity; + } + } + + public void Clear() + { + lock (m_lock) + { + m_eb_uuid.Clear(); + m_eb_localID.Clear(); + } + } + + public int Count + { + get + { + lock (m_lock) + { + return m_eb_uuid.Count; + } + } + } + + public bool ContainsKey(UUID id) + { + lock(m_lock) + { + return m_eb_uuid.ContainsKey(id); + } + } + + public bool ContainsKey(uint localID) + { + lock (m_lock) + { + return m_eb_localID.ContainsKey(localID); + } + } + + public bool Remove(uint localID) + { + lock(m_lock) + { + bool a = m_eb_uuid.Remove(m_eb_localID[localID].UUID); + bool b = m_eb_localID.Remove(localID); + + return a && b; + } + } + + public bool Remove(UUID id) + { + lock(m_lock) + { + bool a = m_eb_localID.Remove(m_eb_uuid[id].LocalId); + bool b = m_eb_uuid.Remove(id); + + return a && b; + } + } + + public List GetAllByType() + { + List tmp = new List(); + + lock(m_lock) + { + foreach (KeyValuePair pair in m_eb_uuid) + { + if(pair.Value is T) + { + tmp.Add(pair.Value); + } + } + } + + return tmp; + } + + public List GetEntities() + { + lock (m_lock) + { + return new List(m_eb_uuid.Values); + } + } + + public EntityBase this[UUID id] + { + get + { + lock (m_lock) + { + return m_eb_uuid[id]; + } + } + set + { + InsertOrReplace(value); + } + } + + public EntityBase this[uint localID] + { + get + { + lock (m_lock) + { + return m_eb_localID[localID]; + } + } + set + { + InsertOrReplace(value); + } + } + + public bool TryGetValue(UUID key, out EntityBase obj) + { + lock(m_lock) + { + return m_eb_uuid.TryGetValue(key, out obj); + } + } + + public bool TryGetValue(uint key, out EntityBase obj) + { + lock (m_lock) + { + return m_eb_localID.TryGetValue(key, out obj); + } + } + + /// + /// This could be optimised to work on the list 'live' rather than making a safe copy and iterating that. + /// + /// + public IEnumerator GetEnumerator() + { + return GetEntities().GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGAssetMapper.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGAssetMapper.cs index 1715ffe..889c77e 100644 --- a/OpenSim/Region/Environment/Scenes/Hypergrid/HGAssetMapper.cs +++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGAssetMapper.cs @@ -1,377 +1,377 @@ -/** - * Copyright (c) 2008, Contributors. All rights reserved. - * 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 Organizations nor the names of Individual - * Contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR 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.Reflection; -using System.Threading; - -using log4net; -using Nini.Config; -using OpenMetaverse; - -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Framework.Communications.Cache; -using OpenSim.Framework.Servers; -using OpenSim.Region.Environment; -using OpenSim.Region.Environment.Scenes; - -//using HyperGrid.Framework; -//using OpenSim.Region.Communications.Hypergrid; - -namespace OpenSim.Region.Environment.Scenes.Hypergrid -{ - public class HGAssetMapper - { - #region Fields - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - // This maps between asset server URLs and asset server clients - private Dictionary m_assetServers = new Dictionary(); - - // This maps between asset UUIDs and asset servers - private Dictionary m_assetMap = new Dictionary(); - - private Scene m_scene; - #endregion - - #region Constructor - - public HGAssetMapper(Scene scene) - { - m_scene = scene; - } - - #endregion - - #region Internal functions - - private string UserAssetURL(UUID userID) - { - CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID); - if (uinfo != null) - return (uinfo.UserProfile.UserAssetURI == "") ? null : uinfo.UserProfile.UserAssetURI; - return null; - } - - private bool IsHomeUser(UUID userID) - { - CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID); - - if (uinfo != null) - { - //if ((uinfo.UserProfile.UserAssetURI == null) || (uinfo.UserProfile.UserAssetURI == "") || - // uinfo.UserProfile.UserAssetURI.Equals(m_scene.CommsManager.NetworkServersInfo.AssetURL)) - if (HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile.UserAssetURI)) - { - m_log.Debug("[HGScene]: Home user " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName); - return true; - } - } - - m_log.Debug("[HGScene]: Foreign user " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName); - return false; - } - - private bool IsInAssetMap(UUID uuid) - { - return m_assetMap.ContainsKey(uuid); - } - - private bool FetchAsset(GridAssetClient asscli, UUID assetID, bool isTexture) - { - // I'm not going over 3 seconds since this will be blocking processing of all the other inbound - // packets from the client. - int pollPeriod = 200; - int maxPolls = 15; - - AssetBase asset; - - // Maybe it came late, and it's already here. Check first. - if (m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset)) - { - m_log.Debug("[HGScene]: Asset already in asset cache. " + assetID); - return true; - } - - - asscli.RequestAsset(assetID, isTexture); - - do - { - Thread.Sleep(pollPeriod); - - if (m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset) && (asset != null)) - { - m_log.Debug("[HGScene]: Asset made it to asset cache. " + asset.Name + " " + assetID); - // I think I need to store it in the asset DB too. - // For now, let me just do it for textures and scripts - if (((AssetType)asset.Type == AssetType.Texture) || - ((AssetType)asset.Type == AssetType.LSLBytecode) || - ((AssetType)asset.Type == AssetType.LSLText)) - { - AssetBase asset1 = new AssetBase(); - Copy(asset, asset1); - m_scene.AssetCache.AssetServer.StoreAsset(asset1); - } - return true; - } - } while (--maxPolls > 0); - - m_log.WarnFormat("[HGScene]: {0} {1} was not received before the retrieval timeout was reached", - isTexture ? "texture" : "asset", assetID.ToString()); - - return false; - } - - private bool PostAsset(GridAssetClient asscli, UUID assetID) - { - AssetBase asset1; - m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset1); - - if (asset1 != null) - { - // See long comment in AssetCache.AddAsset - if (!asset1.Temporary || asset1.Local) - { - // The asset cache returns instances of subclasses of AssetBase: - // TextureImage or AssetInfo. So in passing them to the remote - // server we first need to convert this to instances of AssetBase, - // which is the serializable class for assets. - AssetBase asset = new AssetBase(); - Copy(asset1, asset); - - asscli.StoreAsset(asset); - } - return true; - } - else - m_log.Warn("[HGScene]: Tried to post asset to remote server, but asset not in local cache."); - - return false; - } - - private void Copy(AssetBase from, AssetBase to) - { - to.Data = from.Data; - to.Description = from.Description; - to.FullID = from.FullID; - to.ID = from.ID; - to.Local = from.Local; - to.Name = from.Name; - to.Temporary = from.Temporary; - to.Type = from.Type; - - } - - private void _guardedAdd(Dictionary lst, UUID obj, bool val) - { - if (!lst.ContainsKey(obj)) - lst.Add(obj, val); - } - - private void SniffTextureUUIDs(Dictionary uuids, SceneObjectGroup sog) - { - try - { - _guardedAdd(uuids, sog.RootPart.Shape.Textures.DefaultTexture.TextureID, true); - } - catch (Exception) { } - - foreach (Primitive.TextureEntryFace tface in sog.RootPart.Shape.Textures.FaceTextures) - { - try - { - _guardedAdd(uuids, tface.TextureID, true); - } - catch (Exception) { } - } - - foreach (SceneObjectPart sop in sog.Children.Values) - { - try - { - _guardedAdd(uuids, sop.Shape.Textures.DefaultTexture.TextureID, true); - } - catch (Exception) { } - foreach (Primitive.TextureEntryFace tface in sop.Shape.Textures.FaceTextures) - { - try - { - _guardedAdd(uuids, tface.TextureID, true); - } - catch (Exception) { } - } - } - } - - private void SniffTaskInventoryUUIDs(Dictionary uuids, SceneObjectGroup sog) - { - TaskInventoryDictionary tinv = sog.RootPart.TaskInventory; - - foreach (TaskInventoryItem titem in tinv.Values) - { - uuids.Add(titem.AssetID, (InventoryType)titem.Type == InventoryType.Texture); - } - } - - private Dictionary SniffUUIDs(AssetBase asset) - { - Dictionary uuids = new Dictionary(); - if ((asset != null) && ((AssetType)asset.Type == AssetType.Object)) - { - string ass_str = Utils.BytesToString(asset.Data); - SceneObjectGroup sog = new SceneObjectGroup(ass_str, true); - - SniffTextureUUIDs(uuids, sog); - - // We need to sniff further... - SniffTaskInventoryUUIDs(uuids, sog); - - } - - return uuids; - } - - private Dictionary SniffUUIDs(UUID assetID) - { - //Dictionary uuids = new Dictionary(); - - AssetBase asset; - m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset); - - return SniffUUIDs(asset); - } - - private void Dump(Dictionary lst) - { - m_log.Debug("XXX -------- UUID DUMP ------- XXX"); - foreach (KeyValuePair kvp in lst) - m_log.Debug(" >> " + kvp.Key + " (texture? " + kvp.Value + ")"); - m_log.Debug("XXX -------- UUID DUMP ------- XXX"); - } - - #endregion - - - #region Public interface - - public void Get(UUID itemID, UUID ownerID) - { - if (!IsInAssetMap(itemID) && !IsHomeUser(ownerID)) - { - // Get the item from the remote asset server onto the local AssetCache - // and place an entry in m_assetMap - - GridAssetClient asscli = null; - string userAssetURL = UserAssetURL(ownerID); - if (userAssetURL != null) - { - m_assetServers.TryGetValue(userAssetURL, out asscli); - if (asscli == null) - { - m_log.Debug("[HGScene]: Starting new GridAssetClient for " + userAssetURL); - asscli = new GridAssetClient(userAssetURL); - asscli.SetReceiver(m_scene.CommsManager.AssetCache); // Straight to the asset cache! - m_assetServers.Add(userAssetURL, asscli); - } - - m_log.Debug("[HGScene]: Fetching object " + itemID + " to asset server " + userAssetURL); - bool success = FetchAsset(asscli, itemID, false); // asscli.RequestAsset(item.ItemID, false); - - // OK, now fetch the inside. - Dictionary ids = SniffUUIDs(itemID); - Dump(ids); - foreach (KeyValuePair kvp in ids) - FetchAsset(asscli, kvp.Key, kvp.Value); - - - if (success) - { - m_log.Debug("[HGScene]: Successfully fetched item from remote asset server " + userAssetURL); - m_assetMap.Add(itemID, asscli); - } - else - m_log.Warn("[HGScene]: Could not fetch asset from remote asset server " + userAssetURL); - } - else - m_log.Warn("[HGScene]: Unable to locate foreign user's asset server"); - } - } - - public void Post(UUID itemID, UUID ownerID) - { - if (!IsHomeUser(ownerID)) - { - // Post the item from the local AssetCache ontp the remote asset server - // and place an entry in m_assetMap - - GridAssetClient asscli = null; - string userAssetURL = UserAssetURL(ownerID); - if (userAssetURL != null) - { - m_assetServers.TryGetValue(userAssetURL, out asscli); - if (asscli == null) - { - m_log.Debug("[HGScene]: Starting new GridAssetClient for " + userAssetURL); - asscli = new GridAssetClient(userAssetURL); - asscli.SetReceiver(m_scene.CommsManager.AssetCache); // Straight to the asset cache! - m_assetServers.Add(userAssetURL, asscli); - } - m_log.Debug("[HGScene]: Posting object " + itemID + " to asset server " + userAssetURL); - bool success = PostAsset(asscli, itemID); - - // Now the inside - Dictionary ids = SniffUUIDs(itemID); - Dump(ids); - foreach (KeyValuePair kvp in ids) - PostAsset(asscli, kvp.Key); - - if (success) - { - m_log.Debug("[HGScene]: Successfully posted item to remote asset server " + userAssetURL); - m_assetMap.Add(itemID, asscli); - } - else - m_log.Warn("[HGScene]: Could not post asset to remote asset server " + userAssetURL); - - //if (!m_assetMap.ContainsKey(itemID)) - // m_assetMap.Add(itemID, asscli); - } - else - m_log.Warn("[HGScene]: Unable to locate foreign user's asset server"); - - } - } - - #endregion - - } -} +/** + * Copyright (c) 2008, Contributors. All rights reserved. + * 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 Organizations nor the names of Individual + * Contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR 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.Reflection; +using System.Threading; + +using log4net; +using Nini.Config; +using OpenMetaverse; + +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Communications.Cache; +using OpenSim.Framework.Servers; +using OpenSim.Region.Environment; +using OpenSim.Region.Environment.Scenes; + +//using HyperGrid.Framework; +//using OpenSim.Region.Communications.Hypergrid; + +namespace OpenSim.Region.Environment.Scenes.Hypergrid +{ + public class HGAssetMapper + { + #region Fields + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + // This maps between asset server URLs and asset server clients + private Dictionary m_assetServers = new Dictionary(); + + // This maps between asset UUIDs and asset servers + private Dictionary m_assetMap = new Dictionary(); + + private Scene m_scene; + #endregion + + #region Constructor + + public HGAssetMapper(Scene scene) + { + m_scene = scene; + } + + #endregion + + #region Internal functions + + private string UserAssetURL(UUID userID) + { + CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID); + if (uinfo != null) + return (uinfo.UserProfile.UserAssetURI == "") ? null : uinfo.UserProfile.UserAssetURI; + return null; + } + + private bool IsHomeUser(UUID userID) + { + CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID); + + if (uinfo != null) + { + //if ((uinfo.UserProfile.UserAssetURI == null) || (uinfo.UserProfile.UserAssetURI == "") || + // uinfo.UserProfile.UserAssetURI.Equals(m_scene.CommsManager.NetworkServersInfo.AssetURL)) + if (HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile.UserAssetURI)) + { + m_log.Debug("[HGScene]: Home user " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName); + return true; + } + } + + m_log.Debug("[HGScene]: Foreign user " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName); + return false; + } + + private bool IsInAssetMap(UUID uuid) + { + return m_assetMap.ContainsKey(uuid); + } + + private bool FetchAsset(GridAssetClient asscli, UUID assetID, bool isTexture) + { + // I'm not going over 3 seconds since this will be blocking processing of all the other inbound + // packets from the client. + int pollPeriod = 200; + int maxPolls = 15; + + AssetBase asset; + + // Maybe it came late, and it's already here. Check first. + if (m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset)) + { + m_log.Debug("[HGScene]: Asset already in asset cache. " + assetID); + return true; + } + + + asscli.RequestAsset(assetID, isTexture); + + do + { + Thread.Sleep(pollPeriod); + + if (m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset) && (asset != null)) + { + m_log.Debug("[HGScene]: Asset made it to asset cache. " + asset.Name + " " + assetID); + // I think I need to store it in the asset DB too. + // For now, let me just do it for textures and scripts + if (((AssetType)asset.Type == AssetType.Texture) || + ((AssetType)asset.Type == AssetType.LSLBytecode) || + ((AssetType)asset.Type == AssetType.LSLText)) + { + AssetBase asset1 = new AssetBase(); + Copy(asset, asset1); + m_scene.AssetCache.AssetServer.StoreAsset(asset1); + } + return true; + } + } while (--maxPolls > 0); + + m_log.WarnFormat("[HGScene]: {0} {1} was not received before the retrieval timeout was reached", + isTexture ? "texture" : "asset", assetID.ToString()); + + return false; + } + + private bool PostAsset(GridAssetClient asscli, UUID assetID) + { + AssetBase asset1; + m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset1); + + if (asset1 != null) + { + // See long comment in AssetCache.AddAsset + if (!asset1.Temporary || asset1.Local) + { + // The asset cache returns instances of subclasses of AssetBase: + // TextureImage or AssetInfo. So in passing them to the remote + // server we first need to convert this to instances of AssetBase, + // which is the serializable class for assets. + AssetBase asset = new AssetBase(); + Copy(asset1, asset); + + asscli.StoreAsset(asset); + } + return true; + } + else + m_log.Warn("[HGScene]: Tried to post asset to remote server, but asset not in local cache."); + + return false; + } + + private void Copy(AssetBase from, AssetBase to) + { + to.Data = from.Data; + to.Description = from.Description; + to.FullID = from.FullID; + to.ID = from.ID; + to.Local = from.Local; + to.Name = from.Name; + to.Temporary = from.Temporary; + to.Type = from.Type; + + } + + private void _guardedAdd(Dictionary lst, UUID obj, bool val) + { + if (!lst.ContainsKey(obj)) + lst.Add(obj, val); + } + + private void SniffTextureUUIDs(Dictionary uuids, SceneObjectGroup sog) + { + try + { + _guardedAdd(uuids, sog.RootPart.Shape.Textures.DefaultTexture.TextureID, true); + } + catch (Exception) { } + + foreach (Primitive.TextureEntryFace tface in sog.RootPart.Shape.Textures.FaceTextures) + { + try + { + _guardedAdd(uuids, tface.TextureID, true); + } + catch (Exception) { } + } + + foreach (SceneObjectPart sop in sog.Children.Values) + { + try + { + _guardedAdd(uuids, sop.Shape.Textures.DefaultTexture.TextureID, true); + } + catch (Exception) { } + foreach (Primitive.TextureEntryFace tface in sop.Shape.Textures.FaceTextures) + { + try + { + _guardedAdd(uuids, tface.TextureID, true); + } + catch (Exception) { } + } + } + } + + private void SniffTaskInventoryUUIDs(Dictionary uuids, SceneObjectGroup sog) + { + TaskInventoryDictionary tinv = sog.RootPart.TaskInventory; + + foreach (TaskInventoryItem titem in tinv.Values) + { + uuids.Add(titem.AssetID, (InventoryType)titem.Type == InventoryType.Texture); + } + } + + private Dictionary SniffUUIDs(AssetBase asset) + { + Dictionary uuids = new Dictionary(); + if ((asset != null) && ((AssetType)asset.Type == AssetType.Object)) + { + string ass_str = Utils.BytesToString(asset.Data); + SceneObjectGroup sog = new SceneObjectGroup(ass_str, true); + + SniffTextureUUIDs(uuids, sog); + + // We need to sniff further... + SniffTaskInventoryUUIDs(uuids, sog); + + } + + return uuids; + } + + private Dictionary SniffUUIDs(UUID assetID) + { + //Dictionary uuids = new Dictionary(); + + AssetBase asset; + m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset); + + return SniffUUIDs(asset); + } + + private void Dump(Dictionary lst) + { + m_log.Debug("XXX -------- UUID DUMP ------- XXX"); + foreach (KeyValuePair kvp in lst) + m_log.Debug(" >> " + kvp.Key + " (texture? " + kvp.Value + ")"); + m_log.Debug("XXX -------- UUID DUMP ------- XXX"); + } + + #endregion + + + #region Public interface + + public void Get(UUID itemID, UUID ownerID) + { + if (!IsInAssetMap(itemID) && !IsHomeUser(ownerID)) + { + // Get the item from the remote asset server onto the local AssetCache + // and place an entry in m_assetMap + + GridAssetClient asscli = null; + string userAssetURL = UserAssetURL(ownerID); + if (userAssetURL != null) + { + m_assetServers.TryGetValue(userAssetURL, out asscli); + if (asscli == null) + { + m_log.Debug("[HGScene]: Starting new GridAssetClient for " + userAssetURL); + asscli = new GridAssetClient(userAssetURL); + asscli.SetReceiver(m_scene.CommsManager.AssetCache); // Straight to the asset cache! + m_assetServers.Add(userAssetURL, asscli); + } + + m_log.Debug("[HGScene]: Fetching object " + itemID + " to asset server " + userAssetURL); + bool success = FetchAsset(asscli, itemID, false); // asscli.RequestAsset(item.ItemID, false); + + // OK, now fetch the inside. + Dictionary ids = SniffUUIDs(itemID); + Dump(ids); + foreach (KeyValuePair kvp in ids) + FetchAsset(asscli, kvp.Key, kvp.Value); + + + if (success) + { + m_log.Debug("[HGScene]: Successfully fetched item from remote asset server " + userAssetURL); + m_assetMap.Add(itemID, asscli); + } + else + m_log.Warn("[HGScene]: Could not fetch asset from remote asset server " + userAssetURL); + } + else + m_log.Warn("[HGScene]: Unable to locate foreign user's asset server"); + } + } + + public void Post(UUID itemID, UUID ownerID) + { + if (!IsHomeUser(ownerID)) + { + // Post the item from the local AssetCache ontp the remote asset server + // and place an entry in m_assetMap + + GridAssetClient asscli = null; + string userAssetURL = UserAssetURL(ownerID); + if (userAssetURL != null) + { + m_assetServers.TryGetValue(userAssetURL, out asscli); + if (asscli == null) + { + m_log.Debug("[HGScene]: Starting new GridAssetClient for " + userAssetURL); + asscli = new GridAssetClient(userAssetURL); + asscli.SetReceiver(m_scene.CommsManager.AssetCache); // Straight to the asset cache! + m_assetServers.Add(userAssetURL, asscli); + } + m_log.Debug("[HGScene]: Posting object " + itemID + " to asset server " + userAssetURL); + bool success = PostAsset(asscli, itemID); + + // Now the inside + Dictionary ids = SniffUUIDs(itemID); + Dump(ids); + foreach (KeyValuePair kvp in ids) + PostAsset(asscli, kvp.Key); + + if (success) + { + m_log.Debug("[HGScene]: Successfully posted item to remote asset server " + userAssetURL); + m_assetMap.Add(itemID, asscli); + } + else + m_log.Warn("[HGScene]: Could not post asset to remote asset server " + userAssetURL); + + //if (!m_assetMap.ContainsKey(itemID)) + // m_assetMap.Add(itemID, asscli); + } + else + m_log.Warn("[HGScene]: Unable to locate foreign user's asset server"); + + } + } + + #endregion + + } +} diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.Inventory.cs index af3c04f..92627d1 100644 --- a/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.Inventory.cs @@ -1,152 +1,152 @@ -/** - * Copyright (c) 2008, Contributors. All rights reserved. - * 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 Organizations nor the names of Individual - * Contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR 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.Reflection; -using System.Threading; - -using log4net; -using Nini.Config; -using OpenMetaverse; - -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Framework.Communications.Cache; -using OpenSim.Framework.Servers; -using OpenSim.Region.Environment; -using OpenSim.Region.Environment.Scenes; - -namespace OpenSim.Region.Environment.Scenes.Hypergrid -{ - public partial class HGScene : Scene - { - #region Fields - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private HGAssetMapper m_assMapper; - - #endregion - - #region Constructors - - public HGScene(RegionInfo regInfo, AgentCircuitManager authen, - CommunicationsManager commsMan, SceneCommunicationService sceneGridService, - AssetCache assetCach, StorageManager storeManager, BaseHttpServer httpServer, - ModuleLoader moduleLoader, bool dumpAssetsToFile, bool physicalPrim, - bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion) - : base(regInfo, authen, commsMan, sceneGridService, assetCach, storeManager, httpServer, moduleLoader, - dumpAssetsToFile, physicalPrim, SeeIntoRegionFromNeighbor, config, simulatorVersion) - { - m_log.Info("[HGScene]: Starting HGScene."); - m_assMapper = new HGAssetMapper(this); - - EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem; - } - - #endregion - - #region Event handlers - - public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel) - { - CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(avatarID); - if (userInfo != null) - { - m_assMapper.Post(assetID, avatarID); - } - } - - #endregion - - #region Overrides of Scene.Inventory methods - - /// - /// CapsUpdateInventoryItemAsset - /// - public override UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data) - { - UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data); - - UploadInventoryItem(remoteClient.AgentId, newAssetID, "", 0); - - return newAssetID; - } - - /// - /// DeleteToInventory - /// - public override UUID DeleteToInventory(int destination, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient) - { - UUID assetID = base.DeleteToInventory(destination, folderID, objectGroup, remoteClient); - - if (!assetID.Equals(UUID.Zero)) - { - UploadInventoryItem(remoteClient.AgentId, assetID, "", 0); - } - else - m_log.Debug("[HGScene]: Scene.Inventory did not create asset"); - - return assetID; - } - - /// - /// RezObject - /// - public override SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, - UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, - bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) - { - CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); - if (userInfo != null) - { - if (userInfo.RootFolder != null) - { - InventoryItemBase item = userInfo.RootFolder.FindItem(itemID); - - if (item != null) - { - m_assMapper.Get(item.AssetID, remoteClient.AgentId); - - } - } - } - - // OK, we're done fetching. Pass it up to the default RezObject - return base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, - RezSelected, RemoveItem, fromTaskID, attachment); - - } - - - #endregion - - } - -} +/** + * Copyright (c) 2008, Contributors. All rights reserved. + * 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 Organizations nor the names of Individual + * Contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR 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.Reflection; +using System.Threading; + +using log4net; +using Nini.Config; +using OpenMetaverse; + +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Communications.Cache; +using OpenSim.Framework.Servers; +using OpenSim.Region.Environment; +using OpenSim.Region.Environment.Scenes; + +namespace OpenSim.Region.Environment.Scenes.Hypergrid +{ + public partial class HGScene : Scene + { + #region Fields + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private HGAssetMapper m_assMapper; + + #endregion + + #region Constructors + + public HGScene(RegionInfo regInfo, AgentCircuitManager authen, + CommunicationsManager commsMan, SceneCommunicationService sceneGridService, + AssetCache assetCach, StorageManager storeManager, BaseHttpServer httpServer, + ModuleLoader moduleLoader, bool dumpAssetsToFile, bool physicalPrim, + bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion) + : base(regInfo, authen, commsMan, sceneGridService, assetCach, storeManager, httpServer, moduleLoader, + dumpAssetsToFile, physicalPrim, SeeIntoRegionFromNeighbor, config, simulatorVersion) + { + m_log.Info("[HGScene]: Starting HGScene."); + m_assMapper = new HGAssetMapper(this); + + EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem; + } + + #endregion + + #region Event handlers + + public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel) + { + CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(avatarID); + if (userInfo != null) + { + m_assMapper.Post(assetID, avatarID); + } + } + + #endregion + + #region Overrides of Scene.Inventory methods + + /// + /// CapsUpdateInventoryItemAsset + /// + public override UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data) + { + UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data); + + UploadInventoryItem(remoteClient.AgentId, newAssetID, "", 0); + + return newAssetID; + } + + /// + /// DeleteToInventory + /// + public override UUID DeleteToInventory(int destination, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient) + { + UUID assetID = base.DeleteToInventory(destination, folderID, objectGroup, remoteClient); + + if (!assetID.Equals(UUID.Zero)) + { + UploadInventoryItem(remoteClient.AgentId, assetID, "", 0); + } + else + m_log.Debug("[HGScene]: Scene.Inventory did not create asset"); + + return assetID; + } + + /// + /// RezObject + /// + public override SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, + UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, + bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) + { + CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); + if (userInfo != null) + { + if (userInfo.RootFolder != null) + { + InventoryItemBase item = userInfo.RootFolder.FindItem(itemID); + + if (item != null) + { + m_assMapper.Get(item.AssetID, remoteClient.AgentId); + + } + } + } + + // OK, we're done fetching. Pass it up to the default RezObject + return base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, + RezSelected, RemoveItem, fromTaskID, attachment); + + } + + + #endregion + + } + +} diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.cs index a1a6173..da1d3a7 100644 --- a/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.cs +++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.cs @@ -1,78 +1,78 @@ -/** - * Copyright (c) 2008, Contributors. All rights reserved. - * 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 Organizations nor the names of Individual - * Contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR 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 OpenMetaverse; - -using OpenSim.Framework; - -using OpenSim.Framework.Communications.Cache; -using OpenSim.Region.Environment; -using OpenSim.Region.Environment.Scenes; -using TPFlags = OpenSim.Framework.Constants.TeleportFlags; - -namespace OpenSim.Region.Environment.Scenes.Hypergrid -{ - public partial class HGScene : Scene - { - /// - /// Teleport an avatar to their home region - /// - /// - /// - public override void TeleportClientHome(UUID agentId, IClientAPI client) - { - m_log.Debug("[HGScene]: TeleportClientHome " + client.FirstName + " " + client.LastName); - - CachedUserInfo uinfo = CommsManager.UserProfileCacheService.GetUserDetails(agentId); - UserProfileData UserProfile = uinfo.UserProfile; - - if (UserProfile != null) - { - RegionInfo regionInfo = CommsManager.GridService.RequestNeighbourInfo(UserProfile.HomeRegion); - //if (regionInfo != null) - //{ - // UserProfile.HomeRegionID = regionInfo.RegionID; - // //CommsManager.UserService.UpdateUserProfile(UserProfile); - //} - if (regionInfo == null) - { - // can't find the Home region: Tell viewer and abort - client.SendTeleportFailed("Your home-region could not be found."); - return; - } - RequestTeleportLocation( - client, regionInfo.RegionHandle, UserProfile.HomeLocation, UserProfile.HomeLookAt, - (uint)(TPFlags.SetLastToTarget | TPFlags.ViaHome)); - } - } - - } -} +/** + * Copyright (c) 2008, Contributors. All rights reserved. + * 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 Organizations nor the names of Individual + * Contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR 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 OpenMetaverse; + +using OpenSim.Framework; + +using OpenSim.Framework.Communications.Cache; +using OpenSim.Region.Environment; +using OpenSim.Region.Environment.Scenes; +using TPFlags = OpenSim.Framework.Constants.TeleportFlags; + +namespace OpenSim.Region.Environment.Scenes.Hypergrid +{ + public partial class HGScene : Scene + { + /// + /// Teleport an avatar to their home region + /// + /// + /// + public override void TeleportClientHome(UUID agentId, IClientAPI client) + { + m_log.Debug("[HGScene]: TeleportClientHome " + client.FirstName + " " + client.LastName); + + CachedUserInfo uinfo = CommsManager.UserProfileCacheService.GetUserDetails(agentId); + UserProfileData UserProfile = uinfo.UserProfile; + + if (UserProfile != null) + { + RegionInfo regionInfo = CommsManager.GridService.RequestNeighbourInfo(UserProfile.HomeRegion); + //if (regionInfo != null) + //{ + // UserProfile.HomeRegionID = regionInfo.RegionID; + // //CommsManager.UserService.UpdateUserProfile(UserProfile); + //} + if (regionInfo == null) + { + // can't find the Home region: Tell viewer and abort + client.SendTeleportFailed("Your home-region could not be found."); + return; + } + RequestTeleportLocation( + client, regionInfo.RegionHandle, UserProfile.HomeLocation, UserProfile.HomeLookAt, + (uint)(TPFlags.SetLastToTarget | TPFlags.ViaHome)); + } + } + + } +} diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs index 501584a..9eb331a 100644 --- a/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs @@ -1,263 +1,263 @@ -/** - * Copyright (c) 2008, Contributors. All rights reserved. - * 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 Organizations nor the names of Individual - * Contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR 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 System.Threading; - -using OpenMetaverse; - -using log4net; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Framework.Communications.Cache; -using OpenSim.Region.Environment.Scenes; -using OpenSim.Region.Environment; -using OpenSim.Region.Interfaces; -using OSD = OpenMetaverse.StructuredData.OSD; - -namespace OpenSim.Region.Environment.Scenes.Hypergrid -{ - public class HGSceneCommunicationService : SceneCommunicationService - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private IHyperlink m_hg; - - public HGSceneCommunicationService(CommunicationsManager commsMan, IHyperlink hg) : base(commsMan) - { - m_hg = hg; - } - - - /// - /// Try to teleport an agent to a new region. - /// - /// - /// - /// - /// - /// - public override void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position, - Vector3 lookAt, uint teleportFlags) - { - if (!avatar.Scene.Permissions.CanTeleport(avatar.UUID)) - return; - - bool destRegionUp = false; - - IEventQueue eq = avatar.Scene.RequestModuleInterface(); - - if (regionHandle == m_regionInfo.RegionHandle) - { - // Teleport within the same region - if (position.X < 0 || position.X > Constants.RegionSize || position.Y < 0 || position.Y > Constants.RegionSize || position.Z < 0) - { - Vector3 emergencyPos = new Vector3(128, 128, 128); - - m_log.WarnFormat( - "[HGSceneCommService]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", - position, avatar.Name, avatar.UUID, emergencyPos); - position = emergencyPos; - } - // TODO: Get proper AVG Height - float localAVHeight = 1.56f; - float posZLimit = (float)avatar.Scene.GetLandHeight((int)position.X, (int)position.Y); - float newPosZ = posZLimit + localAVHeight; - if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) - { - position.Z = newPosZ; - } - - // Only send this if the event queue is null - if (eq == null) - avatar.ControllingClient.SendTeleportLocationStart(); - - - avatar.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); - avatar.Teleport(position); - } - else - { - RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle); - if (reg != null) - { - /// - /// Hypergrid mod start - /// - /// - bool isHyperLink = m_hg.IsHyperlinkRegion(reg.RegionHandle); - bool isHomeUser = true; - ulong realHandle = regionHandle; - CachedUserInfo uinfo = m_commsProvider.UserProfileCacheService.GetUserDetails(avatar.UUID); - if (uinfo != null) - { - isHomeUser = HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile.UserAssetURI); - realHandle = m_hg.FindRegionHandle(regionHandle); - Console.WriteLine("XXX ---- home user? " + isHomeUser + " --- hyperlink? " + isHyperLink + " --- real handle: " + realHandle.ToString()); - } - /// - /// Hypergrid mod stop - /// - /// - - if (eq == null) - avatar.ControllingClient.SendTeleportLocationStart(); - - AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); - agent.BaseFolder = UUID.Zero; - agent.InventoryFolder = UUID.Zero; - agent.startpos = position; - agent.child = true; - - if (reg.RemotingAddress != "" && reg.RemotingPort != 0) - { - // region is remote. see if it is up - destRegionUp = m_commsProvider.InterRegion.CheckRegion(reg.RemotingAddress, reg.RemotingPort); - } - else - { - // assume local regions are always up - destRegionUp = true; - } - - if (destRegionUp) - { - // Fixing a bug where teleporting while sitting results in the avatar ending up removed from - // both regions - if (avatar.ParentID != (uint)0) - avatar.StandUp(); - if (!avatar.ValidateAttachments()) - { - avatar.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); - return; - } - - // the avatar.Close below will clear the child region list. We need this below for (possibly) - // closing the child agents, so save it here (we need a copy as it is Clear()-ed). - List childRegions = new List(avatar.GetKnownRegionList()); - // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport - // failure at this point (unlike a border crossing failure). So perhaps this can never fail - // once we reach here... - avatar.Scene.RemoveCapsHandler(avatar.UUID); - agent.child = false; - m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent); - - m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, - position, false); - Thread.Sleep(2000); - AgentCircuitData circuitdata = avatar.ControllingClient.RequestClientInfo(); - - // TODO Should construct this behind a method - string capsPath = - "http://" + reg.ExternalHostName + ":" + reg.HttpPort - + "/CAPS/" + circuitdata.CapsPath + "0000/"; - - m_log.DebugFormat( - "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); - - - /// - /// Hypergrid mod: realHandle instead of reg.RegionHandle - /// - /// - if (eq != null) - { - OSD Item = EventQueueHelper.TeleportFinishEvent(realHandle, 13, reg.ExternalEndPoint, - 4, teleportFlags, capsPath, avatar.UUID); - eq.Enqueue(Item, avatar.UUID); - } - else - { - avatar.ControllingClient.SendRegionTeleport(realHandle, 13, reg.ExternalEndPoint, 4, - teleportFlags, capsPath); - } - /// - /// Hypergrid mod stop - /// - - avatar.MakeChildAgent(); - Thread.Sleep(7000); - avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); - if (KiPrimitive != null) - { - KiPrimitive(avatar.LocalId); - } - - avatar.Close(); - - uint newRegionX = (uint)(reg.RegionHandle >> 40); - uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); - uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40); - uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8); - /// - /// Hypergrid mod: extra check for isHyperLink - /// - if ((Util.fast_distance2d((int)(newRegionX - oldRegionX), (int)(newRegionY - oldRegionY)) > 3) || isHyperLink) - { - //SendCloseChildAgentConnections(avatar.UUID, avatar.GetKnownRegionList()); - SendCloseChildAgentConnections(avatar.UUID, childRegions); - CloseConnection(avatar.UUID); - } - // if (teleport success) // seems to be always success here - // the user may change their profile information in other region, - // so the userinfo in UserProfileCache is not reliable any more, delete it - if (avatar.Scene.NeedSceneCacheClear(avatar.UUID)) - m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID); - m_log.InfoFormat("[HGSceneCommService]: User {0} is going to another region, profile cache removed", avatar.UUID); - } - else - { - avatar.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); - } - } - else - { - // TP to a place that doesn't exist (anymore) - // Inform the viewer about that - avatar.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); - - // and set the map-tile to '(Offline)' - uint regX, regY; - Utils.LongToUInts(regionHandle, out regX, out regY); - - MapBlockData block = new MapBlockData(); - block.X = (ushort)(regX / Constants.RegionSize); - block.Y = (ushort)(regY / Constants.RegionSize); - block.Access = 254; // == not there - - List blocks = new List(); - blocks.Add(block); - avatar.ControllingClient.SendMapBlock(blocks, 0); - } - } - } - - } -} +/** + * Copyright (c) 2008, Contributors. All rights reserved. + * 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 Organizations nor the names of Individual + * Contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR 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 System.Threading; + +using OpenMetaverse; + +using log4net; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Communications.Cache; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Environment; +using OpenSim.Region.Interfaces; +using OSD = OpenMetaverse.StructuredData.OSD; + +namespace OpenSim.Region.Environment.Scenes.Hypergrid +{ + public class HGSceneCommunicationService : SceneCommunicationService + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private IHyperlink m_hg; + + public HGSceneCommunicationService(CommunicationsManager commsMan, IHyperlink hg) : base(commsMan) + { + m_hg = hg; + } + + + /// + /// Try to teleport an agent to a new region. + /// + /// + /// + /// + /// + /// + public override void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position, + Vector3 lookAt, uint teleportFlags) + { + if (!avatar.Scene.Permissions.CanTeleport(avatar.UUID)) + return; + + bool destRegionUp = false; + + IEventQueue eq = avatar.Scene.RequestModuleInterface(); + + if (regionHandle == m_regionInfo.RegionHandle) + { + // Teleport within the same region + if (position.X < 0 || position.X > Constants.RegionSize || position.Y < 0 || position.Y > Constants.RegionSize || position.Z < 0) + { + Vector3 emergencyPos = new Vector3(128, 128, 128); + + m_log.WarnFormat( + "[HGSceneCommService]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", + position, avatar.Name, avatar.UUID, emergencyPos); + position = emergencyPos; + } + // TODO: Get proper AVG Height + float localAVHeight = 1.56f; + float posZLimit = (float)avatar.Scene.GetLandHeight((int)position.X, (int)position.Y); + float newPosZ = posZLimit + localAVHeight; + if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) + { + position.Z = newPosZ; + } + + // Only send this if the event queue is null + if (eq == null) + avatar.ControllingClient.SendTeleportLocationStart(); + + + avatar.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); + avatar.Teleport(position); + } + else + { + RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle); + if (reg != null) + { + /// + /// Hypergrid mod start + /// + /// + bool isHyperLink = m_hg.IsHyperlinkRegion(reg.RegionHandle); + bool isHomeUser = true; + ulong realHandle = regionHandle; + CachedUserInfo uinfo = m_commsProvider.UserProfileCacheService.GetUserDetails(avatar.UUID); + if (uinfo != null) + { + isHomeUser = HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile.UserAssetURI); + realHandle = m_hg.FindRegionHandle(regionHandle); + Console.WriteLine("XXX ---- home user? " + isHomeUser + " --- hyperlink? " + isHyperLink + " --- real handle: " + realHandle.ToString()); + } + /// + /// Hypergrid mod stop + /// + /// + + if (eq == null) + avatar.ControllingClient.SendTeleportLocationStart(); + + AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); + agent.BaseFolder = UUID.Zero; + agent.InventoryFolder = UUID.Zero; + agent.startpos = position; + agent.child = true; + + if (reg.RemotingAddress != "" && reg.RemotingPort != 0) + { + // region is remote. see if it is up + destRegionUp = m_commsProvider.InterRegion.CheckRegion(reg.RemotingAddress, reg.RemotingPort); + } + else + { + // assume local regions are always up + destRegionUp = true; + } + + if (destRegionUp) + { + // Fixing a bug where teleporting while sitting results in the avatar ending up removed from + // both regions + if (avatar.ParentID != (uint)0) + avatar.StandUp(); + if (!avatar.ValidateAttachments()) + { + avatar.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); + return; + } + + // the avatar.Close below will clear the child region list. We need this below for (possibly) + // closing the child agents, so save it here (we need a copy as it is Clear()-ed). + List childRegions = new List(avatar.GetKnownRegionList()); + // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport + // failure at this point (unlike a border crossing failure). So perhaps this can never fail + // once we reach here... + avatar.Scene.RemoveCapsHandler(avatar.UUID); + agent.child = false; + m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent); + + m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, + position, false); + Thread.Sleep(2000); + AgentCircuitData circuitdata = avatar.ControllingClient.RequestClientInfo(); + + // TODO Should construct this behind a method + string capsPath = + "http://" + reg.ExternalHostName + ":" + reg.HttpPort + + "/CAPS/" + circuitdata.CapsPath + "0000/"; + + m_log.DebugFormat( + "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); + + + /// + /// Hypergrid mod: realHandle instead of reg.RegionHandle + /// + /// + if (eq != null) + { + OSD Item = EventQueueHelper.TeleportFinishEvent(realHandle, 13, reg.ExternalEndPoint, + 4, teleportFlags, capsPath, avatar.UUID); + eq.Enqueue(Item, avatar.UUID); + } + else + { + avatar.ControllingClient.SendRegionTeleport(realHandle, 13, reg.ExternalEndPoint, 4, + teleportFlags, capsPath); + } + /// + /// Hypergrid mod stop + /// + + avatar.MakeChildAgent(); + Thread.Sleep(7000); + avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); + if (KiPrimitive != null) + { + KiPrimitive(avatar.LocalId); + } + + avatar.Close(); + + uint newRegionX = (uint)(reg.RegionHandle >> 40); + uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); + uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40); + uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8); + /// + /// Hypergrid mod: extra check for isHyperLink + /// + if ((Util.fast_distance2d((int)(newRegionX - oldRegionX), (int)(newRegionY - oldRegionY)) > 3) || isHyperLink) + { + //SendCloseChildAgentConnections(avatar.UUID, avatar.GetKnownRegionList()); + SendCloseChildAgentConnections(avatar.UUID, childRegions); + CloseConnection(avatar.UUID); + } + // if (teleport success) // seems to be always success here + // the user may change their profile information in other region, + // so the userinfo in UserProfileCache is not reliable any more, delete it + if (avatar.Scene.NeedSceneCacheClear(avatar.UUID)) + m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID); + m_log.InfoFormat("[HGSceneCommService]: User {0} is going to another region, profile cache removed", avatar.UUID); + } + else + { + avatar.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); + } + } + else + { + // TP to a place that doesn't exist (anymore) + // Inform the viewer about that + avatar.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); + + // and set the map-tile to '(Offline)' + uint regX, regY; + Utils.LongToUInts(regionHandle, out regX, out regY); + + MapBlockData block = new MapBlockData(); + block.X = (ushort)(regX / Constants.RegionSize); + block.Y = (ushort)(regY / Constants.RegionSize); + block.Access = 254; // == not there + + List blocks = new List(); + blocks.Add(block); + avatar.ControllingClient.SendMapBlock(blocks, 0); + } + } + } + + } +} -- cgit v1.1