From 3e4b094921dddfe10f6ee5f73eb1b917381c2c30 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Fri, 14 Nov 2008 14:42:00 +0000 Subject: * Implements terrain raw upload. You can now upload your .raw terrain files using the Estate Tools. * Could this be extended in the future to support .oar uploads too? Only time will tell! --- .../AgentAssetTransactionsManager.cs | 2 + .../AssetTransaction/AssetTransactionModule.cs | 9 +- .../Modules/World/Estate/EstateManagementModule.cs | 115 ++++++++++++++++++ .../World/Estate/EstateTerrainXferHandler.cs | 129 +++++++++++++++++++++ .../Environment/Modules/World/NPC/NPCAvatar.cs | 2 + 5 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 OpenSim/Region/Environment/Modules/World/Estate/EstateTerrainXferHandler.cs (limited to 'OpenSim/Region/Environment/Modules') diff --git a/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AgentAssetTransactionsManager.cs b/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AgentAssetTransactionsManager.cs index be8aeea..010fcf7 100644 --- a/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AgentAssetTransactionsManager.cs +++ b/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AgentAssetTransactionsManager.cs @@ -180,6 +180,7 @@ namespace OpenSim.Region.Environment.Modules.Agent.AssetTransaction public void HandleUDPUploadRequest(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data, bool storeLocal, bool tempFile) { + //System.Console.WriteLine("HandleUDPUploadRequest - assetID: " + assetID.ToString() + " transaction: " + transaction.ToString() + " type: " + type.ToString() + " storelocal: " + storeLocal + " tempFile: " + tempFile); if (((AssetType)type == AssetType.Texture || (AssetType)type == AssetType.Sound || (AssetType)type == AssetType.TextureTGA || @@ -219,6 +220,7 @@ namespace OpenSim.Region.Environment.Modules.Agent.AssetTransaction /// public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) { + //System.Console.WriteLine("xferID: " + xferID + " packetID: " + packetID + " data!"); AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); transactions.HandleXfer(xferID, packetID, data); diff --git a/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AssetTransactionModule.cs index 09c9aef..19d7066 100644 --- a/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AssetTransactionModule.cs +++ b/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AssetTransactionModule.cs @@ -43,6 +43,7 @@ namespace OpenSim.Region.Environment.Modules.Agent.AssetTransaction private Scene m_scene = null; private AgentAssetTransactionsManager m_transactionManager; + public AssetTransactionModule() { @@ -68,7 +69,13 @@ namespace OpenSim.Region.Environment.Modules.Agent.AssetTransaction IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item) { m_transactionManager.HandleTaskItemUpdateFromTransaction(remoteClient, part, transactionID, item); - } + } + + public void RequestXferFromClient(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, + byte[] data, bool storeLocal, bool tempFile) + { + m_transactionManager.HandleUDPUploadRequest(remoteClient, assetID, transaction, type, data, storeLocal, tempFile); + } public void RemoveAgentAssetTransactions(UUID userID) { diff --git a/OpenSim/Region/Environment/Modules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/Environment/Modules/World/Estate/EstateManagementModule.cs index 52175f4..4aad3b1 100644 --- a/OpenSim/Region/Environment/Modules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Estate/EstateManagementModule.cs @@ -45,6 +45,8 @@ namespace OpenSim.Region.Environment.Modules.World.Estate private Scene m_scene; + private EstateTerrainXferHandler TerrainUploader = null; + #region Packet Data Responders private void sendDetailedEstateData(IClientAPI remote_client, UUID invoice) @@ -420,7 +422,119 @@ namespace OpenSim.Region.Environment.Modules.World.Estate } } } + private void AbortTerrainXferHandler(IClientAPI remoteClient, ulong XferID) + { + if (TerrainUploader != null) + { + lock (TerrainUploader) + { + if (XferID == TerrainUploader.XferID) + { + remoteClient.OnXferReceive -= TerrainUploader.XferReceive; + remoteClient.OnAbortXfer -= AbortTerrainXferHandler; + TerrainUploader.TerrainUploadDone -= HandleTerrainApplication; + + TerrainUploader = null; + remoteClient.SendAlertMessage("Terrain Upload aborted by the client"); + } + } + } + + } + private void HandleTerrainApplication(string filename, byte[] terrainData, IClientAPI remoteClient) + { + lock (TerrainUploader) + { + remoteClient.OnXferReceive -= TerrainUploader.XferReceive; + remoteClient.OnAbortXfer -= AbortTerrainXferHandler; + TerrainUploader.TerrainUploadDone -= HandleTerrainApplication; + + TerrainUploader = null; + } + remoteClient.SendAlertMessage("Terrain Upload Complete. Loading...."); + OpenSim.Region.Environment.Modules.World.Terrain.ITerrainModule terr = m_scene.RequestModuleInterface(); + + if (terr != null) + { + m_log.Warn("[CLIENT]: Got Request to Send Terrain in region " + m_scene.RegionInfo.RegionName); + if (System.IO.File.Exists(Util.dataDir() + "/terrain.raw")) + { + System.IO.File.Delete(Util.dataDir() + "/terrain.raw"); + } + try + { + System.IO.FileStream input = new System.IO.FileStream(Util.dataDir() + "/terrain.raw", System.IO.FileMode.CreateNew); + input.Write(terrainData, 0, terrainData.Length); + input.Close(); + } + catch (System.IO.IOException e) + { + m_log.ErrorFormat("[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); + remoteClient.SendAlertMessage("There was an IO Exception loading your terrain. Please check free space"); + + return; + } + catch (System.Security.SecurityException e) + { + m_log.ErrorFormat("[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); + remoteClient.SendAlertMessage("There was a security Exception loading your terrain. Please check the security on the simulator drive"); + + return; + } + catch (System.UnauthorizedAccessException e) + { + m_log.ErrorFormat("[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); + remoteClient.SendAlertMessage("There was a security Exception loading your terrain. Please check the security on the simulator drive"); + return; + } + + + + + try + { + terr.LoadFromFile(Util.dataDir() + "/terrain.raw"); + remoteClient.SendAlertMessage("Your terrain was loaded. Give it a minute or two to apply"); + } + catch (Exception e) + { + m_log.ErrorFormat("[TERRAIN]: Error loading a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); + remoteClient.SendAlertMessage("There was a general error loading your terrain. Please fix the terrain file and try again"); + } + + } + else + { + remoteClient.SendAlertMessage("Unable to apply terrain. Cannot get an instance of the terrain module"); + } + + + + } + + private void handleUploadTerrain(IClientAPI remote_client, string clientFileName) + { + + if (TerrainUploader == null) + { + + TerrainUploader = new EstateTerrainXferHandler(remote_client, clientFileName); + lock (TerrainUploader) + { + remote_client.OnXferReceive += TerrainUploader.XferReceive; + remote_client.OnAbortXfer += AbortTerrainXferHandler; + TerrainUploader.TerrainUploadDone += HandleTerrainApplication; + } + TerrainUploader.RequestStartXfer(remote_client); + + } + else + { + remote_client.SendAlertMessage("Another Terrain Upload is in progress. Please wait your turn!"); + } + + } private void handleTerrainRequest(IClientAPI remote_client, string clientFileName) { // Save terrain here @@ -793,6 +907,7 @@ namespace OpenSim.Region.Environment.Modules.World.Estate client.OnEstateTeleportOneUserHomeRequest += handleEstateTeleportOneUserHomeRequest; client.OnEstateTeleportAllUsersHomeRequest += handleEstateTeleportAllUsersHomeRequest; client.OnRequestTerrain += handleTerrainRequest; + client.OnUploadTerrain += handleUploadTerrain; client.OnRegionInfoRequest += HandleRegionInfoRequest; client.OnEstateCovenantRequest += HandleEstateCovenantRequest; diff --git a/OpenSim/Region/Environment/Modules/World/Estate/EstateTerrainXferHandler.cs b/OpenSim/Region/Environment/Modules/World/Estate/EstateTerrainXferHandler.cs new file mode 100644 index 0000000..3ee633e --- /dev/null +++ b/OpenSim/Region/Environment/Modules/World/Estate/EstateTerrainXferHandler.cs @@ -0,0 +1,129 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.IO; +using System.Reflection; +using log4net; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Communications.Cache; +using OpenSim.Region.Environment.Scenes; + + +namespace OpenSim.Region.Environment.Modules.World.Estate +{ + + public class EstateTerrainXferHandler + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private AssetBase m_asset; + + public delegate void TerrainUploadComplete(string name, byte[] filedata, IClientAPI remoteClient); + + public event TerrainUploadComplete TerrainUploadDone; + + private string m_description = String.Empty; + private string m_name = String.Empty; + private UUID TransactionID = UUID.Zero; + private sbyte type = 0; + + public ulong mXferID; + private TerrainUploadComplete handlerTerrainUploadDone; + + + + public EstateTerrainXferHandler(IClientAPI pRemoteClient, string pClientFilename) + { + + m_asset = new AssetBase(); + m_asset.FullID = UUID.Zero; + m_asset.Type = type; + m_asset.Data = new byte[0]; + m_asset.Name = pClientFilename; + m_asset.Description = "empty"; + m_asset.Local = true; + m_asset.Temporary = true; + + } + + public ulong XferID + { + get { return mXferID; } + } + + public void RequestStartXfer(IClientAPI pRemoteClient) + { + mXferID = Util.GetNextXferID(); + pRemoteClient.SendXferRequest(mXferID, m_asset.Type, m_asset.FullID, 0, Utils.StringToBytes(m_asset.Name)); + } + + /// + /// Process transfer data received from the client. + /// + /// + /// + /// + public void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) + { + if (mXferID == xferID) + { + if (m_asset.Data.Length > 1) + { + byte[] destinationArray = new byte[m_asset.Data.Length + data.Length]; + Array.Copy(m_asset.Data, 0, destinationArray, 0, m_asset.Data.Length); + Array.Copy(data, 0, destinationArray, m_asset.Data.Length, data.Length); + m_asset.Data = destinationArray; + } + else + { + byte[] buffer2 = new byte[data.Length - 4]; + Array.Copy(data, 4, buffer2, 0, data.Length - 4); + m_asset.Data = buffer2; + } + + remoteClient.SendConfirmXfer(xferID, packetID); + + if ((packetID & 0x80000000) != 0) + { + SendCompleteMessage(remoteClient); + + } + } + } + + public void SendCompleteMessage(IClientAPI remoteClient) + { + handlerTerrainUploadDone = TerrainUploadDone; + if (handlerTerrainUploadDone != null) + { + handlerTerrainUploadDone(m_asset.Name,m_asset.Data, remoteClient); + } + } + } +} diff --git a/OpenSim/Region/Environment/Modules/World/NPC/NPCAvatar.cs b/OpenSim/Region/Environment/Modules/World/NPC/NPCAvatar.cs index ba73a31..de0a41a 100644 --- a/OpenSim/Region/Environment/Modules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/Environment/Modules/World/NPC/NPCAvatar.cs @@ -243,6 +243,7 @@ namespace OpenSim.Region.Environment.Modules.World.NPC public event UDPAssetUploadRequest OnAssetUploadRequest; public event XferReceive OnXferReceive; public event RequestXfer OnRequestXfer; + public event AbortXfer OnAbortXfer; public event ConfirmXfer OnConfirmXfer; public event RezScript OnRezScript; public event UpdateTaskInventory OnUpdateTaskInventory; @@ -269,6 +270,7 @@ namespace OpenSim.Region.Environment.Modules.World.NPC public event RegionInfoRequest OnRegionInfoRequest; public event EstateCovenantRequest OnEstateCovenantRequest; public event RequestTerrain OnRequestTerrain; + public event RequestTerrain OnUploadTerrain; public event ObjectDuplicateOnRay OnObjectDuplicateOnRay; public event FriendActionDelegate OnApproveFriendRequest; -- cgit v1.1