From ae15b75f79a605f965ffe1498fb4cdfdcfb88466 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 29 Apr 2020 16:29:20 +0100 Subject: [PATCH] change UploadBakedTextureModule. Make it shared and self contained --- .../Linden/Caps/UploadBakedTextureModule.cs | 180 +++++++++++++----- 1 file changed, 135 insertions(+), 45 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs index aaca147a51..604599ff83 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs @@ -26,36 +26,29 @@ */ using System; +using System.Net; using System.Reflection; +using System.Timers; using log4net; using Nini.Config; using Mono.Addins; using OpenMetaverse; -using OpenMetaverse.StructuredData; -using OpenMetaverse.Imaging; using OpenSim.Framework; -using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using OpenSim.Services.Interfaces; +using OpenSim.Framework.Capabilities; using Caps = OpenSim.Framework.Capabilities.Caps; -using OpenSim.Capabilities.Handlers; namespace OpenSim.Region.ClientStack.Linden { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UploadBakedTextureModule")] - public class UploadBakedTextureModule : INonSharedRegionModule + public class UploadBakedTextureModule : ISharedRegionModule { - 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 - /// - private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule. - - private Scene m_scene; + private int m_nscenes; + IAssetCache m_assetCache = null; private string m_URL; @@ -66,36 +59,29 @@ namespace OpenSim.Region.ClientStack.Linden return; m_URL = config.GetString("Cap_UploadBakedTexture", string.Empty); - -// IConfig appearanceConfig = source.Configs["Appearance"]; } 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_scene = null; + --m_nscenes; + if(m_nscenes <= 0) + m_assetCache = 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) - { - } - - private void RegisterNewPresence(ScenePresence presence) - { + if (m_assetCache == null) + m_assetCache = s.RequestModuleInterface (); + if (m_assetCache != null) + { + ++m_nscenes; + s.EventManager.OnRegisterCaps += RegisterCaps; + } } public void PostInitialise() @@ -113,26 +99,130 @@ namespace OpenSim.Region.ClientStack.Linden public void RegisterCaps(UUID agentID, Caps caps) { - //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); if (m_URL == "localhost") { - UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler( - caps, m_scene.AssetService); - - caps.RegisterHandler( - "UploadBakedTexture", - new RestStreamHandler( - "POST", - "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath, - avatarhandler.UploadBakedTexture, - "UploadBakedTexture", - agentID.ToString())); - + caps.RegisterSimpleHandler("UploadBakedTexture", + new SimpleStreamHandler("/" + UUID.Random(), delegate (IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + { + UploadBakedTexture(httpRequest, httpResponse, agentID, caps, m_assetCache); + })); } - else + else if(!string.IsNullOrWhiteSpace(m_URL)) { caps.RegisterHandler("UploadBakedTexture", m_URL); } } + + public void UploadBakedTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID agentID, Caps caps, IAssetCache cache) + { + if(httpRequest.HttpMethod != "POST") + { + httpResponse.StatusCode = (int)HttpStatusCode.NotFound; + return; + } + try + { + string capsBase = "/" + UUID.Random()+"-BK"; + string protocol = caps.SSLCaps ? "https://" : "http://"; + string uploaderURL = protocol + caps.HostName + ":" + caps.Port.ToString() + capsBase; + + LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); + uploadResponse.uploader = uploaderURL; + uploadResponse.state = "upload"; + + BakedTextureUploader uploader = + new BakedTextureUploader(capsBase, caps.HttpListener, agentID, cache, httpRequest.RemoteIPEndPoint.Address); + + var uploaderHandler = new SimpleBinaryHandler("POST", capsBase, uploader.process); + + uploaderHandler.MaxDataSize = 6000000; // change per asset type? + + caps.HttpListener.AddSimpleStreamHandler(uploaderHandler); + + httpResponse.RawBuffer = Util.UTF8NBGetbytes(LLSDHelpers.SerialiseLLSDReply(uploadResponse)); + httpResponse.StatusCode = (int)HttpStatusCode.OK; + return; + } + catch (Exception e) + { + m_log.ErrorFormat("[UPLOAD BAKED TEXTURE HANDLER]: {0}{1}", e.Message, e.StackTrace); + } + httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; + } + } + + class BakedTextureUploader + { + // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private string m_uploaderPath = String.Empty; + private IHttpServer m_httpListener; + private UUID m_agentID = UUID.Zero; + private IPAddress m_remoteAddress; + private IAssetCache m_assetCache; + private Timer m_timeout; + + public BakedTextureUploader(string path, IHttpServer httpServer, UUID agentID, IAssetCache cache, IPAddress remoteAddress) + { + m_uploaderPath = path; + m_httpListener = httpServer; + m_agentID = agentID; + m_remoteAddress = remoteAddress; + m_assetCache = cache; + m_timeout = new Timer(); + m_timeout.Elapsed += Timeout; + m_timeout.Interval = 1000; + m_timeout.Start(); + } + + private void Timeout(Object source, ElapsedEventArgs e) + { + m_httpListener.RemoveSimpleStreamHandler(m_uploaderPath); + m_timeout.Dispose(); + } + + /// + /// Handle raw uploaded baked texture data. + /// + /// + /// + /// + /// + public void process(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, byte[] data) + { + m_timeout.Stop(); + m_httpListener.RemoveSimpleStreamHandler(m_uploaderPath); + m_timeout.Dispose(); + + if (!httpRequest.RemoteIPEndPoint.Address.Equals(m_remoteAddress)) + { + httpResponse.StatusCode = (int)HttpStatusCode.Unauthorized; + return; + } + + // need to check if data is a baked + try + { + UUID newAssetID = UUID.Random(); + AssetBase asset = new AssetBase(newAssetID, "Baked Texture", (sbyte)AssetType.Texture, m_agentID.ToString()); + asset.Data = data; + asset.Temporary = true; + asset.Local = true; + //asset.Flags = AssetFlags.AvatarBake; + m_assetCache.Cache(asset); + + LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); + uploadComplete.new_asset = newAssetID.ToString(); + uploadComplete.new_inventory_item = UUID.Zero; + uploadComplete.state = "complete"; + + httpResponse.RawBuffer = Util.UTF8NBGetbytes(LLSDHelpers.SerialiseLLSDReply(uploadComplete)); + httpResponse.StatusCode = (int)HttpStatusCode.OK; + return; + } + catch { } + httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; + } } } +