From 6797ac14741851efa5ba60a00891e18cf7755c80 Mon Sep 17 00:00:00 2001 From: teravus Date: Sat, 29 Dec 2012 08:53:58 -0500 Subject: [PATCH 1/5] * This finishes the implementation of AgentCachedTexture. Requires the XBakes Module and service for full functionality. Previous no-cache functionality works without the service and module. In some ways, I would have been happier not putting an AssetBase in WearableCacheItem.. but turns out it was probably unavoidable. No additional locks, yay. --- .../UploadBakedTextureHandler.cs | 13 +- OpenSim/Framework/AvatarAppearance.cs | 14 +- OpenSim/Framework/WearableCacheItem.cs | 118 +++++++++++++++ .../Linden/Caps/UploadBakedTextureModule.cs | 140 +++++++++++++++++- .../ClientStack/Linden/UDP/LLClientView.cs | 114 +++++++++++--- .../AvatarFactory/AvatarFactoryModule.cs | 7 +- .../Interfaces/IBakedTextureModule.cs | 4 +- 7 files changed, 374 insertions(+), 36 deletions(-) diff --git a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs index 4fa604fc30..5536564233 100644 --- a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs @@ -27,6 +27,7 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Collections.Specialized; using System.Drawing; using System.Drawing.Imaging; @@ -50,6 +51,7 @@ namespace OpenSim.Capabilities.Handlers { public class UploadBakedTextureHandler { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Caps m_HostCapsObj; @@ -79,9 +81,9 @@ namespace OpenSim.Capabilities.Handlers { string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); - + BakedTextureUploader uploader = - new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener); + new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_HostCapsObj.AgentID); uploader.OnUpLoad += BakedTextureUploaded; m_HostCapsObj.HttpListener.AddStreamHandler( @@ -125,6 +127,7 @@ namespace OpenSim.Capabilities.Handlers asset.Temporary = true; asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are m_assetService.Store(asset); + } } @@ -137,15 +140,19 @@ namespace OpenSim.Capabilities.Handlers private string uploaderPath = String.Empty; private UUID newAssetID; private IHttpServer httpListener; + private UUID AgentId = UUID.Zero; - public BakedTextureUploader(string path, IHttpServer httpServer) + public BakedTextureUploader(string path, IHttpServer httpServer, UUID uUID) { newAssetID = UUID.Random(); uploaderPath = path; httpListener = httpServer; + AgentId = uUID; // m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID); } + + /// /// Handle raw uploaded baked texture data. /// diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index 4df4fb6717..ffc3527035 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs @@ -66,7 +66,9 @@ namespace OpenSim.Framework protected Vector3 m_avatarBoxSize = new Vector3(0.45f, 0.6f, 1.9f); protected float m_avatarFeetOffset = 0; protected float m_avatarAnimOffset = 0; - protected WearableCacheItem[] cacheitems; + protected WearableCacheItem[] m_cacheitems; + protected bool m_cacheItemsDirty = true; + public virtual int Serial { get { return m_serial; } @@ -118,8 +120,14 @@ namespace OpenSim.Framework public virtual WearableCacheItem[] WearableCacheItems { - get { return cacheitems; } - set { cacheitems = value; } + get { return m_cacheitems; } + set { m_cacheitems = value; } + } + + public virtual bool WearableCacheItemsDirty + { + get { return m_cacheItemsDirty; } + set { m_cacheItemsDirty = value; } } public AvatarAppearance() diff --git a/OpenSim/Framework/WearableCacheItem.cs b/OpenSim/Framework/WearableCacheItem.cs index 83b1346230..1aecf79695 100644 --- a/OpenSim/Framework/WearableCacheItem.cs +++ b/OpenSim/Framework/WearableCacheItem.cs @@ -26,14 +26,132 @@ */ using System; +using System.Collections.Generic; using OpenMetaverse; +using OpenMetaverse.StructuredData; namespace OpenSim.Framework { + [Serializable] public class WearableCacheItem { public uint TextureIndex { get; set; } public UUID CacheId { get; set; } public UUID TextureID { get; set; } + public AssetBase TextureAsset { get; set; } + + + public static WearableCacheItem[] GetDefaultCacheItem() + { + int itemmax = 21; + WearableCacheItem[] retitems = new WearableCacheItem[itemmax]; + for (uint i=0;i ret = new List(); + if (pInput.Type == OSDType.Array) + { + OSDArray itemarray = (OSDArray) pInput; + foreach (OSDMap item in itemarray) + { + ret.Add(new WearableCacheItem() + { + TextureIndex = item["textureindex"].AsUInteger(), + CacheId = item["cacheid"].AsUUID(), + TextureID = item["textureid"].AsUUID() + }); + + if (dataCache != null && item.ContainsKey("assetdata")) + { + AssetBase asset = new AssetBase(item["textureid"].AsUUID(),"BakedTexture",(sbyte)AssetType.Texture,UUID.Zero.ToString()); + asset.Temporary = true; + asset.Data = item["assetdata"].AsBinary(); + dataCache.Cache(asset); + } + } + } + else if (pInput.Type == OSDType.Map) + { + OSDMap item = (OSDMap) pInput; + ret.Add(new WearableCacheItem(){ + TextureIndex = item["textureindex"].AsUInteger(), + CacheId = item["cacheid"].AsUUID(), + TextureID = item["textureid"].AsUUID() + }); + if (dataCache != null && item.ContainsKey("assetdata")) + { + string assetCreator = item["assetcreator"].AsString(); + string assetName = item["assetname"].AsString(); + AssetBase asset = new AssetBase(item["textureid"].AsUUID(), assetName, (sbyte)AssetType.Texture, assetCreator); + asset.Temporary = true; + asset.Data = item["assetdata"].AsBinary(); + dataCache.Cache(asset); + } + } + else + { + return new WearableCacheItem[0]; + } + return ret.ToArray(); + + } + public static OSD ToOSD(WearableCacheItem[] pcacheItems, IImprovedAssetCache dataCache) + { + OSDArray arr = new OSDArray(); + foreach (WearableCacheItem item in pcacheItems) + { + OSDMap itemmap = new OSDMap(); + itemmap.Add("textureindex", OSD.FromUInteger(item.TextureIndex)); + itemmap.Add("cacheid", OSD.FromUUID(item.CacheId)); + itemmap.Add("textureid", OSD.FromUUID(item.TextureID)); + if (dataCache != null) + { + if (dataCache.Check(item.TextureID.ToString())) + { + AssetBase assetItem = dataCache.Get(item.TextureID.ToString()); + if (assetItem != null) + { + itemmap.Add("assetdata", OSD.FromBinary(assetItem.Data)); + itemmap.Add("assetcreator", OSD.FromString(assetItem.CreatorID)); + itemmap.Add("assetname", OSD.FromString(assetItem.Name)); + } + } + } + arr.Add(itemmap); + } + return arr; + } + public static WearableCacheItem SearchTextureIndex(uint pTextureIndex,WearableCacheItem[] pcacheItems) + { + for (int i = 0; i < pcacheItems.Length; i++) + { + if (pcacheItems[i].TextureIndex == pTextureIndex) + return pcacheItems[i]; + } + return null; + } + public static WearableCacheItem SearchTextureCacheId(UUID pCacheId, WearableCacheItem[] pcacheItems) + { + for (int i = 0; i < pcacheItems.Length; i++) + { + if (pcacheItems[i].CacheId == pCacheId) + return pcacheItems[i]; + } + return null; + } + public static WearableCacheItem SearchTextureTextureId(UUID pTextureId, WearableCacheItem[] pcacheItems) + { + for (int i = 0; i < pcacheItems.Length; i++) + { + if (pcacheItems[i].TextureID == pTextureId) + return pcacheItems[i]; + } + return null; + } } + + } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs index 3b0ccd75ec..6778ba5d48 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs @@ -27,6 +27,7 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Collections.Specialized; using System.Drawing; using System.Drawing.Imaging; @@ -53,8 +54,8 @@ namespace OpenSim.Region.ClientStack.Linden [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UploadBakedTextureModule")] public class UploadBakedTextureModule : INonSharedRegionModule { -// private static readonly ILog m_log = -// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// /// For historical reasons this is fixed, but there @@ -64,31 +65,154 @@ namespace OpenSim.Region.ClientStack.Linden private Scene m_scene; private bool m_persistBakedTextures; + private IBakedTextureModule m_BakedTextureModule; + public void Initialise(IConfigSource source) { IConfig appearanceConfig = source.Configs["Appearance"]; if (appearanceConfig != null) m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures); + + } public void AddRegion(Scene s) { m_scene = s; + } public void RemoveRegion(Scene s) { + s.EventManager.OnRegisterCaps -= RegisterCaps; + s.EventManager.OnNewPresence -= RegisterNewPresence; + s.EventManager.OnRemovePresence -= DeRegisterPresence; + m_BakedTextureModule = null; + m_scene = null; } + + public void RegionLoaded(Scene s) { m_scene.EventManager.OnRegisterCaps += RegisterCaps; + m_scene.EventManager.OnNewPresence += RegisterNewPresence; + m_scene.EventManager.OnRemovePresence += DeRegisterPresence; + + } + + private void DeRegisterPresence(UUID agentId) + { + ScenePresence presence = null; + if (m_scene.TryGetScenePresence(agentId, out presence)) + { + presence.ControllingClient.OnSetAppearance -= CaptureAppearanceSettings; + } + + } + + private void RegisterNewPresence(ScenePresence presence) + { + presence.ControllingClient.OnSetAppearance += CaptureAppearanceSettings; + + } + + private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) + { + m_BakedTextureModule = m_scene.RequestModuleInterface(); + if (cacheItems.Length > 0) + { + m_log.Info("[Cacheitems]: " + cacheItems.Length); + for (int iter = 0; iter < cacheItems.Length; iter++) + { + m_log.Info("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + + cacheItems[iter].TextureID); + } + + ScenePresence p = null; + if (m_scene.TryGetScenePresence(remoteClient.AgentId, out p)) + { + + WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems; + if (existingitems == null) + { + if (m_BakedTextureModule != null) + { + WearableCacheItem[] savedcache = null; + try + { + if (p.Appearance.WearableCacheItemsDirty) + { + savedcache = m_BakedTextureModule.Get(p.UUID); + p.Appearance.WearableCacheItems = savedcache; + p.Appearance.WearableCacheItemsDirty = false; + } + + } + catch (InvalidOperationException) + { + } + + if (savedcache != null) + existingitems = savedcache; + } + } + // Existing items null means it's a fully new appearance + if (existingitems == null) + { + + for (int iter = 0; iter < cacheItems.Length; iter++) + { + + cacheItems[iter].TextureID = textureEntry.FaceTextures[cacheItems[iter].TextureIndex].TextureID; + if (m_scene.AssetService != null) + cacheItems[iter].TextureAsset = m_scene.AssetService.GetCached(cacheItems[iter].TextureID.ToString()); + + + } + } + else + + + { + // for each uploaded baked texture + for (int i = 0; i < cacheItems.Length; i++) + { + cacheItems[i].TextureID = + textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID; + } + + for (int i = 0; i < cacheItems.Length; i++) + { + if (cacheItems[i].TextureAsset == null) + { + cacheItems[i].TextureAsset = m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); + } + } + } + + + + p.Appearance.WearableCacheItems = cacheItems; + + + + if (m_BakedTextureModule != null) + { + m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems); + p.Appearance.WearableCacheItemsDirty = true; + + } + } + } } public void PostInitialise() { } + + public void Close() { } public string Name { get { return "UploadBakedTextureModule"; } } @@ -100,15 +224,23 @@ namespace OpenSim.Region.ClientStack.Linden public void RegisterCaps(UUID agentID, Caps caps) { + UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler( + caps, m_scene.AssetService, m_persistBakedTextures); + + + caps.RegisterHandler( "UploadBakedTexture", new RestStreamHandler( "POST", "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath, - new UploadBakedTextureHandler( - caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture, + avatarhandler.UploadBakedTexture, "UploadBakedTexture", agentID.ToString())); + + + + } } } \ No newline at end of file diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index d18b026bc8..9e39699246 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3629,7 +3629,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP avp.Sender.IsTrial = false; avp.Sender.ID = agentID; - //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); + m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); OutPacket(avp, ThrottleOutPacketType.State); } @@ -11725,32 +11725,110 @@ namespace OpenSim.Region.ClientStack.LindenUDP // var item = fac.GetBakedTextureFaces(AgentId); //WearableCacheItem[] items = fac.GetCachedItems(AgentId); - IImprovedAssetCache cache = m_scene.RequestModuleInterface(); - if (cache == null) + IAssetService cache = m_scene.AssetService; + IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface(); + if (bakedTextureModule != null && cache != null) { - for (int i = 0; i < cachedtex.WearableData.Length; i++) + // We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid + + WearableCacheItem[] cacheItems = null; + ScenePresence p = m_scene.GetScenePresence(AgentId); + if (p.Appearance != null) + if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty) + { + try + { + cacheItems = bakedTextureModule.Get(AgentId); + p.Appearance.WearableCacheItems = cacheItems; + p.Appearance.WearableCacheItemsDirty = false; + } + catch (InvalidOperationException) + { + cacheItems = null; + } + } + else if (p.Appearance.WearableCacheItems != null) + { + cacheItems = p.Appearance.WearableCacheItems; + } + + if (cache != null && cacheItems != null) { - cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); - cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; - cachedresp.WearableData[i].TextureID = UUID.Zero; //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); - cachedresp.WearableData[i].HostName = new byte[0]; + foreach (WearableCacheItem item in cacheItems) + { + + if (cache.GetCached(item.TextureID.ToString()) == null) + { + item.TextureAsset.Temporary = true; + cache.Store(item.TextureAsset); + } + + + } + } + if (cacheItems != null) + { + + for (int i = 0; i < cachedtex.WearableData.Length; i++) + { + WearableCacheItem item = + WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems); + + cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); + cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex; + cachedresp.WearableData[i].HostName = new byte[0]; + if (item != null) + { + cachedresp.WearableData[i].TextureID = item.TextureID; + } + else + { + cachedresp.WearableData[i].TextureID = UUID.Zero; + } + } + } + else + { + for (int i = 0; i < cachedtex.WearableData.Length; i++) + { + cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); + cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; + cachedresp.WearableData[i].TextureID = UUID.Zero; + //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); + cachedresp.WearableData[i].HostName = new byte[0]; + } } } else { - for (int i = 0; i < cachedtex.WearableData.Length; i++) + if (cache == null) { - cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); - cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; - - - - if (cache.Check(cachedtex.WearableData[i].ID.ToString())) + for (int i = 0; i < cachedtex.WearableData.Length; i++) + { + cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); + cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; cachedresp.WearableData[i].TextureID = UUID.Zero; //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); - else - cachedresp.WearableData[i].TextureID = UUID.Zero; // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); - cachedresp.WearableData[i].HostName = new byte[0]; + cachedresp.WearableData[i].HostName = new byte[0]; + } + } + else + { + for (int i = 0; i < cachedtex.WearableData.Length; i++) + { + cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); + cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; + + + + if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null) + cachedresp.WearableData[i].TextureID = UUID.Zero; + //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); + else + cachedresp.WearableData[i].TextureID = UUID.Zero; + // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); + cachedresp.WearableData[i].HostName = new byte[0]; + } } } cachedresp.Header.Zerocoded = true; diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 3080023c0f..27cf20473a 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -205,10 +205,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // ((ScenePresence)sp).SetSize(box,off); } - //if (cacheItems.Length > 0) - //{ - sp.Appearance.WearableCacheItems = cacheItems; - //} + // Process the baked texture array if (textureEntry != null) { @@ -284,8 +281,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory public WearableCacheItem[] GetCachedItems(UUID agentId) { ScenePresence sp = m_scene.GetScenePresence(agentId); - Dictionary bakedTextures = GetBakedTextureFaces(sp); - WearableCacheItem[] items = sp.Appearance.WearableCacheItems; //foreach (WearableCacheItem item in items) //{ diff --git a/OpenSim/Region/Framework/Interfaces/IBakedTextureModule.cs b/OpenSim/Region/Framework/Interfaces/IBakedTextureModule.cs index d63898acd8..21ed44ffdb 100644 --- a/OpenSim/Region/Framework/Interfaces/IBakedTextureModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IBakedTextureModule.cs @@ -13,7 +13,7 @@ namespace OpenSim.Services.Interfaces { public interface IBakedTextureModule { - AssetBase[] Get(UUID id); - void Store(UUID id, AssetBase[] data); + WearableCacheItem[] Get(UUID id); + void Store(UUID id, WearableCacheItem[] data); } } From 2805ec64662494d680925c6034e59b823e051a9d Mon Sep 17 00:00:00 2001 From: teravus Date: Mon, 31 Dec 2012 23:04:28 -0500 Subject: [PATCH 2/5] * Fixed a bug that replayed old cached appearance when changing outfits * Added suser(bad client) DOS protection by limiting the max cacheitems to the maximum sane amount. * Prevents potential numerous loops from running amok and index errors if the client purposely provides bad cache info. * If the XBakes service wasn't running, the SetAvatarAppearance routine would crash when contacting the XBakes service even though it was in a Try/Catch for the appropriate error type. It only properly error handles with the type Exception :(. (commented on that because it's unusual) --- .../Linden/Caps/UploadBakedTextureModule.cs | 129 ++++++++++++------ .../ClientStack/Linden/UDP/LLClientView.cs | 36 ++++- 2 files changed, 115 insertions(+), 50 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs index 6778ba5d48..6bed95f369 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs @@ -119,13 +119,20 @@ namespace OpenSim.Region.ClientStack.Linden private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) { + int maxCacheitemsLoop = cacheItems.Length; + if (maxCacheitemsLoop > AvatarWearable.MAX_WEARABLES) + { + maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES; + m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES); + } + m_BakedTextureModule = m_scene.RequestModuleInterface(); if (cacheItems.Length > 0) { - m_log.Info("[Cacheitems]: " + cacheItems.Length); - for (int iter = 0; iter < cacheItems.Length; iter++) + m_log.Debug("[Cacheitems]: " + cacheItems.Length); + for (int iter = 0; iter < maxCacheitemsLoop; iter++) { - m_log.Info("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + + m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + cacheItems[iter].TextureID); } @@ -133,65 +140,99 @@ namespace OpenSim.Region.ClientStack.Linden if (m_scene.TryGetScenePresence(remoteClient.AgentId, out p)) { - WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems; - if (existingitems == null) + WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems; + if (existingitems == null) + { + if (m_BakedTextureModule != null) { - if (m_BakedTextureModule != null) + WearableCacheItem[] savedcache = null; + try { - WearableCacheItem[] savedcache = null; - try - { - if (p.Appearance.WearableCacheItemsDirty) - { - savedcache = m_BakedTextureModule.Get(p.UUID); - p.Appearance.WearableCacheItems = savedcache; - p.Appearance.WearableCacheItemsDirty = false; - } - - } - catch (InvalidOperationException) + if (p.Appearance.WearableCacheItemsDirty) { + savedcache = m_BakedTextureModule.Get(p.UUID); + p.Appearance.WearableCacheItems = savedcache; + p.Appearance.WearableCacheItemsDirty = false; } - if (savedcache != null) - existingitems = savedcache; } - } - // Existing items null means it's a fully new appearance - if (existingitems == null) - { - - for (int iter = 0; iter < cacheItems.Length; iter++) + /* + * The following Catch types DO NOT WORK with m_BakedTextureModule.Get + * it jumps to the General Packet Exception Handler if you don't catch Exception! + * + catch (System.Net.Sockets.SocketException) { - - cacheItems[iter].TextureID = textureEntry.FaceTextures[cacheItems[iter].TextureIndex].TextureID; - if (m_scene.AssetService != null) - cacheItems[iter].TextureAsset = m_scene.AssetService.GetCached(cacheItems[iter].TextureID.ToString()); - - + cacheItems = null; + } + catch (WebException) + { + cacheItems = null; + } + catch (InvalidOperationException) + { + cacheItems = null; + } */ + catch (Exception) + { + // The service logs a sufficient error message. } - } - else - + + if (savedcache != null) + existingitems = savedcache; + } + } + // Existing items null means it's a fully new appearance + if (existingitems == null) + { + + for (int i = 0; i < maxCacheitemsLoop; i++) { - // for each uploaded baked texture - for (int i = 0; i < cacheItems.Length; i++) + if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) + { + cacheItems[i].TextureID = + textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID; + if (m_scene.AssetService != null) + cacheItems[i].TextureAsset = + m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); + } + else + { + m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length); + } + + + } + } + else + + + { + // for each uploaded baked texture + for (int i = 0; i < maxCacheitemsLoop; i++) + { + if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) { cacheItems[i].TextureID = textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID; } - - for (int i = 0; i < cacheItems.Length; i++) + else { - if (cacheItems[i].TextureAsset == null) - { - cacheItems[i].TextureAsset = m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); - } + m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length); } } - + for (int i = 0; i < maxCacheitemsLoop; i++) + { + if (cacheItems[i].TextureAsset == null) + { + cacheItems[i].TextureAsset = + m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); + } + } + } + + p.Appearance.WearableCacheItems = cacheItems; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 9e39699246..d46adb8863 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -11727,6 +11727,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP IAssetService cache = m_scene.AssetService; IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface(); + //bakedTextureModule = null; + int maxWearablesLoop = cachedtex.WearableData.Length; + if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES) + maxWearablesLoop = AvatarWearable.MAX_WEARABLES; + if (bakedTextureModule != null && cache != null) { // We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid @@ -11742,10 +11747,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP p.Appearance.WearableCacheItems = cacheItems; p.Appearance.WearableCacheItemsDirty = false; } - catch (InvalidOperationException) + + /* + * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception! + * + catch (System.Net.Sockets.SocketException) { cacheItems = null; } + catch (WebException) + { + cacheItems = null; + } + catch (InvalidOperationException) + { + cacheItems = null; + } */ + catch (Exception) + { + cacheItems = null; + } + } else if (p.Appearance.WearableCacheItems != null) { @@ -11766,10 +11788,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + if (cacheItems != null) { - for (int i = 0; i < cachedtex.WearableData.Length; i++) + for (int i = 0; i < maxWearablesLoop; i++) { WearableCacheItem item = WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems); @@ -11777,8 +11800,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex; cachedresp.WearableData[i].HostName = new byte[0]; - if (item != null) + if (item != null && cachedtex.WearableData[i].ID == item.CacheId) { + cachedresp.WearableData[i].TextureID = item.TextureID; } else @@ -11789,7 +11813,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { - for (int i = 0; i < cachedtex.WearableData.Length; i++) + for (int i = 0; i < maxWearablesLoop; i++) { cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; @@ -11803,7 +11827,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (cache == null) { - for (int i = 0; i < cachedtex.WearableData.Length; i++) + for (int i = 0; i < maxWearablesLoop; i++) { cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; @@ -11814,7 +11838,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { - for (int i = 0; i < cachedtex.WearableData.Length; i++) + for (int i = 0; i < maxWearablesLoop; i++) { cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; From d1fa650c3f16ee74cd39d9258c5ef7aa4869ca03 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 8 Jan 2013 12:08:34 +0100 Subject: [PATCH 3/5] Remove sending AvatarData because this also happens on login, where it chokes Firestorm, Singularity and other viewers with the new appearance pipeline. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4504e18de8..b6407d2d57 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -140,8 +140,6 @@ namespace OpenSim.Region.Framework.Scenes private Vector3 m_lastPosition; private Quaternion m_lastRotation; private Vector3 m_lastVelocity; - private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f); - private Vector3? m_forceToApply; private int m_userFlags; @@ -2525,13 +2523,7 @@ namespace OpenSim.Region.Framework.Scenes // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to // grab the latest PhysicsActor velocity, whereas m_velocity is often // storing a requested force instead of an actual traveling velocity - if (Appearance.AvatarSize != m_lastSize) - { - m_lastSize = Appearance.AvatarSize; - SendAvatarDataToAllAgents(); - } - - else if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || + if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) { From 09d41f4f7892b2d40b692f0cdd451fea07ad0cf0 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 8 Jan 2013 13:11:04 +0100 Subject: [PATCH 4/5] Revert "Remove sending AvatarData because this also happens on login, where it chokes" This reverts commit d1fa650c3f16ee74cd39d9258c5ef7aa4869ca03. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index be3a39a787..cdba2824b4 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -140,6 +140,8 @@ namespace OpenSim.Region.Framework.Scenes private Vector3 m_lastPosition; private Quaternion m_lastRotation; private Vector3 m_lastVelocity; + private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f); + private Vector3? m_forceToApply; private int m_userFlags; @@ -2539,7 +2541,13 @@ namespace OpenSim.Region.Framework.Scenes // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to // grab the latest PhysicsActor velocity, whereas m_velocity is often // storing a requested force instead of an actual traveling velocity - if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || + if (Appearance.AvatarSize != m_lastSize) + { + m_lastSize = Appearance.AvatarSize; + SendAvatarDataToAllAgents(); + } + + else if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) { From fb088a48ac6cd737a25ce46f76e988879c0f0255 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 8 Jan 2013 14:09:01 +0000 Subject: [PATCH 5/5] also update m_lastSize in SendAvatarDataToAllAgents so more paths update it --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index cdba2824b4..a90bee437f 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2738,6 +2738,8 @@ namespace OpenSim.Region.Framework.Scenes return; } + m_lastSize = Appearance.AvatarSize; + int count = 0; m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) {